From 89d68994efe8609cff3b1d60033c591d7fe3eb2c Mon Sep 17 00:00:00 2001 From: Lyubomir Marinov Date: Fri, 29 Jun 2012 06:55:08 +0000 Subject: [PATCH] Switches Jitsi trunk to libjitsi. --- .classpath | 1 + build.xml | 52 +- lib/felix.client.run.properties | 4 +- lib/felix.unit.test.properties | 4 +- lib/installer-exclude/libjitsi.jar | Bin 0 -> 1759618 bytes lib/native/linux-64/libjnpulseaudio.so | Bin 35592 -> 33480 bytes lib/native/linux-64/libjnvideo4linux2.so | Bin 40908 -> 19632 bytes lib/native/linux/libjnpulseaudio.so | Bin 30156 -> 28044 bytes lib/native/linux/libjnvideo4linux2.so | Bin 34500 -> 16076 bytes .../argdelegation/ArgDelegationActivator.java | 5 +- .../argdelegation/argdelegation.manifest.mf | 3 +- .../browserlauncher/BrowserLauncherImpl.java | 4 +- .../browserlauncher.manifest.mf | 1 + .../callhistory/CallHistoryActivator.java | 10 +- .../impl/callhistory/callhistory.manifest.mf | 4 +- .../certificate/CertificateServiceImpl.java | 17 +- .../CertificateVerificationActivator.java | 4 +- .../certificate/VerifyCertificateDialog.java | 3 +- .../impl/certificate/certificate.manifest.mf | 5 +- .../configuration/ChangeEventDispatcher.java | 2 +- .../configuration/ConfigurationActivator.java | 2 +- .../ConfigurationServiceImpl.java | 23 +- .../configuration/configuration.manifest.mf | 4 +- .../contactlist/ContactlistActivator.java | 2 +- .../impl/contactlist/MclStorageManager.java | 10 +- .../impl/contactlist/MetaContactImpl.java | 3 +- .../impl/contactlist/meta.cl.manifest.mf | 4 +- .../CredentialsStorageServiceImpl.java | 2 +- .../credentialsstorage.manifest.mf | 2 +- .../fileaccess/FailSafeTransactionImpl.java | 3 +- .../impl/fileaccess/FileAccessActivator.java | 3 +- .../fileaccess/FileAccessServiceImpl.java | 8 +- .../impl/fileaccess/fileaccess.manifest.mf | 4 +- .../GalagoNotificationActivator.java | 1 + .../galagonotification.manifest.mf | 2 +- .../GlobalShortcutServiceImpl.java | 10 +- .../NativeKeyboardHookDelegate.java | 2 +- .../globalshortcut/globalshortcut.manifest.mf | 1 + .../GoogleContactsActivator.java | 4 +- .../GoogleContactsServiceImpl.java | 2 +- .../googlecontacts/googlecontacts.manifest.mf | 4 +- .../GrowlNotificationActivator.java | 6 +- .../growlnotification.manifest.mf | 4 +- .../communicator/impl/gui/GuiActivator.java | 10 +- .../communicator/impl/gui/UIServiceImpl.java | 6 +- .../impl/gui/customcontrols/SCScrollPane.java | 3 +- .../gui/customcontrols/wizard/Wizard.java | 3 +- .../gui/lookandfeel/SIPCommCheckBoxUI.java | 2 +- .../impl/gui/main/DialPadFieldUI.java | 2 +- .../impl/gui/main/GeneralDialPadDialog.java | 3 +- .../impl/gui/main/GeneralDialPanel.java | 3 +- .../communicator/impl/gui/main/MainFrame.java | 12 +- .../AccountRegWizardContainerImpl.java | 3 +- .../account/AccountsConfigurationPanel.java | 3 +- .../gui/main/account/NewAccountDialog.java | 2 +- .../main/call/AbstractCallToggleButton.java | 2 +- .../impl/gui/main/call/CallButton.java | 2 +- .../impl/gui/main/call/CallHistoryButton.java | 2 +- .../impl/gui/main/call/CallInfoFrame.java | 14 +- .../impl/gui/main/call/CallManager.java | 7 +- .../impl/gui/main/call/CallPanel.java | 10 +- .../impl/gui/main/call/CallPeerAdapter.java | 2 + .../impl/gui/main/call/CallStatusPanel.java | 2 +- .../gui/main/call/CallTransferHandler.java | 2 +- .../impl/gui/main/call/DTMFHandler.java | 5 +- .../gui/main/call/DesktopSharingFrame.java | 6 +- .../main/call/InputVolumeControlButton.java | 5 +- .../impl/gui/main/call/LocalVideoButton.java | 5 +- .../impl/gui/main/call/OneToOneCallPanel.java | 7 +- .../gui/main/call/OneToOneCallPeerPanel.java | 6 +- .../main/call/OutputVolumeControlButton.java | 3 +- .../main/call/ParanoiaTimerSecurityPanel.java | 14 +- .../impl/gui/main/call/PreCallDialog.java | 5 +- .../impl/gui/main/call/RecordButton.java | 10 +- .../impl/gui/main/call/ResizeVideoButton.java | 3 +- .../impl/gui/main/call/SecurityPanel.java | 3 +- .../gui/main/call/SelectScreenDialog.java | 9 +- .../impl/gui/main/call/UIVideoHandler.java | 7 +- .../gui/main/call/VolumeControlSlider.java | 5 +- .../impl/gui/main/call/ZrtpSecurityPanel.java | 8 +- .../BasicConferenceParticipantPanel.java | 3 +- .../call/conference/ConferenceFocusPanel.java | 2 + .../conference/ConferenceInviteDialog.java | 2 +- .../call/conference/ConferencePeerPanel.java | 7 +- .../ProtocolProviderSelectorBox.java | 2 +- .../conference/VideoConferenceCallPanel.java | 3 +- .../main/chat/ChatConversationComponent.java | 3 +- .../impl/gui/main/chat/ChatPanel.java | 9 +- .../impl/gui/main/chat/ChatWindow.java | 2 + .../impl/gui/main/chat/ChatWindowManager.java | 4 +- .../impl/gui/main/chat/ChatWritePanel.java | 2 +- .../impl/gui/main/chat/ContactPhotoPanel.java | 2 +- .../impl/gui/main/chat/FontChooser.java | 3 +- .../chat/conference/ChatContactRoleIcon.java | 2 +- .../chat/conference/ChatRoomSubjectPanel.java | 3 +- .../conference/ConferenceChatManager.java | 6 +- .../main/chatroomslist/AdHocChatRoomList.java | 2 +- .../gui/main/chatroomslist/ChatRoomList.java | 2 +- .../ChatRoomRightButtonMenu.java | 2 + .../joinforms/JoinChatRoomWizard.java | 2 +- .../joinforms/JoinChatRoomWizardPage2.java | 2 +- .../main/configforms/ConfigurationFrame.java | 3 +- .../ContactListTreeCellRenderer.java | 2 +- .../main/contactlist/ContactListUtils.java | 2 +- .../impl/gui/main/contactlist/GroupNode.java | 2 +- .../gui/main/contactlist/SearchFieldUI.java | 2 +- .../gui/main/contactlist/UIContactDetail.java | 2 +- .../main/contactlist/UnknownContactPanel.java | 2 +- .../contactsource/MetaUIContact.java | 2 +- .../notifsource/NotificationContact.java | 3 +- .../main/login/DefaultSecurityAuthority.java | 2 +- .../impl/gui/main/menus/AutoAnswerMenu.java | 9 +- .../impl/gui/main/menus/FileMenu.java | 3 +- .../impl/gui/main/menus/HelpMenu.java | 6 +- .../impl/gui/main/menus/MainMenu.java | 3 +- .../presence/GlobalStatusSelectorBox.java | 2 +- .../gui/main/presence/StatusSelectorMenu.java | 2 +- .../avatar/imagepicker/WebcamDialog.java | 7 +- .../impl/gui/swing.ui.manifest.mf | 61 +- .../impl/gui/utils/ConfigurationManager.java | 2 +- .../impl/gui/utils/SoundProperties.java | 3 +- .../communicator/impl/hid/HIDServiceImpl.java | 4 +- .../sip/communicator/impl/hid/hid.manifest.mf | 3 +- .../impl/history/HistoryServiceImpl.java | 12 +- .../impl/history/history.manifest.mf | 4 +- .../keybindings/KeybindingsActivator.java | 4 +- .../keybindings/KeybindingsServiceImpl.java | 11 +- .../impl/keybindings/keybindings.manifest.mf | 6 +- .../communicator/impl/ldap/LdapActivator.java | 15 +- .../impl/ldap/LdapDirectorySetImpl.java | 2 +- .../impl/ldap/LdapDirectorySettingsImpl.java | 2 +- .../impl/ldap/LdapServiceImpl.java | 2 +- .../communicator/impl/ldap/ldap.manifest.mf | 4 +- .../msghistory/MessageHistoryServiceImpl.java | 10 +- .../impl/msghistory/msghistory.manifest.mf | 6 +- .../impl/neomedia/AbstractRTPConnector.java | 417 --- .../impl/neomedia/AbstractVolumeControl.java | 536 ---- .../impl/neomedia/ArrayIOUtils.java | 91 - .../impl/neomedia/AudioMediaStreamImpl.java | 484 --- .../neomedia/CallRecordingConfigForm.java | 11 +- .../DeviceConfigurationComboBoxModel.java | 4 +- .../EncodingConfigurationTableModel.java | 9 +- .../impl/neomedia/MediaConfiguration.java | 16 +- .../impl/neomedia/MediaServiceImpl.java | 1496 ---------- .../impl/neomedia/MediaStreamImpl.java | 2476 ---------------- .../impl/neomedia/MediaStreamStatsImpl.java | 665 ----- .../impl/neomedia/MediaUtils.java | 826 ------ .../impl/neomedia/NeomediaActivator.java | 21 +- .../impl/neomedia/ProcessorUtility.java | 159 - .../neomedia/RTCPConnectorInputStream.java | 121 - .../impl/neomedia/RTCPFeedbackPacket.java | 87 - .../neomedia/RTPConnectorInputStream.java | 425 --- .../neomedia/RTPConnectorOutputStream.java | 559 ---- .../impl/neomedia/RTPConnectorTCPImpl.java | 121 - .../neomedia/RTPConnectorTCPInputStream.java | 148 - .../neomedia/RTPConnectorTCPOutputStream.java | 100 - .../impl/neomedia/RTPConnectorUDPImpl.java | 121 - .../neomedia/RTPConnectorUDPInputStream.java | 119 - .../neomedia/RTPConnectorUDPOutputStream.java | 103 - .../impl/neomedia/RTPTranslatorImpl.java | 1545 ---------- .../communicator/impl/neomedia/RawPacket.java | 962 ------ .../impl/neomedia/RecorderImpl.java | 350 --- .../impl/neomedia/SecurityConfigForm.java | 5 +- .../impl/neomedia/StreamRTPManager.java | 206 -- .../impl/neomedia/VideoMediaStreamImpl.java | 1251 -------- .../impl/neomedia/ZrtpConfigurePanel.java | 5 +- .../impl/neomedia/ZrtpConfigureUtils.java | 66 - .../impl/neomedia/ZrtpControlImpl.java | 368 --- .../neomedia/ZrtpFortunaEntropyGatherer.java | 296 -- .../audiolevel/AudioLevelCalculator.java | 200 -- .../neomedia/audiolevel/AudioLevelEffect.java | 288 -- .../audiolevel/AudioLevelEventDispatcher.java | 340 --- .../neomedia/audiolevel/AudioLevelMap.java | 163 - .../impl/neomedia/codec/AbstractCodecExt.java | 296 -- .../impl/neomedia/codec/Constants.java | 128 - .../neomedia/codec/EncodingConfiguration.java | 752 ----- .../impl/neomedia/codec/FFmpeg.java | 802 ----- .../codec/audio/alaw/DePacketizer.java | 113 - .../codec/audio/alaw/JavaEncoder.java | 339 --- .../neomedia/codec/audio/alaw/Packetizer.java | 150 - .../neomedia/codec/audio/g722/JNIDecoder.java | 122 - .../neomedia/codec/audio/g722/JNIEncoder.java | 148 - .../neomedia/codec/audio/g729/AcelpCo.java | 755 ----- .../impl/neomedia/codec/audio/g729/Bits.java | 197 -- .../neomedia/codec/audio/g729/CodLd8k.java | 498 ---- .../impl/neomedia/codec/audio/g729/Coder.java | 200 -- .../neomedia/codec/audio/g729/CorFunc.java | 106 - .../neomedia/codec/audio/g729/DeAcelp.java | 102 - .../neomedia/codec/audio/g729/DecGain.java | 117 - .../neomedia/codec/audio/g729/DecLag3.java | 104 - .../neomedia/codec/audio/g729/DecLd8k.java | 315 -- .../neomedia/codec/audio/g729/Decoder.java | 284 -- .../neomedia/codec/audio/g729/Filter.java | 166 -- .../codec/audio/g729/FloatReference.java | 15 - .../neomedia/codec/audio/g729/Gainpred.java | 136 - .../codec/audio/g729/IntReference.java | 15 - .../codec/audio/g729/JavaDecoder.java | 167 -- .../codec/audio/g729/JavaEncoder.java | 294 -- .../impl/neomedia/codec/audio/g729/Ld8k.java | 389 --- .../impl/neomedia/codec/audio/g729/Lpc.java | 303 -- .../neomedia/codec/audio/g729/Lpcfunc.java | 235 -- .../neomedia/codec/audio/g729/Lspdec.java | 167 -- .../neomedia/codec/audio/g729/Lspgetq.java | 303 -- .../neomedia/codec/audio/g729/PParity.java | 93 - .../impl/neomedia/codec/audio/g729/Pitch.java | 516 ---- .../neomedia/codec/audio/g729/PostPro.java | 108 - .../neomedia/codec/audio/g729/Postfil.java | 860 ------ .../neomedia/codec/audio/g729/PreProc.java | 110 - .../neomedia/codec/audio/g729/PredLt3.java | 96 - .../impl/neomedia/codec/audio/g729/Pwf.java | 145 - .../neomedia/codec/audio/g729/QuaGain.java | 238 -- .../neomedia/codec/audio/g729/QuaLsp.java | 435 --- .../neomedia/codec/audio/g729/TabLd8k.java | 2626 ----------------- .../neomedia/codec/audio/g729/Taming.java | 140 - .../impl/neomedia/codec/audio/g729/Util.java | 202 -- .../codec/audio/gsm/DePacketizer.java | 118 - .../neomedia/codec/audio/gsm/Decoder.java | 260 -- .../neomedia/codec/audio/gsm/Encoder.java | 224 -- .../codec/audio/gsm/GSMDecoderUtil.java | 71 - .../codec/audio/gsm/GSMEncoderUtil.java | 68 - .../neomedia/codec/audio/gsm/Packetizer.java | 124 - .../codec/audio/ilbc/JavaDecoder.java | 205 -- .../codec/audio/ilbc/JavaEncoder.java | 249 -- .../neomedia/codec/audio/ilbc/bitpack.java | 43 - .../neomedia/codec/audio/ilbc/bitstream.java | 189 -- .../codec/audio/ilbc/ilbc_common.java | 722 ----- .../codec/audio/ilbc/ilbc_constants.java | 778 ----- .../codec/audio/ilbc/ilbc_decoder.java | 2050 ------------- .../codec/audio/ilbc/ilbc_encoder.java | 2340 --------------- .../neomedia/codec/audio/ilbc/ilbc_ulp.java | 111 - .../neomedia/codec/audio/mp3/JNIEncoder.java | 288 -- .../codec/audio/silk/JavaDecoder.java | 169 -- .../codec/audio/silk/JavaEncoder.java | 306 -- .../codec/audio/silk/Silk_A2NLSF.java | 356 --- .../neomedia/codec/audio/silk/Silk_CNG.java | 168 -- .../silk/Silk_HP_variable_cutoff_FLP.java | 327 -- .../codec/audio/silk/Silk_Inlines.java | 315 -- .../codec/audio/silk/Silk_LBRR_reset.java | 31 - .../silk/Silk_LPC_analysis_filter_FLP.java | 243 -- .../audio/silk/Silk_LPC_inv_pred_gain.java | 189 -- .../silk/Silk_LPC_inv_pred_gain_FLP.java | 72 - .../codec/audio/silk/Silk_LPC_stabilize.java | 131 - .../audio/silk/Silk_LPC_synthesis_filter.java | 77 - .../silk/Silk_LPC_synthesis_order16.java | 117 - .../audio/silk/Silk_LP_variable_cutoff.java | 223 -- .../codec/audio/silk/Silk_LSF_cos_table.java | 54 - .../silk/Silk_LTP_analysis_filter_FLP.java | 71 - .../audio/silk/Silk_LTP_scale_ctrl_FLP.java | 78 - .../neomedia/codec/audio/silk/Silk_MA.java | 200 -- .../codec/audio/silk/Silk_NLSF2A.java | 161 - .../codec/audio/silk/Silk_NLSF2A_stable.java | 53 - .../audio/silk/Silk_NLSF_MSVQ_decode.java | 89 - .../audio/silk/Silk_NLSF_MSVQ_decode_FLP.java | 89 - .../audio/silk/Silk_NLSF_MSVQ_encode_FLP.java | 241 -- .../Silk_NLSF_VQ_rate_distortion_FLP.java | 57 - .../silk/Silk_NLSF_VQ_sum_error_FLP.java | 136 - .../silk/Silk_NLSF_VQ_weights_laroia_FLP.java | 57 - .../codec/audio/silk/Silk_NLSF_stabilize.java | 154 - .../neomedia/codec/audio/silk/Silk_NSQ.java | 461 --- .../codec/audio/silk/Silk_NSQ_del_dec.java | 796 ----- .../neomedia/codec/audio/silk/Silk_PLC.java | 473 --- .../codec/audio/silk/Silk_SDK_API.java | 32 - .../codec/audio/silk/Silk_SigProc_FIX.java | 810 ----- .../codec/audio/silk/Silk_SigProc_FLP.java | 100 - .../neomedia/codec/audio/silk/Silk_VAD.java | 347 --- .../silk/Silk_VQ_nearest_neighbor_FLP.java | 104 - .../codec/audio/silk/Silk_allpass_int.java | 60 - .../audio/silk/Silk_allpass_int_FLP.java | 54 - .../audio/silk/Silk_ana_filt_bank_1.java | 78 - .../silk/Silk_apply_sine_window_FLP.java | 84 - .../audio/silk/Silk_autocorrelation_FLP.java | 48 - .../codec/audio/silk/Silk_biquad.java | 64 - .../codec/audio/silk/Silk_biquad_alt.java | 67 - .../audio/silk/Silk_burg_modified_FLP.java | 148 - .../codec/audio/silk/Silk_bwexpander.java | 42 - .../codec/audio/silk/Silk_bwexpander_32.java | 38 - .../codec/audio/silk/Silk_bwexpander_FLP.java | 40 - .../codec/audio/silk/Silk_code_signs.java | 106 - .../silk/Silk_common_pitch_est_defines.java | 49 - .../codec/audio/silk/Silk_control.java | 99 - .../audio/silk/Silk_control_codec_FLP.java | 665 ----- .../codec/audio/silk/Silk_corrMatrix_FLP.java | 105 - .../audio/silk/Silk_create_init_destroy.java | 41 - .../codec/audio/silk/Silk_dec_API.java | 299 -- .../audio/silk/Silk_decimate2_coarse_FLP.java | 67 - .../silk/Silk_decimate2_coarsest_FLP.java | 64 - .../codec/audio/silk/Silk_decode_core.java | 244 -- .../codec/audio/silk/Silk_decode_frame.java | 155 - .../audio/silk/Silk_decode_parameters.java | 269 -- .../codec/audio/silk/Silk_decode_pitch.java | 48 - .../codec/audio/silk/Silk_decode_pulses.java | 110 - .../codec/audio/silk/Silk_decoder_set_fs.java | 78 - .../codec/audio/silk/Silk_define.java | 292 -- .../codec/audio/silk/Silk_define_FLP.java | 77 - .../audio/silk/Silk_detect_SWB_input.java | 74 - .../codec/audio/silk/Silk_enc_API.java | 303 -- .../audio/silk/Silk_encode_frame_FLP.java | 701 ----- .../audio/silk/Silk_encode_parameters.java | 153 - .../codec/audio/silk/Silk_encode_pulses.java | 203 -- .../codec/audio/silk/Silk_energy_FLP.java | 54 - .../codec/audio/silk/Silk_errors.java | 67 - .../codec/audio/silk/Silk_find_LPC_FLP.java | 93 - .../codec/audio/silk/Silk_find_LTP_FLP.java | 142 - .../audio/silk/Silk_find_pitch_lags_FLP.java | 126 - .../audio/silk/Silk_find_pred_coefs_FLP.java | 179 -- .../codec/audio/silk/Silk_gain_quant.java | 94 - .../audio/silk/Silk_init_encoder_FLP.java | 55 - .../audio/silk/Silk_inner_product_FLP.java | 56 - .../codec/audio/silk/Silk_interpolate.java | 44 - .../codec/audio/silk/Silk_k2a_FLP.java | 47 - .../audio/silk/Silk_levinsondurbin_FLP.java | 75 - .../codec/audio/silk/Silk_lin2log.java | 38 - .../codec/audio/silk/Silk_log2lin.java | 44 - .../codec/audio/silk/Silk_lowpass_int.java | 50 - .../codec/audio/silk/Silk_lowpass_short.java | 49 - .../codec/audio/silk/Silk_macros.java | 109 - .../codec/audio/silk/Silk_main_FLP.java | 25 - .../silk/Silk_noise_shape_analysis_FLP.java | 390 --- .../silk/Silk_perceptual_parameters_FLP.java | 99 - .../silk/Silk_pitch_analysis_core_FLP.java | 712 ----- .../audio/silk/Silk_pitch_est_defines.java | 20 - .../silk/Silk_pitch_est_defines_FLP.java | 20 - .../audio/silk/Silk_pitch_est_tables.java | 71 - .../codec/audio/silk/Silk_prefilter_FLP.java | 168 -- .../audio/silk/Silk_process_NLSFs_FLP.java | 98 - .../audio/silk/Silk_process_gains_FLP.java | 90 - .../audio/silk/Silk_quant_LTP_gains_FLP.java | 140 - .../codec/audio/silk/Silk_range_coder.java | 471 --- .../Silk_regularize_correlations_FLP.java | 39 - .../codec/audio/silk/Silk_resampler.java | 513 ---- .../audio/silk/Silk_resampler_down2.java | 68 - .../audio/silk/Silk_resampler_down2_3.java | 101 - .../audio/silk/Silk_resampler_down3.java | 92 - .../audio/silk/Silk_resampler_private.java | 21 - .../silk/Silk_resampler_private_AR2.java | 53 - .../silk/Silk_resampler_private_ARMA4.java | 70 - .../silk/Silk_resampler_private_IIR_FIR.java | 117 - .../silk/Silk_resampler_private_copy.java | 37 - .../silk/Silk_resampler_private_down4.java | 71 - .../silk/Silk_resampler_private_down_FIR.java | 159 - .../silk/Silk_resampler_private_up2_HQ.java | 120 - .../silk/Silk_resampler_private_up4.java | 75 - .../codec/audio/silk/Silk_resampler_rom.java | 262 -- .../audio/silk/Silk_resampler_structs.java | 133 - .../codec/audio/silk/Silk_resampler_up2.java | 67 - .../audio/silk/Silk_residual_energy_FLP.java | 126 - .../silk/Silk_scale_copy_vector_FLP.java | 50 - .../audio/silk/Silk_scale_vector_FLP.java | 45 - .../codec/audio/silk/Silk_schur_FLP.java | 60 - .../codec/audio/silk/Silk_shell_coder.java | 191 -- .../codec/audio/silk/Silk_sigm_Q15.java | 67 - .../codec/audio/silk/Silk_solve_LS_FLP.java | 223 -- .../neomedia/codec/audio/silk/Silk_sort.java | 325 -- .../codec/audio/silk/Silk_sort_FLP.java | 176 -- .../codec/audio/silk/Silk_structs.java | 468 --- .../codec/audio/silk/Silk_structs_FLP.java | 315 -- .../codec/audio/silk/Silk_sum_sqr_shift.java | 100 - .../codec/audio/silk/Silk_tables.java | 54 - .../codec/audio/silk/Silk_tables_LTP.java | 530 ---- .../audio/silk/Silk_tables_NLSF_CB0_10.java | 885 ------ .../silk/Silk_tables_NLSF_CB0_10_FLP.java | 740 ----- .../audio/silk/Silk_tables_NLSF_CB0_16.java | 1325 --------- .../silk/Silk_tables_NLSF_CB0_16_FLP.java | 1930 ------------ .../audio/silk/Silk_tables_NLSF_CB1_10.java | 576 ---- .../silk/Silk_tables_NLSF_CB1_10_FLP.java | 476 --- .../audio/silk/Silk_tables_NLSF_CB1_16.java | 708 ----- .../silk/Silk_tables_NLSF_CB1_16_FLP.java | 979 ------ .../codec/audio/silk/Silk_tables_gain.java | 46 - .../codec/audio/silk/Silk_tables_other.java | 128 - .../audio/silk/Silk_tables_other_FLP.java | 24 - .../audio/silk/Silk_tables_pitch_lag.java | 184 -- .../silk/Silk_tables_pulses_per_block.java | 219 -- .../codec/audio/silk/Silk_tables_sign.java | 28 - .../audio/silk/Silk_tables_type_offset.java | 37 - .../codec/audio/silk/Silk_typedef.java | 45 - .../codec/audio/silk/Silk_wrappers_FLP.java | 536 ---- .../codec/audio/speex/JNIDecoder.java | 365 --- .../codec/audio/speex/JNIEncoder.java | 492 --- .../codec/audio/speex/JavaDecoder.java | 237 -- .../codec/audio/speex/JavaEncoder.java | 269 -- .../neomedia/codec/audio/speex/Speex.java | 121 - .../codec/audio/speex/SpeexResampler.java | 388 --- .../codec/audio/ulaw/JavaDecoder.java | 111 - .../codec/audio/ulaw/JavaEncoder.java | 221 -- .../neomedia/codec/audio/ulaw/Packetizer.java | 28 - .../impl/neomedia/codec/video/AVFrame.java | 48 - .../neomedia/codec/video/AVFrameFormat.java | 261 -- .../impl/neomedia/codec/video/ByteBuffer.java | 118 - .../codec/video/FinalizableAVFrame.java | 135 - .../impl/neomedia/codec/video/HFlip.java | 347 --- .../neomedia/codec/video/ImageScaler.java | 232 -- .../impl/neomedia/codec/video/SwScaler.java | 663 ----- .../codec/video/h263p/DePacketizer.java | 232 -- .../codec/video/h263p/JNIDecoder.java | 349 --- .../codec/video/h263p/JNIEncoder.java | 462 --- .../codec/video/h263p/Packetizer.java | 419 --- .../codec/video/h264/ConfigurationPanel.java | 8 +- .../codec/video/h264/DePacketizer.java | 753 ----- .../neomedia/codec/video/h264/JNIDecoder.java | 391 --- .../neomedia/codec/video/h264/JNIEncoder.java | 794 ----- .../neomedia/codec/video/h264/Packetizer.java | 550 ---- .../impl/neomedia/conference/AudioMixer.java | 1141 ------- .../AudioMixerPushBufferStream.java | 1406 --------- .../AudioMixingPushBufferDataSource.java | 413 --- .../AudioMixingPushBufferStream.java | 460 --- .../neomedia/conference/DataSourceFilter.java | 32 - .../conference/InputDataSourceDesc.java | 313 -- .../neomedia/conference/InputStreamDesc.java | 151 - .../neomedia/control/AbstractControls.java | 88 - .../control/AbstractFormatControl.java | 137 - .../neomedia/control/ControlsAdapter.java | 37 - .../control/FrameProcessingControlImpl.java | 106 - .../control/FrameRateControlAdapter.java | 87 - .../ReadOnlyBufferControlDelegate.java | 133 - .../ReadOnlyFormatControlDelegate.java | 112 - .../neomedia/device/AbstractMediaDevice.java | 122 - .../neomedia/device/AudioMediaDeviceImpl.java | 439 --- .../device/AudioMediaDeviceSession.java | 266 -- .../device/AudioMixerMediaDevice.java | 1239 -------- .../impl/neomedia/device/AudioSystem.java | 505 ---- .../neomedia/device/DeviceConfiguration.java | 1131 ------- .../impl/neomedia/device/DeviceSystem.java | 395 --- .../neomedia/device/DirectShowSystem.java | 114 - .../neomedia/device/ImgStreamingSystem.java | 127 - .../impl/neomedia/device/JavaSoundSystem.java | 51 - .../impl/neomedia/device/LtiCivilSystem.java | 47 - .../impl/neomedia/device/MediaDeviceImpl.java | 468 --- .../neomedia/device/MediaDeviceSession.java | 2194 -------------- .../impl/neomedia/device/NoneAudioSystem.java | 36 - .../impl/neomedia/device/PortAudioSystem.java | 292 -- .../neomedia/device/PulseAudioSystem.java | 628 ---- .../impl/neomedia/device/QuickTimeSystem.java | 98 - .../ReceiveStreamPushBufferDataSource.java | 137 - .../neomedia/device/ScreenDeviceImpl.java | 169 -- .../neomedia/device/Video4Linux2System.java | 234 -- .../device/VideoMediaDeviceSession.java | 1836 ------------ .../device/VideoTranslatorMediaDevice.java | 372 --- .../neomedia/directshow/DSCaptureDevice.java | 196 -- .../impl/neomedia/directshow/DSFormat.java | 281 -- .../impl/neomedia/directshow/DSManager.java | 183 -- .../neomedia/format/AudioMediaFormatImpl.java | 222 -- .../format/MediaFormatFactoryImpl.java | 487 --- .../impl/neomedia/format/MediaFormatImpl.java | 611 ---- .../format/ParameterizedVideoFormat.java | 302 -- .../neomedia/format/VideoMediaFormatImpl.java | 375 --- .../imgstreaming/DesktopInteract.java | 116 - .../imgstreaming/DesktopInteractImpl.java | 198 -- .../imgstreaming/ImageStreamingUtils.java | 98 - .../imgstreaming/NativeScreenCapture.java | 52 - .../protocol/AbstractBufferCaptureDevice.java | 873 ------ .../media/protocol/AbstractBufferStream.java | 243 -- .../AbstractPullBufferCaptureDevice.java | 476 --- .../protocol/AbstractPullBufferStream.java | 51 - .../AbstractPushBufferCaptureDevice.java | 467 --- .../protocol/AbstractPushBufferStream.java | 59 - .../AbstractVideoPullBufferCaptureDevice.java | 79 - .../AbstractVideoPullBufferStream.java | 182 -- .../AbstractVideoPushBufferCaptureDevice.java | 56 - .../jmfext/media/protocol/ByteBufferPool.java | 168 -- .../media/protocol/alsa/AlsaStream.java | 196 -- .../media/protocol/alsa/DataSource.java | 147 - .../media/protocol/directshow/DataSource.java | 472 --- .../protocol/directshow/DirectShowStream.java | 462 --- .../protocol/imgstreaming/DataSource.java | 168 -- .../protocol/imgstreaming/ImageStream.java | 348 --- .../media/protocol/portaudio/DataSource.java | 245 -- .../protocol/portaudio/PortAudioStream.java | 452 --- .../media/protocol/pulseaudio/DataSource.java | 649 ---- .../media/protocol/quicktime/DataSource.java | 511 ---- .../protocol/quicktime/QuickTimeStream.java | 786 ----- .../protocol/video4linux2/DataSource.java | 239 -- .../protocol/video4linux2/Video4Linux2.java | 222 -- .../video4linux2/Video4Linux2Stream.java | 851 ------ .../media/renderer/AbstractRenderer.java | 69 - .../renderer/audio/PortAudioRenderer.java | 686 ----- .../renderer/audio/PulseAudioRenderer.java | 543 ---- .../media/renderer/video/JAWTRenderer.java | 640 ---- .../JAWTRendererSwingVideoComponent.java | 908 ------ .../video/JAWTRendererVideoComponent.java | 137 - .../impl/neomedia/neomedia.manifest.mf | 70 +- .../notify/AudioNotifierServiceImpl.java | 192 -- .../neomedia/notify/AudioSystemClipImpl.java | 343 --- .../neomedia/notify/JavaSoundClipImpl.java | 201 -- .../impl/neomedia/notify/SCAudioClipImpl.java | 94 - .../impl/neomedia/portaudio/PortAudio.java | 806 ----- .../portaudio/PortAudioException.java | 29 - .../portaudio/PortAudioStreamCallback.java | 44 - .../protocol/BufferStreamAdapter.java | 177 -- .../protocol/CachingPushBufferStream.java | 777 ----- ...ureDeviceDelegatePullBufferDataSource.java | 234 -- ...ureDeviceDelegatePushBufferDataSource.java | 224 -- .../protocol/InbandDTMFDataSource.java | 25 - .../neomedia/protocol/MuteDataSource.java | 32 - .../PullBufferDataSourceDelegate.java | 214 -- .../protocol/PullBufferStreamAdapter.java | 131 - .../protocol/PushBufferDataSourceAdapter.java | 573 ---- .../PushBufferDataSourceDelegate.java | 214 -- .../protocol/PushBufferStreamAdapter.java | 86 - .../RewritablePullBufferDataSource.java | 194 -- .../RewritablePushBufferDataSource.java | 353 --- .../protocol/SourceStreamDelegate.java | 103 - ...StreamSubstituteBufferTransferHandler.java | 85 - .../protocol/TranscodingDataSource.java | 311 -- .../impl/neomedia/pulseaudio/PA.java | 301 -- .../neomedia/quicktime/CVImageBuffer.java | 64 - .../neomedia/quicktime/CVPixelBuffer.java | 153 - .../quicktime/CVPixelBufferAttributeKey.java | 42 - .../neomedia/quicktime/CVPixelFormatType.java | 33 - .../impl/neomedia/quicktime/NSDictionary.java | 48 - .../impl/neomedia/quicktime/NSError.java | 40 - .../neomedia/quicktime/NSErrorException.java | 55 - .../quicktime/NSMutableDictionary.java | 47 - .../impl/neomedia/quicktime/NSObject.java | 101 - .../QTCaptureDecompressedVideoOutput.java | 269 -- .../neomedia/quicktime/QTCaptureDevice.java | 315 -- .../quicktime/QTCaptureDeviceInput.java | 51 - .../neomedia/quicktime/QTCaptureInput.java | 29 - .../neomedia/quicktime/QTCaptureOutput.java | 29 - .../neomedia/quicktime/QTCaptureSession.java | 100 - .../quicktime/QTFormatDescription.java | 61 - .../impl/neomedia/quicktime/QTMediaType.java | 32 - .../neomedia/quicktime/QTSampleBuffer.java | 48 - .../ControlTransformInputStream.java | 127 - .../neomedia/transform/PacketTransformer.java | 42 - .../transform/RTPTransformTCPConnector.java | 248 -- .../transform/RTPTransformUDPConnector.java | 248 -- .../neomedia/transform/TransformEngine.java | 31 - .../transform/TransformEngineChain.java | 188 -- .../transform/TransformTCPInputStream.java | 91 - .../transform/TransformTCPOutputStream.java | 101 - .../transform/TransformUDPInputStream.java | 91 - .../transform/TransformUDPOutputStream.java | 101 - .../transform/csrc/CsrcTransformEngine.java | 351 --- .../transform/dtmf/DtmfRawPacket.java | 178 -- .../transform/dtmf/DtmfTransformEngine.java | 468 --- .../transform/rtcp/StatisticsEngine.java | 260 -- .../transform/sdes/SDesControlImpl.java | 235 -- .../transform/sdes/SDesTransformEngine.java | 123 - .../srtp/AsymmetricSRTPTransformer.java | 69 - .../transform/srtp/SRTCPCryptoContext.java | 710 ----- .../transform/srtp/SRTCPTransformer.java | 142 - .../transform/srtp/SRTPCipherCTR.java | 131 - .../neomedia/transform/srtp/SRTPCipherF8.java | 195 -- .../transform/srtp/SRTPCryptoContext.java | 837 ------ .../neomedia/transform/srtp/SRTPPolicy.java | 232 -- .../transform/srtp/SRTPTransformEngine.java | 114 - .../transform/srtp/SRTPTransformer.java | 172 -- .../transform/zrtp/SecurityEventManager.java | 467 --- .../transform/zrtp/ZRTCPTransformer.java | 100 - .../transform/zrtp/ZRTPTransformEngine.java | 1482 ---------- .../transform/zrtp/ZrtpRawPacket.java | 160 - .../impl/netaddr/Ice4jPacketLogger.java | 2 +- .../impl/netaddr/NetaddrActivator.java | 7 +- .../NetworkAddressManagerServiceImpl.java | 6 +- .../impl/netaddr/netaddr.manifest.mf | 5 +- .../notification/NotificationActivator.java | 2 +- .../SoundNotificationHandlerImpl.java | 3 +- .../notification/notification.manifest.mf | 8 +- .../impl/osdependent/Desktop.java | 5 +- .../osdependent/OsDependentActivator.java | 6 +- .../impl/osdependent/Resources.java | 2 + .../impl/osdependent/TrayIcon.java | 5 +- .../jdic/ProviderUnRegistration.java | 2 +- .../jdic/SystrayServiceJdicImpl.java | 16 +- .../osdependent/jdic/TrayMenuFactory.java | 5 +- .../impl/osdependent/osdependent.manifest.mf | 5 +- .../packetlogging/PacketLoggingActivator.java | 8 +- .../PacketLoggingConfigurationImpl.java | 5 +- .../PacketLoggingServiceImpl.java | 9 +- .../packetlogging/packetlogging.manifest.mf | 8 +- .../impl/protocol/dict/DictActivator.java | 9 +- .../dict/ProtocolProviderServiceDictImpl.java | 2 +- .../protocol/dict/dict.provider.manifest.mf | 6 +- .../gibberish/GibberishActivator.java | 9 +- .../gibberish/ProtocolIconGibberishImpl.java | 2 +- .../gibberish/gibberish.provider.manifest.mf | 4 +- .../impl/protocol/icq/IcqActivator.java | 8 +- ...ationSetExtendedAuthorizationsIcqImpl.java | 2 +- .../protocol/icq/ProtocolIconAimImpl.java | 3 +- .../protocol/icq/ProtocolIconIcqImpl.java | 3 +- .../impl/protocol/icq/VolatileBuddy.java | 2 +- .../protocol/icq/icq.provider.manifest.mf | 4 +- .../irc/ChatRoomInvitationIrcImpl.java | 2 +- .../impl/protocol/irc/IrcActivator.java | 8 +- .../protocol/irc/irc.provider.manifest.mf | 4 +- .../ActiveCallsRepositoryGTalkImpl.java | 2 +- .../impl/protocol/jabber/CallJabberImpl.java | 2 +- .../protocol/jabber/CallPeerJabberImpl.java | 16 +- .../jabber/CallPeerMediaHandlerGTalkImpl.java | 7 +- .../CallPeerMediaHandlerJabberImpl.java | 12 +- .../jabber/IceUdpTransportManager.java | 3 +- .../impl/protocol/jabber/JabberActivator.java | 11 +- .../protocol/jabber/JingleNodesHarvester.java | 2 +- .../OperationSetAutoAnswerJabberImpl.java | 7 +- .../OperationSetBasicTelephonyJabberImpl.java | 6 +- .../jabber/OperationSetDTMFJabberImpl.java | 9 +- ...tionSetDesktopSharingServerJabberImpl.java | 21 +- ...perationSetDesktopStreamingJabberImpl.java | 7 +- ...ionSetTelephonyConferencingJabberImpl.java | 16 +- .../OperationSetVideoTelephonyJabberImpl.java | 3 +- .../jabber/ProtocolIconJabberImpl.java | 2 +- .../ProtocolProviderServiceJabberImpl.java | 2 +- .../jabber/QualityControlWrapper.java | 21 +- .../jabber/RawUdpTransportManager.java | 3 +- .../jabber/TransportManagerGTalkImpl.java | 22 +- .../jabber/TransportManagerJabberImpl.java | 3 +- .../WhiteboardInvitationJabberImpl.java | 2 +- .../jabber/debugger/SmackPacketDebugger.java | 3 +- .../extensions/caps/EntityCapsManager.java | 2 +- .../cobri/CobriStreamConnector.java | 2 +- .../jabber/extensions/coin/StateProvider.java | 2 +- .../gtalk/SrcIdPacketExtension.java | 2 +- .../gtalk/UsagePacketExtension.java | 2 +- .../jingle/CoinPacketExtension.java | 2 +- .../extensions/version/VersionManager.java | 3 +- .../WhiteboardObjectImageJabberImpl.java | 2 +- .../WhiteboardObjectJabberImpl.java | 2 +- .../WhiteboardObjectJabberProvider.java | 2 +- .../WhiteboardObjectLineJabberImpl.java | 2 +- .../WhiteboardObjectPacketExtension.java | 2 +- .../WhiteboardObjectRectJabberImpl.java | 2 +- .../WhiteboardObjectTextJabberImpl.java | 2 +- .../jabber/jabber.provider.manifest.mf | 16 +- .../jabber/jinglesdp/JingleUtils.java | 10 +- .../impl/protocol/msn/MsnActivator.java | 7 +- .../protocol/msn/msn.provider.manifest.mf | 6 +- .../protocol/rss/ProtocolIconRssImpl.java | 2 +- .../impl/protocol/rss/RssActivator.java | 5 +- .../protocol/rss/rss.provider.manifest.mf | 4 +- .../sip/CallPeerMediaHandlerSipImpl.java | 9 +- .../impl/protocol/sip/CallPeerSipImpl.java | 6 +- .../impl/protocol/sip/CallSipImpl.java | 3 +- .../sip/OperationSetAutoAnswerSipImpl.java | 20 +- .../protocol/sip/OperationSetDTMFSipImpl.java | 9 +- ...erationSetDesktopSharingServerSipImpl.java | 22 +- .../OperationSetDesktopStreamingSipImpl.java | 7 +- ...rationSetTelephonyConferencingSipImpl.java | 6 +- .../OperationSetVideoTelephonySipImpl.java | 5 +- .../protocol/sip/ProtocolIconSipImpl.java | 3 +- .../sip/ProtocolProviderServiceSipImpl.java | 20 +- .../protocol/sip/QualityControlWrapper.java | 19 +- .../sip/ServerStoredContactListXivoImpl.java | 17 +- .../impl/protocol/sip/SipActivator.java | 16 +- .../impl/protocol/sip/SipLogger.java | 7 +- .../impl/protocol/sip/SipStackProperties.java | 6 +- .../impl/protocol/sip/dtmf/DTMFInfo.java | 3 + .../protocol/sip/net/SslNetworkLayer.java | 2 +- .../impl/protocol/sip/sdp/SdpUtils.java | 9 +- .../protocol/sip/sip.provider.manifest.mf | 19 +- .../protocol/sip/xcap/BaseHttpXCapClient.java | 2 +- .../sip/xcap/model/ParsingException.java | 2 +- .../sip/xcap/model/prescontent/DataType.java | 2 +- .../xcap/model/prescontent/EncodingType.java | 2 +- .../sip/xcap/model/prescontent/MimeType.java | 2 +- .../sip/xcap/model/presrules/ClassType.java | 2 +- .../model/presrules/OccurrenceIdType.java | 2 +- .../xcap/model/presrules/PresRulesParser.java | 2 +- .../ProvideServicePermissionType.java | 2 +- .../xcap/model/presrules/SubHandlingType.java | 2 +- .../xcap/model/resourcelists/ListType.java | 2 +- .../resourcelists/ResourceListsParser.java | 2 +- .../impl/protocol/ssh/SSHActivator.java | 6 +- .../protocol/ssh/ssh.provider.manifest.mf | 4 +- .../protocol/yahoo/ProtocolIconYahooImpl.java | 6 +- .../impl/protocol/yahoo/YahooActivator.java | 7 +- .../protocol/yahoo/yahoo.provider.manifest.mf | 4 +- .../zeroconf/ProtocolIconZeroconfImpl.java | 2 +- .../zeroconf/zeroconf.provider.manifest.mf | 4 +- .../ProvisioningDiscoveryServiceDHCPImpl.java | 2 +- .../replacement/bliptv/BliptvActivator.java | 2 +- .../bliptv/ReplacementServiceBliptvImpl.java | 2 +- .../bliptv/bliptv.source.manifest.mf | 6 +- .../dailymotion/DailymotionActivator.java | 2 +- .../ReplacementServiceDailymotionImpl.java | 2 +- .../dailymotion.source.manifest.mf | 8 +- .../directimage/DirectImageActivator.java | 2 +- .../ReplacementServiceDirectImageImpl.java | 2 +- .../directimage.source.manifest.mf | 8 +- .../replacement/flickr/FlickrActivator.java | 2 +- .../flickr/ReplacementServiceFlickrImpl.java | 2 +- .../flickr/flickr.source.manifest.mf | 6 +- .../impl/replacement/hulu/HuluActivator.java | 2 +- .../hulu/ReplacementServiceHuluImpl.java | 2 +- .../replacement/hulu/hulu.source.manifest.mf | 6 +- .../metacafe/MetacafeActivator.java | 2 +- .../ReplacementServiceMetacafeImpl.java | 2 +- .../metacafe/metacafe.source.manifest.mf | 6 +- .../replacement/smiley/SmileyActivator.java | 4 +- .../impl/replacement/smiley/SmileyImpl.java | 2 +- .../smiley/smiley.source.manifest.mf | 8 +- .../ReplacementServiceTwitpicImpl.java | 2 +- .../replacement/twitpic/TwitpicActivator.java | 2 +- .../twitpic/twitpic.source.manifest.mf | 6 +- .../vbox7/ReplacementServiceVbox7Impl.java | 2 +- .../replacement/vbox7/Vbox7Activator.java | 2 +- .../vbox7/vbox7.source.manifest.mf | 6 +- .../ReplacementServiceViddlerImpl.java | 2 +- .../replacement/viddler/ViddlerActivator.java | 2 +- .../viddler/viddler.source.manifest.mf | 6 +- .../vimeo/ReplacementServiceVimeoImpl.java | 2 +- .../replacement/vimeo/VimeoActivator.java | 2 +- .../vimeo/vimeo.source.manifest.mf | 6 +- .../ReplacementServiceYoutubeImpl.java | 2 +- .../replacement/youtube/YoutubeActivator.java | 2 +- .../youtube/youtube.source.manifest.mf | 6 +- .../ResourceManagementActivator.java | 6 +- .../ResourceManagementServiceImpl.java | 1 + .../resources/resourcemanagement.manifest.mf | 3 +- .../shutdown.timeout.manifest.mf | 2 +- .../impl/sparkle/SparkleActivator.java | 2 +- .../impl/sparkle/sparkle.manifest.mf | 4 +- .../SwingNotificationActivator.java | 7 +- .../swingnotification.manifest.mf | 4 +- .../NetworkManagerListenerImpl.java | 1 + .../sysactivity/SysActivityActivator.java | 7 +- .../SystemActivityEventDispatcher.java | 4 +- ...ystemActivityNotificationsServiceImpl.java | 6 +- .../sysactivity/sysactivity.impl.manifest.mf | 9 +- .../impl/version/VersionActivator.java | 6 +- .../impl/version/VersionImpl.java | 5 +- .../impl/version/VersionServiceImpl.java | 2 +- .../impl/version/version.impl.manifest.mf | 8 +- .../launcher/BrowserLauncher.java | 4 +- .../plugin/accountinfo/Resources.java | 2 + .../accountinfo/accountinfo.manifest.mf | 2 +- .../plugin/addrbook/AddrBookActivator.java | 6 +- .../plugin/addrbook/AdvancedConfigForm.java | 9 +- .../plugin/addrbook/addrbook.manifest.mf | 5 +- .../AdvancedConfigActivator.java | 3 +- .../advancedconfig/advancedconfig.manifest.mf | 4 +- .../plugin/aimaccregwizz/Resources.java | 2 + .../aimaccregwizz/aimaccregwizz.manifest.mf | 4 +- .../plugin/branding/AboutWindow.java | 4 +- .../plugin/branding/BrandingActivator.java | 3 +- .../plugin/branding/JitsiWarningWindow.java | 4 +- .../plugin/branding/WelcomeWindow.java | 3 +- .../plugin/branding/branding.manifest.mf | 5 +- .../certconfig/CertConfigActivator.java | 6 +- .../certconfig/CertConfigEntryDialog.java | 8 +- .../plugin/certconfig/CertConfigPanel.java | 7 +- .../certconfig/CertConfigTableModel.java | 3 +- .../plugin/certconfig/certconfig.manifest.mf | 7 +- .../chatalerter/ChatAlerterActivator.java | 3 +- .../chatalerter/chatalerter.manifest.mf | 13 +- .../chatconfig/ChatConfigActivator.java | 3 +- .../plugin/chatconfig/ChatConfigPanel.java | 2 +- .../plugin/chatconfig/chatconfig.manifest.mf | 6 +- .../replacement/ReplacementConfigPanel.java | 4 +- .../ReplacementConfigurationTableModel.java | 4 +- .../contactinfo/ContactInfoActivator.java | 2 +- .../plugin/contactinfo/Resources.java | 2 + .../contactinfo/contactinfo.manifest.mf | 2 +- .../ContactSourceConfigActivator.java | 4 +- .../contactsourceconfig.manifest.mf | 4 +- .../defaultresourcepack.manifest.mf | 2 +- .../plugin/dictaccregwizz/Resources.java | 2 + .../dictaccregwizz/dictaccregwizz.manifest.mf | 4 +- .../plugin/dnsconfig/DnsConfigActivator.java | 4 +- .../plugin/dnsconfig/DnsContainerPanel.java | 6 +- .../plugin/dnsconfig/DnssecPanel.java | 12 +- .../plugin/dnsconfig/DnssecTableModel.java | 4 +- .../plugin/dnsconfig/ParallelDnsPanel.java | 26 +- .../plugin/dnsconfig/dnsconfig.manifest.mf | 6 +- .../FacebookAccRegWizzActivator.java | 3 +- .../facebookaccregwizz.manifest.mf | 4 +- .../generalconfig/ConfigurationManager.java | 4 +- .../GeneralConfigPluginActivator.java | 3 +- .../GeneralConfigurationPanel.java | 3 +- .../plugin/generalconfig/Resources.java | 2 + .../plugin/generalconfig/SIPConfigForm.java | 2 +- .../autoaway/AutoAwayConfigurationPanel.java | 5 +- .../autoaway/AutoAwayWatcher.java | 2 +- .../generalconfig/autoaway/Preferences.java | 2 +- .../autoaway/StatusUpdateThread.java | 5 +- .../generalconfig/generalconfig.manifest.mf | 5 +- .../plugin/gibberishaccregwizz/Resources.java | 2 + .../gibberishaccregwizz.manifest.mf | 4 +- .../GlobalProxyConfigForm.java | 2 +- .../GlobalProxyPluginActivator.java | 2 +- .../plugin/globalproxyconfig/Resources.java | 3 +- .../globalproxyconfig.manifest.mf | 4 +- .../GoogleTalkAccRegWizzActivator.java | 5 +- .../googletalkaccregwizz.manifest.mf | 6 +- .../plugin/icqaccregwizz/Resources.java | 2 + .../icqaccregwizz/icqaccregwizz.manifest.mf | 4 +- .../IppiAccRegWizzActivator.java | 5 +- .../ippiaccregwizz/ippiaccregwizz.manifest.mf | 6 +- .../IptelAccRegWizzActivator.java | 5 +- .../iptelaccregwizz.manifest.mf | 6 +- .../plugin/ircaccregwizz/Resources.java | 2 + .../ircaccregwizz/ircaccregwizz.manifest.mf | 4 +- .../JabberAccRegWizzActivator.java | 2 +- .../JabberAccountRegistration.java | 2 +- .../JabberAccountRegistrationWizard.java | 2 +- .../JabberServerChooserDialog.java | 2 +- .../plugin/jabberaccregwizz/Resources.java | 2 + .../jabberaccregwizz.manifest.mf | 6 +- .../KeybindingChooserActivator.java | 3 +- .../globalchooser/GlobalShortcutDialog.java | 6 +- .../keybindingChooser.manifest.mf | 5 +- .../plugin/ldap/LdapActivator.java | 2 +- .../communicator/plugin/ldap/ldap.manifest.mf | 4 +- .../loggingutils/LoggingConfigForm.java | 18 +- .../loggingutils/LoggingUtilsActivator.java | 13 +- .../plugin/loggingutils/LogsCollector.java | 6 +- .../loggingutils/loggingutils.manifest.mf | 9 +- .../plugin/msnaccregwizz/Resources.java | 2 + .../msnaccregwizz/msnaccregwizz.manifest.mf | 4 +- .../msofficecomm/MsOfficeCommActivator.java | 3 +- .../msofficecomm/msofficecomm.manifest.mf | 1 + .../NotificationConfigurationActivator.java | 4 +- .../NotificationConfigurationPanel.java | 6 +- .../notificationconfiguration/Resources.java | 2 + .../SoundFilter.java | 3 +- .../notificationconfiguration.manifest.mf | 6 +- .../NotificationManager.java | 15 +- .../NotificationWiringActivator.java | 4 +- .../notificationwiring/SoundProperties.java | 2 +- .../notificationwiring.manifest.mf | 4 +- .../plugin/otr/OtrActionHandlers.java | 2 +- .../communicator/plugin/otr/OtrActivator.java | 3 +- .../plugin/otr/OtrConfigurationPanel.java | 2 +- .../plugin/otr/OtrConfigurator.java | 2 +- .../plugin/otr/ScOtrKeyManager.java | 2 +- .../communicator/plugin/otr/otr.manifest.mf | 4 +- .../pluginmanager/PluginManagerActivator.java | 2 +- .../plugin/pluginmanager/Resources.java | 2 + .../pluginmanager/pluginmanager.manifest.mf | 4 +- .../plugin/profiler4j/Resources.java | 2 + .../plugin/profiler4j/profiler4j.manifest.mf | 2 +- .../provisioning/ProvisioningActivator.java | 4 +- .../plugin/provisioning/ProvisioningForm.java | 5 +- .../provisioning/ProvisioningServiceImpl.java | 2 +- .../provisioning/provisioning.manifest.mf | 4 +- .../ReconnectPluginActivator.java | 4 +- .../reconnectplugin.manifest.mf | 6 +- .../plugin/rssaccregwizz/Resources.java | 2 + .../rssaccregwizz/rssaccregwizz.manifest.mf | 4 +- .../SecurityConfigActivator.java | 3 +- .../SecurityConfigurationPanel.java | 2 +- .../MasterPasswordChangeDialog.java | 3 +- .../masterpassword/MasterPasswordPanel.java | 5 +- .../masterpassword/SavedPasswordsDialog.java | 8 +- .../securityconfig/securityconfig.manifest.mf | 4 +- .../InitialAccountRegistrationFrame.java | 2 +- .../plugin/simpleaccreg/Resources.java | 3 + .../SimpleAccountRegistrationActivator.java | 4 +- .../simpleaccreg/simpleaccreg.manifest.mf | 4 +- .../Sip2SipAccRegWizzActivator.java | 5 +- .../sip2sipaccregwizz.manifest.mf | 6 +- .../plugin/sipaccregwizz/Resources.java | 2 + .../sipaccregwizz/SIPAccRegWizzActivator.java | 2 +- .../plugin/sipaccregwizz/SecurityPanel.java | 7 +- .../sipaccregwizz/sipaccregwizz.manifest.mf | 6 +- .../plugin/skinmanager/Resources.java | 2 + .../skinmanager/SkinManagerActivator.java | 2 +- .../skinmanager/SkinSelectionListener.java | 2 +- .../plugin/skinmanager/SkinSelector.java | 2 +- .../skinmanager/skinmanager.manifest.mf | 4 +- .../skinresourcepack.manifest.mf | 2 +- .../plugin/spellcheck/ChatAttachments.java | 4 +- .../plugin/spellcheck/DocUnderliner.java | 2 +- .../plugin/spellcheck/Parameters.java | 2 +- .../plugin/spellcheck/Resources.java | 4 +- .../spellcheck/SpellCheckActivator.java | 6 +- .../plugin/spellcheck/SpellChecker.java | 4 +- .../spellcheck/SpellCheckerConfigDialog.java | 8 +- .../communicator/plugin/spellcheck/Word.java | 2 +- .../plugin/spellcheck/spellCheck.manifest.mf | 8 +- .../plugin/sshaccregwizz/Resources.java | 2 + .../sshaccregwizz/sshaccregwizz.manifest.mf | 4 +- .../communicator/plugin/update/Resources.java | 3 +- .../communicator/plugin/update/Update.java | 12 +- .../plugin/update/UpdateActivator.java | 6 +- .../plugin/update/update.manifest.mf | 6 +- .../plugin/whiteboard/Resources.java | 2 + .../plugin/whiteboard/WhiteboardMenuItem.java | 2 +- .../whiteboard/gui/WhiteboardFileFilter.java | 2 +- .../whiteboard/gui/WhiteboardPanel.java | 2 +- .../gui/whiteboardshapes/WhiteboardShape.java | 2 +- .../plugin/whiteboard/whiteboard.manifest.mf | 2 +- .../plugin/yahooaccregwizz/Resources.java | 2 + .../yahooaccregwizz.manifest.mf | 4 +- .../plugin/zeroconfaccregwizz/Resources.java | 2 + .../zeroconfaccregwizz.manifest.mf | 4 +- .../audionotifier/AudioNotifierService.java | 47 - .../service/audionotifier/SCAudioClip.java | 33 - .../certificate/CertificateService.java | 2 +- .../service/certificate/KeyStoreType.java | 2 +- .../ConfigPropertyVetoException.java | 53 - .../ConfigVetoableChangeListener.java | 25 - .../configuration/ConfigurationService.java | 454 --- .../service/contactsource/SourceContact.java | 2 +- .../fileaccess/FailSafeTransaction.java | 60 - .../service/fileaccess/FileAccessService.java | 128 - .../globalshortcut/GlobalShortcutService.java | 2 +- .../communicator/service/gui/Container.java | 2 +- .../service/gui/LazyConfigurationForm.java | 2 + .../communicator/service/gui/UIService.java | 2 +- .../service/gui/event/ChatListener.java | 2 +- .../service/gui/event/ChatMenuListener.java | 2 +- .../communicator/service/gui/gui.manifest.mf | 2 +- .../gui/internal/GuiServiceActivator.java | 2 +- .../service/httputil/HttpUtilActivator.java | 4 +- .../service/httputil/httputil.manifest.mf | 4 +- .../keybindings/KeybindingsService.java | 2 +- .../service/ldap/ldap.manifest.mf | 2 +- .../service/neomedia/AbstractMediaStream.java | 168 -- .../service/neomedia/AudioMediaStream.java | 94 - .../service/neomedia/DTMFInbandTone.java | 423 --- .../service/neomedia/DTMFMethod.java | 30 - .../service/neomedia/DTMFRtpTone.java | 220 -- .../neomedia/DefaultStreamConnector.java | 301 -- .../neomedia/DefaultTCPStreamConnector.java | 177 -- .../service/neomedia/MediaDirection.java | 261 -- .../service/neomedia/MediaException.java | 111 - .../service/neomedia/MediaService.java | 320 -- .../service/neomedia/MediaStream.java | 357 --- .../service/neomedia/MediaStreamStats.java | 139 - .../service/neomedia/MediaStreamTarget.java | 157 - .../service/neomedia/MediaType.java | 80 - .../neomedia/MediaTypeSrtpControl.java | 90 - .../service/neomedia/MediaUseCase.java | 83 - .../service/neomedia/QualityControl.java | 53 - .../service/neomedia/QualityPreset.java | 111 - .../service/neomedia/RTPExtension.java | 200 -- .../service/neomedia/RTPTranslator.java | 22 - .../service/neomedia/Recorder.java | 121 - .../service/neomedia/SDesControl.java | 80 - .../service/neomedia/SrtpControl.java | 92 - .../service/neomedia/SrtpControlType.java | 32 - .../service/neomedia/StreamConnector.java | 105 - .../neomedia/StreamConnectorDelegate.java | 88 - .../neomedia/StreamConnectorFactory.java | 22 - .../service/neomedia/VideoMediaStream.java | 134 - .../service/neomedia/VolumeControl.java | 82 - .../service/neomedia/ZrtpControl.java | 96 - .../neomedia/control/KeyFrameControl.java | 182 -- .../control/KeyFrameControlAdapter.java | 276 -- .../service/neomedia/device/MediaDevice.java | 83 - .../neomedia/device/MediaDeviceWrapper.java | 26 - .../service/neomedia/device/ScreenDevice.java | 41 - .../event/CsrcAudioLevelListener.java | 30 - .../service/neomedia/event/DTMFListener.java | 33 - .../service/neomedia/event/DTMFToneEvent.java | 56 - .../neomedia/event/RTCPFeedbackEvent.java | 91 - .../neomedia/event/RTCPFeedbackListener.java | 25 - .../event/SimpleAudioLevelListener.java | 52 - .../service/neomedia/event/SrtpListener.java | 69 - .../neomedia/event/VolumeChangeEvent.java | 87 - .../neomedia/event/VolumeChangeListener.java | 22 - .../neomedia/format/AudioMediaFormat.java | 27 - .../service/neomedia/format/MediaFormat.java | 174 -- .../neomedia/format/MediaFormatFactory.java | 226 -- .../neomedia/format/VideoMediaFormat.java | 36 - .../notification/NotificationAction.java | 2 +- .../NotificationServiceActivator.java | 2 +- .../notification/NotificationServiceImpl.java | 2 +- .../SoundNotificationHandler.java | 2 +- .../notification/notification.manifest.mf | 2 +- .../PacketLoggingConfiguration.java | 237 -- .../packetlogging/PacketLoggingService.java | 130 - .../service/protocol/AbstractCallPeer.java | 4 +- .../protocol/AbstractConferenceMember.java | 2 +- .../service/protocol/AccountManager.java | 2 +- .../service/protocol/CallPeer.java | 4 +- .../service/protocol/DTMFTone.java | 201 -- .../protocol/OperationSetBasicTelephony.java | 3 +- .../service/protocol/OperationSetDTMF.java | 2 + .../OperationSetDesktopStreaming.java | 4 +- .../protocol/OperationSetVideoTelephony.java | 5 +- .../protocol/ProtocolProviderActivator.java | 8 +- .../protocol/ProtocolProviderFactory.java | 2 +- ...ocChatRoomParticipantPresenceListener.java | 2 +- .../service/protocol/event/CallEvent.java | 3 +- .../event/CallPeerSecurityListener.java | 2 + .../event/CallPeerSecurityMessageEvent.java | 112 - ...llPeerSecurityNegotiationStartedEvent.java | 4 +- .../event/CallPeerSecurityOffEvent.java | 2 + .../event/CallPeerSecurityOnEvent.java | 4 +- .../event/CallPeerSecurityStatusEvent.java | 64 - .../event/CallPeerSecurityTimeoutEvent.java | 2 + .../protocol/event/DTMFReceivedEvent.java | 4 +- .../WhiteboardInvitationReceivedEvent.java | 2 +- .../WhiteboardInvitationRejectedEvent.java | 2 +- .../event/WhiteboardObjectDeletedEvent.java | 2 +- .../WhiteboardSessionPresenceChangeEvent.java | 2 +- .../AbstractOperationSetBasicTelephony.java | 3 +- .../AbstractOperationSetVideoTelephony.java | 5 +- .../media/AbstractQualityControlWrapper.java | 6 +- .../protocol/media/CallPeerMediaHandler.java | 13 +- .../media/DynamicPayloadTypeRegistry.java | 4 +- .../media/DynamicRTPExtensionsRegistry.java | 2 +- .../protocol/media/MediaAwareCall.java | 9 +- .../protocol/media/MediaAwareCallPeer.java | 5 +- .../service/protocol/media/MediaHandler.java | 13 +- .../media/ProtocolMediaActivator.java | 4 +- .../protocol/media/TransportManager.java | 4 +- .../protocol/media/protocol.media.manifest.mf | 13 +- .../protocol/protocol.provider.manifest.mf | 6 +- .../whiteboardobjects/WhiteboardObject.java | 2 +- .../WhiteboardObjectCircle.java | 2 +- .../WhiteboardObjectEllipse.java | 2 +- .../WhiteboardObjectImage.java | 2 +- .../WhiteboardObjectLine.java | 2 +- .../WhiteboardObjectRect.java | 2 +- .../WhiteboardObjectText.java | 2 +- .../service/provdisc/provdisc.manifest.mf | 2 +- .../replacement/ReplacementProperty.java | 2 +- .../replacement/ReplacementService.java | 2 +- .../replacement/replacement.manifest.mf | 2 +- .../service/replacement/smilies/Smiley.java | 2 +- .../resources/ResourceManagementService.java | 261 -- .../ResourceManagementServiceUtils.java | 1 + .../communicator/service/version/Version.java | 148 - .../service/version/VersionService.java | 37 - .../service/version/version.manifest.mf | 6 - .../sip/communicator/util/FileHandler.java | 1 - .../java/sip/communicator/util/OSUtils.java | 171 -- .../communicator/util/OrderedProperties.java | 2 +- .../sip/communicator/util/SoundFileUtils.java | 125 - .../sip/communicator/util/UtilActivator.java | 3 +- .../util/dns/ConfigurableDnssecResolver.java | 4 +- .../util/dns/DnsUtilActivator.java | 3 +- .../util/dns/util.dns.manifest.mf | 4 +- .../util/event/PropertyChangeNotifier.java | 135 - .../util/event/SizeChangeVideoEvent.java | 96 - .../communicator/util/event/VideoEvent.java | 226 -- .../util/event/VideoListener.java | 50 - .../util/event/VideoNotifierSupport.java | 327 -- .../util/launchutils/LaunchArgHandler.java | 2 + .../util/swing/AuthenticationWindow.java | 2 + .../util/swing/EmphasizedLabel.java | 2 +- .../communicator/util/swing/FitLayout.java | 166 -- .../communicator/util/swing/FramedImage.java | 2 +- .../util/swing/GenericFileDialog.java | 4 +- .../util/swing/MasterPasswordInputDialog.java | 3 +- .../util/swing/SIPCommCheckBox.java | 2 +- .../util/swing/SIPCommDialog.java | 5 +- .../communicator/util/swing/SIPCommFrame.java | 7 +- .../util/swing/SIPCommRadioButton.java | 2 +- .../util/swing/SIPCommTextField.java | 2 +- .../util/swing/SipCommFileDialogImpl.java | 4 +- .../util/swing/SoundLevelIndicator.java | 3 +- .../communicator/util/swing/SwingWorker.java | 2 +- .../util/swing/TransparentPanel.java | 12 +- .../util/swing/VideoContainer.java | 368 --- .../communicator/util/swing/VideoLayout.java | 470 --- .../util/swing/X509CertificatePanel.java | 3 +- .../util/swing/plaf/SIPCommTextFieldUI.java | 2 +- .../transparent/AWTUtilitiesWrapper.java | 2 +- .../sip/communicator/util/util.manifest.mf | 7 +- .../ConfigurationServiceLick.java | 2 +- .../TestConfigurationService.java | 4 +- .../TestConfigurationServicePersistency.java | 2 +- .../TestConfigurationSlickFinalizer.java | 2 +- .../configuration.slick.manifest.mf | 2 +- .../contactlist/meta.cl.slick.manifest.mf | 2 +- .../fileaccess/FileAccessServiceLick.java | 5 +- .../fileaccess/TestFailSafeTransaction.java | 7 +- .../fileaccess/TestFileAccessService.java | 5 +- .../fileaccess/fileaccess.slick.manifest.mf | 4 +- .../slick/history/history.slick.manifest.mf | 2 +- .../TestNetworkAddressManagerService.java | 2 +- .../slick/netaddr/netaddr.slick.manifest.mf | 2 +- .../slick/protocol/generic/AuthHandler.java | 2 +- .../protocol/generic/ImEventCollector.java | 2 +- .../generic/TestOperationSetFileTransfer.java | 4 +- .../TestAccountUninstallationPersistence.java | 2 +- .../gibberish.provider.slick.manifest.mf | 2 +- .../TestAccountUninstallationPersistence.java | 2 +- .../icq/icq.provider.slick.manifest.mf | 4 +- .../jabber/TestAccountInstallation.java | 2 +- .../TestAccountUninstallationPersistence.java | 2 +- .../jabber/jabber.provider.slick.manifest.mf | 4 +- .../TestAccountUninstallationPersistence.java | 2 +- .../msn/msn.provider.slick.manifest.mf | 4 +- .../TestAccountUninstallationPersistence.java | 2 +- .../rss/rss.provider.slick.manifest.mf | 2 +- .../TestAccountUninstallationPersistence.java | 2 +- .../sip/sip.provider.slick.manifest.mf | 2 +- .../TestAccountUninstallationPersistence.java | 2 +- .../yahoo/yahoo.provider.slick.manifest.mf | 4 +- .../slick/runner/slick-runner.manifest.mf | 2 +- .../slick/slickless/slickless.manifest.mf | 2 +- .../slick/version/version.slick.manifest.mf | 2 +- 1086 files changed, 1609 insertions(+), 129748 deletions(-) create mode 100644 lib/installer-exclude/libjitsi.jar delete mode 100755 src/net/java/sip/communicator/impl/neomedia/AbstractRTPConnector.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/AbstractVolumeControl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/ArrayIOUtils.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/AudioMediaStreamImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/MediaStreamImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/MediaStreamStatsImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/MediaUtils.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/ProcessorUtility.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/RTCPConnectorInputStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/RTCPFeedbackPacket.java delete mode 100755 src/net/java/sip/communicator/impl/neomedia/RTPConnectorInputStream.java delete mode 100755 src/net/java/sip/communicator/impl/neomedia/RTPConnectorOutputStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPInputStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPOutputStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPInputStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPOutputStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/RTPTranslatorImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/RawPacket.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/RecorderImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/StreamRTPManager.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/VideoMediaStreamImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/ZrtpConfigureUtils.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/ZrtpControlImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/ZrtpFortunaEntropyGatherer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelCalculator.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelEffect.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelEventDispatcher.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelMap.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/AbstractCodecExt.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/Constants.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/EncodingConfiguration.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/FFmpeg.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/alaw/DePacketizer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/alaw/JavaEncoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/alaw/Packetizer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g722/JNIDecoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g722/JNIEncoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/AcelpCo.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Bits.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/CodLd8k.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Coder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/CorFunc.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/DeAcelp.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/DecGain.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/DecLag3.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/DecLd8k.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Decoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Filter.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/FloatReference.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Gainpred.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/IntReference.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/JavaDecoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/JavaEncoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Ld8k.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Lpc.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Lpcfunc.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Lspdec.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Lspgetq.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/PParity.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Pitch.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/PostPro.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Postfil.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/PreProc.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/PredLt3.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Pwf.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/QuaGain.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/QuaLsp.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/TabLd8k.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Taming.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Util.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/DePacketizer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/Decoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/Encoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/GSMDecoderUtil.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/GSMEncoderUtil.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/Packetizer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/JavaDecoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/JavaEncoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/bitpack.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/bitstream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/ilbc_common.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/ilbc_constants.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/ilbc_decoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/ilbc_encoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/ilbc_ulp.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/mp3/JNIEncoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/JavaDecoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/JavaEncoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_A2NLSF.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_CNG.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_HP_variable_cutoff_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_Inlines.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LBRR_reset.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_analysis_filter_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_inv_pred_gain.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_inv_pred_gain_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_stabilize.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_synthesis_filter.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_synthesis_order16.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LP_variable_cutoff.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LSF_cos_table.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LTP_analysis_filter_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LTP_scale_ctrl_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_MA.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF2A.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF2A_stable.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_MSVQ_decode.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_MSVQ_decode_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_MSVQ_encode_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_VQ_rate_distortion_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_VQ_sum_error_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_VQ_weights_laroia_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_stabilize.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NSQ.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NSQ_del_dec.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_PLC.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_SDK_API.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_SigProc_FIX.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_SigProc_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_VAD.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_VQ_nearest_neighbor_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_allpass_int.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_allpass_int_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_ana_filt_bank_1.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_apply_sine_window_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_autocorrelation_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_biquad.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_biquad_alt.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_burg_modified_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_bwexpander.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_bwexpander_32.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_bwexpander_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_code_signs.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_common_pitch_est_defines.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_control.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_control_codec_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_corrMatrix_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_create_init_destroy.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_dec_API.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decimate2_coarse_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decimate2_coarsest_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decode_core.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decode_frame.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decode_parameters.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decode_pitch.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decode_pulses.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decoder_set_fs.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_define.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_define_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_detect_SWB_input.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_enc_API.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_encode_frame_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_encode_parameters.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_encode_pulses.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_energy_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_errors.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_find_LPC_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_find_LTP_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_find_pitch_lags_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_find_pred_coefs_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_gain_quant.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_init_encoder_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_inner_product_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_interpolate.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_k2a_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_levinsondurbin_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_lin2log.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_log2lin.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_lowpass_int.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_lowpass_short.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_macros.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_main_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_noise_shape_analysis_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_perceptual_parameters_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_pitch_analysis_core_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_pitch_est_defines.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_pitch_est_defines_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_pitch_est_tables.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_prefilter_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_process_NLSFs_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_process_gains_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_quant_LTP_gains_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_range_coder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_regularize_correlations_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_down2.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_down2_3.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_down3.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_AR2.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_ARMA4.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_IIR_FIR.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_copy.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_down4.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_down_FIR.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_up2_HQ.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_up4.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_rom.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_structs.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_up2.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_residual_energy_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_scale_copy_vector_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_scale_vector_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_schur_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_shell_coder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_sigm_Q15.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_solve_LS_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_sort.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_sort_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_structs.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_structs_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_sum_sqr_shift.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_LTP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB0_10.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB0_10_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB0_16.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB0_16_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB1_10.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB1_10_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB1_16.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB1_16_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_gain.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_other.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_other_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_pitch_lag.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_pulses_per_block.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_sign.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_type_offset.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_typedef.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_wrappers_FLP.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/JNIDecoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/JNIEncoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/JavaDecoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/JavaEncoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/Speex.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/SpeexResampler.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/ulaw/JavaDecoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/ulaw/JavaEncoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/audio/ulaw/Packetizer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/video/AVFrame.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/video/AVFrameFormat.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/video/ByteBuffer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/video/FinalizableAVFrame.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/video/HFlip.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/video/ImageScaler.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/video/SwScaler.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/video/h263p/DePacketizer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/video/h263p/JNIDecoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/video/h263p/JNIEncoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/video/h263p/Packetizer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/video/h264/DePacketizer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/video/h264/JNIDecoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/video/h264/JNIEncoder.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/codec/video/h264/Packetizer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/conference/AudioMixer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/conference/AudioMixerPushBufferStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/conference/AudioMixingPushBufferDataSource.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/conference/AudioMixingPushBufferStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/conference/DataSourceFilter.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/conference/InputDataSourceDesc.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/conference/InputStreamDesc.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/control/AbstractControls.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/control/AbstractFormatControl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/control/ControlsAdapter.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/control/FrameProcessingControlImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/control/FrameRateControlAdapter.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/control/ReadOnlyBufferControlDelegate.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/control/ReadOnlyFormatControlDelegate.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/AbstractMediaDevice.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/AudioMediaDeviceImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/AudioMediaDeviceSession.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/AudioMixerMediaDevice.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/AudioSystem.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/DeviceConfiguration.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/DeviceSystem.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/DirectShowSystem.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/ImgStreamingSystem.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/JavaSoundSystem.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/LtiCivilSystem.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceSession.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/NoneAudioSystem.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/PortAudioSystem.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/PulseAudioSystem.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/QuickTimeSystem.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/ReceiveStreamPushBufferDataSource.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/ScreenDeviceImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/Video4Linux2System.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/device/VideoTranslatorMediaDevice.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/directshow/DSCaptureDevice.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/directshow/DSFormat.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/directshow/DSManager.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/format/AudioMediaFormatImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/format/MediaFormatFactoryImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/format/MediaFormatImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/format/ParameterizedVideoFormat.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/format/VideoMediaFormatImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteract.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteractImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/imgstreaming/ImageStreamingUtils.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/imgstreaming/NativeScreenCapture.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractBufferCaptureDevice.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractBufferStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPullBufferCaptureDevice.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPullBufferStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPushBufferCaptureDevice.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPushBufferStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractVideoPullBufferCaptureDevice.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractVideoPullBufferStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractVideoPushBufferCaptureDevice.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/ByteBufferPool.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/alsa/AlsaStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/alsa/DataSource.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/directshow/DataSource.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/directshow/DirectShowStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/DataSource.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/portaudio/DataSource.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/portaudio/PortAudioStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/pulseaudio/DataSource.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/DataSource.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/QuickTimeStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/video4linux2/DataSource.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/video4linux2/Video4Linux2.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/video4linux2/Video4Linux2Stream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/AbstractRenderer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/audio/PortAudioRenderer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/audio/PulseAudioRenderer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRendererSwingVideoComponent.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRendererVideoComponent.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/notify/AudioNotifierServiceImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/notify/AudioSystemClipImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/notify/JavaSoundClipImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/notify/SCAudioClipImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudio.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudioException.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudioStreamCallback.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/protocol/BufferStreamAdapter.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/protocol/CachingPushBufferStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/protocol/CaptureDeviceDelegatePullBufferDataSource.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/protocol/CaptureDeviceDelegatePushBufferDataSource.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/protocol/InbandDTMFDataSource.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/protocol/MuteDataSource.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/protocol/PullBufferDataSourceDelegate.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/protocol/PullBufferStreamAdapter.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/protocol/PushBufferDataSourceAdapter.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/protocol/PushBufferDataSourceDelegate.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/protocol/PushBufferStreamAdapter.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/protocol/RewritablePullBufferDataSource.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/protocol/RewritablePushBufferDataSource.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/protocol/SourceStreamDelegate.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/protocol/StreamSubstituteBufferTransferHandler.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/protocol/TranscodingDataSource.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/pulseaudio/PA.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/CVImageBuffer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/CVPixelBuffer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/CVPixelBufferAttributeKey.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/CVPixelFormatType.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/NSDictionary.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/NSError.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/NSErrorException.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/NSMutableDictionary.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/NSObject.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureDecompressedVideoOutput.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureDevice.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureDeviceInput.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureInput.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureOutput.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureSession.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/QTFormatDescription.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/QTMediaType.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/quicktime/QTSampleBuffer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/ControlTransformInputStream.java delete mode 100755 src/net/java/sip/communicator/impl/neomedia/transform/PacketTransformer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/RTPTransformTCPConnector.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/RTPTransformUDPConnector.java delete mode 100755 src/net/java/sip/communicator/impl/neomedia/transform/TransformEngine.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/TransformEngineChain.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/TransformTCPInputStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/TransformTCPOutputStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/TransformUDPInputStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/TransformUDPOutputStream.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/csrc/CsrcTransformEngine.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/dtmf/DtmfRawPacket.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/dtmf/DtmfTransformEngine.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/rtcp/StatisticsEngine.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/sdes/SDesControlImpl.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/sdes/SDesTransformEngine.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/srtp/AsymmetricSRTPTransformer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTCPCryptoContext.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTCPTransformer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCipherCTR.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCipherF8.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCryptoContext.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPPolicy.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPTransformEngine.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPTransformer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/zrtp/SecurityEventManager.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZRTCPTransformer.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZRTPTransformEngine.java delete mode 100644 src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZrtpRawPacket.java delete mode 100644 src/net/java/sip/communicator/service/audionotifier/AudioNotifierService.java delete mode 100644 src/net/java/sip/communicator/service/audionotifier/SCAudioClip.java delete mode 100644 src/net/java/sip/communicator/service/configuration/ConfigPropertyVetoException.java delete mode 100644 src/net/java/sip/communicator/service/configuration/ConfigVetoableChangeListener.java delete mode 100644 src/net/java/sip/communicator/service/configuration/ConfigurationService.java delete mode 100644 src/net/java/sip/communicator/service/fileaccess/FailSafeTransaction.java delete mode 100644 src/net/java/sip/communicator/service/fileaccess/FileAccessService.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/AbstractMediaStream.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/AudioMediaStream.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/DTMFInbandTone.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/DTMFMethod.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/DTMFRtpTone.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/DefaultStreamConnector.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/DefaultTCPStreamConnector.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/MediaDirection.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/MediaException.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/MediaService.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/MediaStream.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/MediaStreamStats.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/MediaStreamTarget.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/MediaType.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/MediaTypeSrtpControl.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/MediaUseCase.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/QualityControl.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/QualityPreset.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/RTPExtension.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/RTPTranslator.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/Recorder.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/SDesControl.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/SrtpControl.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/SrtpControlType.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/StreamConnector.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/StreamConnectorDelegate.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/StreamConnectorFactory.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/VideoMediaStream.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/VolumeControl.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/ZrtpControl.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/control/KeyFrameControl.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/control/KeyFrameControlAdapter.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/device/MediaDevice.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/device/MediaDeviceWrapper.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/device/ScreenDevice.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/event/CsrcAudioLevelListener.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/event/DTMFListener.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/event/DTMFToneEvent.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/event/RTCPFeedbackEvent.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/event/RTCPFeedbackListener.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/event/SimpleAudioLevelListener.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/event/SrtpListener.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/event/VolumeChangeEvent.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/event/VolumeChangeListener.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/format/AudioMediaFormat.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/format/MediaFormat.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/format/MediaFormatFactory.java delete mode 100644 src/net/java/sip/communicator/service/neomedia/format/VideoMediaFormat.java delete mode 100644 src/net/java/sip/communicator/service/packetlogging/PacketLoggingConfiguration.java delete mode 100644 src/net/java/sip/communicator/service/packetlogging/PacketLoggingService.java delete mode 100644 src/net/java/sip/communicator/service/protocol/DTMFTone.java delete mode 100644 src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityMessageEvent.java delete mode 100644 src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityStatusEvent.java delete mode 100644 src/net/java/sip/communicator/service/resources/ResourceManagementService.java delete mode 100644 src/net/java/sip/communicator/service/version/Version.java delete mode 100644 src/net/java/sip/communicator/service/version/VersionService.java delete mode 100755 src/net/java/sip/communicator/service/version/version.manifest.mf delete mode 100644 src/net/java/sip/communicator/util/OSUtils.java delete mode 100644 src/net/java/sip/communicator/util/SoundFileUtils.java delete mode 100644 src/net/java/sip/communicator/util/event/PropertyChangeNotifier.java delete mode 100644 src/net/java/sip/communicator/util/event/SizeChangeVideoEvent.java delete mode 100644 src/net/java/sip/communicator/util/event/VideoEvent.java delete mode 100644 src/net/java/sip/communicator/util/event/VideoListener.java delete mode 100644 src/net/java/sip/communicator/util/event/VideoNotifierSupport.java delete mode 100644 src/net/java/sip/communicator/util/swing/FitLayout.java delete mode 100644 src/net/java/sip/communicator/util/swing/VideoContainer.java delete mode 100644 src/net/java/sip/communicator/util/swing/VideoLayout.java diff --git a/.classpath b/.classpath index 9a97ae24b..26c77551c 100644 --- a/.classpath +++ b/.classpath @@ -36,6 +36,7 @@ + diff --git a/build.xml b/build.xml index 673099616..dfc6a8e25 100644 --- a/build.xml +++ b/build.xml @@ -471,8 +471,15 @@ - + + + + + + + @@ -905,7 +912,7 @@ bundle-plugin-msnaccregwizz,bundle-plugin-sipaccregwizz, bundle-plugin-yahooaccregwizz,bundle-plugin-aimaccregwizz, bundle-commons-codec,bundle-httputil,bundle-plugin-spellcheck, - bundle-version,bundle-version-impl,bundle-shutdown-timeout, + bundle-version-impl,bundle-shutdown-timeout, bundle-growlnotification,bundle-swingnotification,bundle-galagonotification, bundle-sparkle, bundle-plugin-branding, bundle-systemactivitynotifications, @@ -935,7 +942,7 @@ bundle-provdisc,bundle-provdisc-dhcp,bundle-provdisc-mdns, bundle-provisioning,bundle-addrbook,bundle-plugin-ldap, bundle-plugin-contactsourceconfig,bundle-plugin-certconfig, - bundle-globalshortcut,bundle-plugin-msofficecomm"/> + bundle-globalshortcut,bundle-plugin-msofficecomm,bundle-libjitsi"/> @@ -1073,8 +1080,6 @@ destfile="${bundles.dest}/configuration.jar" manifest="${src}/net/java/sip/communicator/impl/configuration/configuration.manifest.mf" > - @@ -1120,24 +1125,33 @@ + + + + + + + + + + - - - - @@ -1700,16 +1714,6 @@ javax.swing.event, javax.swing.border"/> - - - - - - - - @@ -2666,8 +2670,6 @@ javax.swing.event, javax.swing.border"/> - diff --git a/lib/felix.client.run.properties b/lib/felix.client.run.properties index 8f63d7b9c..1dc204200 100644 --- a/lib/felix.client.run.properties +++ b/lib/felix.client.run.properties @@ -31,6 +31,9 @@ felix.auto.start.10= \ # file:lib/bundle/servicebinder.jar \ # file:lib/bundle/tablelayout.jar +felix.auto.start.15= \ + reference:file:sc-bundles/libjitsi.jar + felix.auto.start.20= \ reference:file:sc-bundles/util.jar \ reference:file:lib/bundle/log4j.jar \ @@ -69,7 +72,6 @@ felix.auto.start.42= \ felix.auto.start.45= \ reference:file:sc-bundles/ui-service.jar \ reference:file:sc-bundles/argdelegation-service.jar \ - reference:file:sc-bundles/version.jar \ reference:file:sc-bundles/version-impl.jar \ reference:file:sc-bundles/branding.jar \ reference:file:sc-bundles/provdisc-dhcp.jar \ diff --git a/lib/felix.unit.test.properties b/lib/felix.unit.test.properties index 0a454475d..2637869ae 100644 --- a/lib/felix.unit.test.properties +++ b/lib/felix.unit.test.properties @@ -51,6 +51,9 @@ felix.auto.start.10= \ # file:lib/bundle/bundlerepository.jar \ # file:lib/bundle/servicebinder.jar \ +felix.auto.start.15= \ + reference:file:sc-bundles/libjitsi.jar + felix.auto.start.20= \ reference:file:sc-bundles/util.jar \ reference:file:lib/bundle/log4j.jar \ @@ -74,7 +77,6 @@ felix.auto.start.40= \ reference:file:sc-bundles/resourcemanager.jar \ reference:file:sc-bundles/defaultresources.jar \ reference:file:sc-bundles/jfontchooserlib.jar \ - reference:file:sc-bundles/version.jar \ reference:file:sc-bundles/version-impl.jar \ reference:file:sc-bundles/keybindings.jar \ reference:file:sc-bundles/netaddr.jar \ diff --git a/lib/installer-exclude/libjitsi.jar b/lib/installer-exclude/libjitsi.jar new file mode 100644 index 0000000000000000000000000000000000000000..de260e2883000185778e9fb7675cd74a8ad14f8b GIT binary patch literal 1759618 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

q9Ag7A+Bsoo-r^rLZd73;_oM*`C;{236Oq^%Q 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

`T5RJ*}UelB}JyPs>Q_ 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ℑ_$tMmpN+zU4Bu(vEDVVZKM{vquHpm_afA0 zdM0TK7)3dEg~ukaVm7#c3ks^!FJ)mq(2ugxl9EyeSSkD&&X9Z|IYder22<4G79SCE zh?v)KRpnAgsZvKU@L8O)3z4E=y9Ix2MRB>}wH35W* zAccxxX4_y0lbXw?P*|`jlHhb{Hz*e*l)q1Z;#07MDOrFca0LtZr(rW->ob*>@Kw-0f5WprOUby(&}tyogB>m0!H=&rtw%Uim7u4tils-$hOudf4plbbheX=w-V z6zRtvzy1yw{bQt}GDDXQ+nJ>kt%2q&e+IX7^kZMhiN+c1!+JHw6dN4QXmZG7UFLWK zudr>OY%&0>`fV8XPbb3+Fo$7t3FZ+r@Z|*r3kenxEGAe&a0bCrg4G0TxnX=5mYJ{6 zvkQ-e)#%>>79aXG@csNlu@qP7ESHHuL?icvv|QAdhVO^Q)dicwjLm$~^n)5XhO-00#JE?(*4 zRW3$7>-THidsI2@J@|oKfX~L&6E3Ila6TVtJrN`qscN4fm3sLdGzwv<)0rL2+;f?byECZD6hdo1aUfKSsKSXEZZWfmPrLR>=Utprza4UTtMm2&yf2J-n!?n+&w8 z^U}7-nK>O2bhZBvL7}An14#P zw)XAr7@+E`WoIvE1f#@irgf9^x}Gbtzlf`1V|_Dh>zfDr_I2*-=|etFtosY;q?=K6nz<17 zO;B^jvs8aq!rZT2--{V_A@zY-fvQ*Rhq9@=4d%iS3o+xr`l`7il?0%N-9-)O^5Lrc zn%148y)mOKEA8pR2LAyQs=8fUn{oxTe9-)X95ls_Zr8CwOmB_Cx2>p~3AvSNz}CkCt}#7$H1O(m|AP)m9j41vmI*S^#$xlTS4C3^Ly}?bPG)}c=-!5~hlRvfQ4I?}1FwpX#+D1r z26^2bf6<6kp(&A6C&%&mhr(xwXtm{O)C1C6(E3R|#6c^XKc&dx1xp=yZ zXSjH#i)Xobwu|Suc&>}*xp=;d8(h4=#S2}$$i<6Yyu`(4xOl0Hm$~>%7cX~lql;I# z7}TldTkYPjaq(IgpXFkjG4YQEMEqOthHr53Mi*~#@n#oqadESYK`{FLdG7r-7oYFq z?Jfp6=zAApmks|eR!r6!!v$FDR$Sc;H6?Uva&tawoz~WZy*4V^$KkT+F$qy6`?y4K zSwwzXtydnEVk%=x9+gt!D6N{#s0tjCau}gFRgX)Q`q^gPB>fwF9mg&9?Iv(pj?0Qi zrBWk8!aURlOv*yWZqQmv~uE8v=k z_7i#oZw>G?Qe~UhlJ0;T+&Y~P;hu7(dH;~Xc%bSPy?2+e^Xxv{Wo}I?FeQ)Fm?PmXR{Bc zS4IlPbtEg>E}NK>N!Jo|BnI&rJ5z9FSw^}Q-Sl_Ds?0X19`5H#r{YjGC+utXy#KU<+7UT%;5^R_ngqMr%_BwiEnbM|)HEN(ckp9bJZX zA7UWJTc= zbl5Cp9uZUjxKK5gF#4g+ap{Okn!~G^?lolTdN^G335Fs`t$vqdx*fXuZC1fgti4RJ zfCgu@m-UEE)Uhh@$yc>aI;Xy>&27kJY|u%->TpfF-PIzVKa|x8fC+(y&jLRZ!X*@g z5nQV06tXstO9?{VrDpfisdxMfjg}A`PaNt&mtSFfx+%_v0*yX4CxQz~Or18J2K@=z zgNI-d9!VA@v7H^xI7&Y*(d7wnsb14sNH4vdo%Xj^4-*F;fgjE8^&OMK>xVyX41Pa? zi1}NN_=nfD98ywpc3!(W^etK(2DO)1Qff&QN*3r(@piWUG!CsxcYi0%%v`&+ZuoZO z@|S-vYyweVXLQ0L-7;u(>$sWJzY?KtBf_%yv=jrWX6k}=a%S4b#)oX{u70rEv|7%$ zTV^8|_Y|}|t#q5k)@D%=#ch;4W6wMH_Wt(@G%0_>??QP)cV1P)Y#=O2ni`KHfB`{> z1_YsOt7J>YsNZ3W`p?}d6OYi!6{*|C;cDWt^3?1yMd1xls}8iT=R%z_j6R%O%1g9o z2nqEKY#IQkXiQH+>pR=qyE>?)EY!#z*-+PX+IfQefuyAI1eGQkpSS zwqeui40|lds)G|ueKH2^K&undQpQf%*aIL32!%VaA@<1*LfPSwWk4R-SzuQeA6L4M z=iqf3zf4j>tfEo!G!6jMIRGU6T%Sq?XyTOQ3{!BF-~6|~e&Gy|Cx2@Y)$oUcT$8*! zDjiEItt45Vm{cvbbiu%VA}U>aIurqMrZ`QZSPX}&H?xSNRC-DTdiLqj zVjR?xOMsv~uaccl3C>SC4Ag@xL4Y7bmjL-aJ?8TJ0`#3Xgid<0V;~ILSqQ`e z_e$w`i`#b9UnIPLU@qf~M$QELB(#l{J;B^>(FPa#%@Iv*ZWlz33UJ|BL8rM<7{l7h z_!n-I$nY;?Fg|f&Ez|Ky$ph42#-|h)Q;dPo80D>VC*S3%(acvr?Wvk}u9bUr)0)>u zt_IuBFs%8XN(A(gKj}{d5bozgKObgdCV7#FPflhJZguYUfW-KtMs>u)pw5b?OKM(f za&#^YD1~K_R~APE`U7Rbr5EXnM5eyI40*x+GLP|1k=L@*E871y5-ZTOq`(wSgn7U&-SLqgeslUqpslN?8}dY1-ISrO53(i2@iM{X6k%;o zwG;q+x2tdE5v?Moo5~{-GMt0iMOxV-dj$ z?#QU-J`8{{1mg%WLr~cTFq(5k*4S=j87%(iB}c_PM!{a32`~U|yzR2BeXVT>F`u45 zS~V^vAhtGRB17`9B*#!%raSA%o$}A@OQ2qcCv|YQoWYsh2`T-I!N{<_hr%dE$rPhp zz!Ztm3P^?8nt93xi`3~lU&?mh?^@=khkP#gnHcJT8E2Vi9pVT+1D7O+ zCA5CpQ3+3d7|*HvU zU5EuJf>=Rzd-CfZdgc!v5&l*n@!=1~nO!G&qrhnHI|i2>pgdSrHho=3t6vrr}cAa5k60JhAdSo%Lo7-C9%1yVR(#LfX z%+lLhV8Pk98~#U}tUFlsbaIcH_G2V$oSm32)kcZy1-NZ+hm`bIxcPQYjasGP~{VTRot{*bI<&awP6bVQ5slw@bZ9rt<64d)p*{7blW zCoBr+kNsw{OL5?EElLj2S`VeG5H)lbx3XK3 zASfrO;A&+Oj4QS;U~o_hgQ{m`%N1zN)Xqi{TQN2j8Y3^7nDM@KfA)QZl&8G4PBc&+ z6l(bF@mjaBt9noA0KBvkgT;XnrU4_;X%DG~0%Va2I>E3BCq`zpWc!ox<=G<$f)vj zFdXU+X$^naLG9!(mFCe2&J~JDT^MBnE8>t9amb1|GA+V0NO(1qU>3n_f;j|p3BZmx zWJesbBM#XSM;3w^0V~3VPaQM%^v>q^0P08wfUh9WL6dkqOI;$=Nqv%HDDaq+I3yhJ zM%@@vuOg@@!@clBB&i|B`xQd6o~Pb6&v0k;({}zWEI4Klm>JgRWTdS|M;Ix{j{uYt zR7e^4F)d4c9m(SFt_nF@O4?qC!M zB>2n#Xa+(Q4xwZv4CV$I{*7`m3aIzSRGo(EG+7rGS1}5!80A%rA}dCzfg#G#gbUq^ z=Ie9aelyvy6kgH(RS&21%HG#U9b)AufCHu*;bf(B1TAg^&EyH#)5s&ZSbHAseR_}X zXt8&O2*UNSRf!N35!eL91X)Z&!9M%cJI>#77DjdcMmDlzlFr>`pVwod?!ZPtYU{aG z5aT;Id}E`z&fS;JJ`*xQRN01h!f>)>GmnVi5n&{7B%l*_pu?OA6*OmH8d{FcCY)LsWBt#09I@i=l@?&~#JksA z@a=11*e?8Sz^B6>V)ORfyXw2VHiJd{XjvUbSHKZNwX&7~20yg|gP&S@d#IIjieTi0 z&04jxp@>He@oICCY~kjtTG?7e-^jc&2MX~DTe51oC99TOvTC^{tCm}`YPlt=mRquF zxh1QX#`m?-MgYtHT3Ytks%5_=d!X3tZ))1&a&Z3sHM|b?uY##8s3n#u+pfWG>@cN+ zfmoJIW)Ay;uC^%sCUqbUr*6%%CAHIBEm-Wq-Z?Fqqyo5Qe6vnHzH@u$XiVXqt=PRp z!*er**l>Qf}Iz z5pfHK*{ocK8HV?m(|MAvf~5p!5G*0kIlPW9FOZ3^ zqQP!~p>8F^PE6zAE zFyDg^G#pf+7$l+?^a9K&hwcnK(uk`Dm$j%jtbdS3uNgmADF;IgO5)k0tO!+myne*?;z0^csZQ)awPLIIz@q(i?Uv}GcTjl6nMEf>t)yj zq*$s|>2kl#E%)o|J=C92iGK_#6r+0~rp|?!Iv3)gVsKSP#lp|x1geiIBfFI#C?}{O zP$?nb|?AY1V(RV6-eM-}ok;aEn;h|U8qCB$Z z)hS=92j?uh>>`wiR4#(7VP7+A5K?JFYp)0aT<{-7uL(w6Lj&D?3!1XfQXjp-J1YC0e~D zL}zwJE(1sL(8`R!<{t%KYNLQd1fohiST3Zc5rfnD>fYY^R$zvsifYCiXno zKk+&=FMn%?-NZE8$g>;Gug332Ul3y;?Xx>nw@Isb zbYtDHZ>|fqUABfxWu%-XJhp5R=8NGGc7akCZd9|fOQn@D4ahcJF&1h_9#1J%X9T1I zjYe%&N`4ya4)8iEdnxt$2>b-Dh@IDsulU`2Z^oV^?n@e>f_&@7lvAy|<}D``LfrLp z+25}MFVvZ6Kr^Cd9Hp^U(>iGEtfcEO?jJ<^wDt7$4faBp9dezGDU*-)ZP#5F9grcc zQ1iN`9q@d~rnE<-w9XW+a4VXzmE47CPqrqx0;(bnCXMqi*8wMLJF8VQ_Jp)M#A)Va zM-&xykrV!DaFqqZ;I9!e4WC5QyYBMZY%-?+n6<$f2|+CZoNY#A48d4}aRl&565#^c zL`x>2aZ-nJy5ea1U{2`n($^46vk&APda7vd5uUjxk`6h~H1~+o!p*OK*3kB@vzyYi z#~X)NWdsQVb$~OB6EucwT`Wu+tV;H3y39+qlxMGS%-v0FDYkS3!d;gHp~D3UXr`FMasv8<7Hk z^YA-mDpLU_kFYFo9Tsg#^E3r{Lguigq#-M^=!>92WEa@aHAxP!d4t~A{S()G5Y@=v zLOdN#$(q0?oV7Wxbg-rNOA(!Vx{Rfo;ufOHSFQl{;sticb?SQRA|R^VWUK%wjzIPt z24~6%FRep@f~9jG_$=(?p3`#HW{-?b8_Avconk!zCZ%W)qf3NN2Mxn^{BX|yrxbMWd)RfdBfSMpQ4jWt3czO z%82&mU+)`r4~Ut+GloadR2_2cI6ay^SzY9fY^Q!~w5b?3g9U15WIC_^cc}ZXU#h(K zVYE7bBX0S5c_coZ`Rw1)^7CG`mLG---`sI6GqoWzwXZm@;f4Q!aSq)+{YRbaDNP;l zJGy^n?nbor`V83~p}P!A;H~`vxrpFm0-Q!VLoVU_tpqy>+6dbD6#f`5kX;13 znd}~3bz&_e0(~;wXJNep)7+}nYZ}j8x3y*Cxm!1#yR~J_#x3g`w>D$X$PQg>+dp$J z+!(da1V06@MObc&(9Fx+K^Il{9m{o6?2#H>Kic2fyJsdhaqpi=4>kMU8b)k|8B7bF zoHoEWITFaR!%VOFCGkSqBy!{60M0uzS%M%v)vO8SWqisBic^W0aO!c}9&C%xi^$*8 z+kr(#nuPWvEAU#_IRLfnz7E)7_IYG{ZaTZPf@U@jws-cpl|?IStGBNQzEp?iYlUug zUy@USZrGG2dj4C0^-fx5<`x7UH#=}>s;JX-O&eA>Vy|w4z)BRW5?tGw%e5%%ItZI) z=o{$ebF5YM3PjwPHp>`N{}{J%EVO?F zE%#>3ChdS0GLO@VWLKF}VKT?$<96R-6e7q{2$mVOWt%E$^9K@5}(Tz|4Rz z7JC?oiVz-YXL2_elO)CI$y1+$p%j+(9-jJ1@!gI!u&KCnj!FD}3HgxehwG=pV~>fz zi_>3T(}}uy4xkmzlWhhOk zrW&u5`;JO-TPj6!bRVnf&xq6p{#iX<8g+*R{15S}>UNlop%B%+hj3T(jMU=)23(GA z@cSA9xERwA#Pcx?7OuxGW+h^K|9vnqONLM-kI6VDJv|Xj_>anXo=xY!TUSv-$jF3- z@ZsYx@`a-^u_1tXY8FS5kxxqP?NXJDnA8>*C5y1n>JXIGi;Hl87+|vKISD5MPlOg1 z@narAc2p*9o0cp(Dw6@9Ix2P35dV~EcwB!}rXCg?NS6#BmFd2RP>-ACTk>7A6rRiF z{p9H9zVSQ=g1@Dxjp2>=Sh&J)-Zx=(9-jv_aX_H>4@!luKzU|QhfW6j`>HVd^>@H; zQP+7mVIKBK=Qd%~q*YrnxPtzH*6xAxTDt~2^ebcsSq~2E>Fl3?eJ=}6&5TAlBu>I^ z=CT>2_ES9ha!4FQZKiZmYFd@`U?rHk{v{kkbmu&V60Rl=!qMTN+UaG9QN+hl&0i+I4*@fNo?qq1`alBdQh{%Dk+{t5LDyd7iEV?5pTFVDNp4l< z^`DP~=-Qo!LWL;Lcqz)vrAPNU^yof^9^L2Ad~lBJ2+4(6@{(6BDkLw>p{N5FaNL6i zDW`=}PK)|^Cx(nOgEGzxItx}Ar;`Fsi(E#~MX;Bkn>m4xU@sj6d*yNhcn9`MKXWo* z$slj`5nMq4&%|E2G6Dmbt1P*iQNM=Z8Uk{(mYxGRgj$O>G;Z0laa+rZ#tj@BzzO7z z4QwYgMkxfYEsZVPnpUmWR~hUDZR7-az(#bKLFzoU##kBSw>`$X?6m0L=sKQbty+5trBFhg0MVEaVBAB_1Vou^I<`EV53WC}2 zB)pNyZP^l0ddxWKV3fnars_9a~Q$Qp#HWJWXE%rz&-&y5))GsFTQMg~jJM z%5Q{fj>1jdD>?_jzT^tktoqeBT&ETM6t9~*cXzA9^IU0pm`T35pDtB-l&;!Vkb zURT7$zF#Ba;`D_OuhiZ%LSa`$VZ2vVCU!LHr<_=#!mbG`&4fYNHDOLV3`VCZDbAcu zz7{zfB2qTNpN?1U)bbvkjkoCk#8LGNCn_sJ&^TJelj;{RgGgUJT&Ny4Gx31SF#qqgxLq9nvMOCMPf z&8oLS+N)R`N`^iumA6YZrA3VcV%k$l3nxB9+zYF?hmhwaf-ppYL&<%~un#xKq-Gi= zx?0M35eTHXgWNZUa^F~!x%W%eRCCpi2UAUkF2Uo#L%xTshfq$|0sPUrrEhSB`TD6S zZ(5jVLn5!^@Eecc1pFrAH;IjvQV3uwb>ny&6b=;EUQc$LXP{4JToBXiwo{Itg5Qvs z5XNUy@tgLTz+VlW@6CW%KNAu@s&w2<%X|&~8kOtA{s#YHDXvk$J{V|VD_A%_y$0g- ztZnt&fr+}Fy$8gWA`dEM$gkJ2y!rh4i_fn5&etIL^S2mJhaqQeXma(sdF=YrA$9K? zM&H3w#6s@)S-|6%7VtQx1>E+tfXw>>GVcq>yf2UoB5>7=m53c&iP#|*ThbCDe_l%d zd?$DNEZ_n}J(=?bWX`>0&UbJDVh4}$*g+0`hg{~9(iO}31=#eRdXNV(nDiZF(szQyaG8%}8%q%!kG{>q6Trn(sVsTl~h zr{(8t4xNHQ#B6mj19brE1KReUU^(O!`RxA{Om+#>nW_~|&93#iT458s3xA zuKzyAU5VJxlv;>5sSbc!Xcm)$2CocvmSn8~bc;_T_xY^gEp&|Jq!(LcrriYwFszrz zjp%Eq&JdRB@<|I@7$*;R4lvo9EVD}S4rRe@d6(Q`W02lp%dK*oE$^1wZMj3@0a^*xnB;Giw00G`h)V2EgvFh{b51$ACZS`Y>IfqmLu}9 zJau`h;?pw3qjHqFd(4(&aY_m=h zzy()4PE)EV%c^9o>b1kmXU|@YpLJ*Jf()ABBusf?Uu#!qI|flM(5N$2qYO#rjzg}3 zp=k>D8b`AWhVG1&E+ohlS)wAY;iQM}QdC*?`mo7Rs?(iVmdGvGUbrn$rk+)cG~(@@ z{cWv%?Iz}w7?&4YN-4rh*qJIFG=M_{PLB*vJqad!sNj)V0xU%ZR;pT%WVZc%o`Rfl9t`8Gqb3fcbgm6Z(6syWlQ7M)y*6nS3xp>|7lF@@EW4-k-5bh z<2^#W9PJfjz*lUJ`=tc1T<1q>+-(%sT(`0UhjlYv#e!gYklE*=RC(|im%GSXBLNeJOP~Lk zByV>!6OL9UP&=7>d^4&clnA|7Uq}R4m5ERQT(Sl1_+Ho(tJ;GYLtWRS!BFbzhF~Ii zm(0VZyXdu;ocQPlE^q~sRG%ZxF}{W%#0p3hQyBo!g2lBOtb}!!TvR`e%TnVPhv~14 z`3*pFIVKbCkvWuE@Y%#^Se%-~H7mY3mZA$IK-TN-64nIP*g~iem1$IbC~%($`VUDY z5kgh?9txzS8lJIYsB;d~`P2qaN=Y^KTw{e)LwTcI6YapNZILPARGCmI3lR%d5_5a zbLyWuqYCdHk%(_;b=4u6h~8JNsW#MC&-Oy-&LrA=(CayT{D-Dz>BaY->0q)#$BhMr?V({imnRs@|C?N*fy*+!3|Ar(Tvg2OxfV%mJ;hy*zWLivI5-LwzhUbsTq4cYQ+T{#Xl({VdUhu-A^C5SD|vMl z!PNw>A-IO%T7v5cAn(6cUPthH-X7!?W&V)7A%fz*F#?mbH}lC`xWM?<2(E6VHRerx z@ofZeCwK?JJE<$epYH{8q3Vk_anrx>+9Mhp3p>%CV4q+>%dN@_3;>IDDna$=N-uBV<^@ zkttU6WYW%_!G6_8sDuqhyB7}Q(t#<%tN*ujFvA$TPETF)Dve~2wo-Z@TP~Cx5NTAh z7;`q1KWP!+Bx|m=Y!|r4Zl^*+PZYdJF1B%49KcS3Hl8vF_eE59oM*{XwmdD**z!pN zSQXgv2Km%!YJl41)0TY3me10h_E~w(me0xOX;=#b+Aqi#ZTXUX*_N-!S8e&4e4XGM zw)`LYrVYcUZ`<-6`L-qBwdH&AeM^2|%May8w)|LrV#`knekT86%g>qJU&t?Q`IS6x z%M0>rTmDmiW6N*(Kz+{qPX6lz8ljAe$ClsAi>$0aSn}Vt{89ci;z`+t5!zpD`72BC zH-f(t{Da`11TV4R|B^p3wU=!^Cog1Xrz=i45SP}ynhlt(N)4twGEf2ZE5!`OKI zTl7xN3SY4GjkK_&s% zNUI|3l?{7`tMPGlRH|^sMnoRA>;{<%ORKG*wNjOmtF6-yx~VRLp3v1coraD~qr0LH z?z1yWxgk0-s_0Ix5qq_DSXphG@@O4G)9d;+CjNqp-lw#}emX1q!(W~M_sDWXb$WR! zz!RzXpoiNG29k@Dqd1@9s*+MBbX+Uk zxEdhFL{dt+h^vWN-&X7Q+F&R4y|`^A$s0gQca<1Lag%T2q&BHFXInV^W&Bij<}f~_o%PxTuog# zOH+4!nbdTa$!Kbz!q@Lb4W<4H7Kzf0yPg9*mOhp?dKyW92Z5~vhm zRU2+c2B^%NOpRa|8o@fgiJx^3P9VXDi-XYNkwl=_`*P~p`-K+z%nJzsc?se_OdKZi zT_%9Lb}B9L5SRK6KnQOfmN!s6I9b($2@ASFRRii(Y37OVp@bS=9MY6fHN}kNsRXK| zxE_~C8%0i)&c`B8tWQ`-b7&mdW#p%BDbaL{DdI+g+o?4D0G?(l?;L1EX@kF*BoRzT ze8~vPIKw;~OP#3asLZ5JbQVk)^xer!y$%KsnOx-DWD1P#!4A?Td);2o!w0EwmQB`;tbc0BC_FkMMK}?A)FG+E$ch88k+n^DST#GPx=po&o{{}MGf;YD zE0Uz`3ROP%%d<6q{MtV@Md9rQzh!uO>bgJ`3Sp6x_I`cMcU9r z&GKb-aQOdY?@IvVD9)^_Ml;hrqt-RjNR}+w@@?z#iELzSEZZ{3mSowIZDc|uSsK{_ zUFa~FfN>HNawm|4#3liU5DbJQV8BPX3?z{IBw=%G&dny9Y?3{4U;f{#>YnKtjjRJ_ zll}i+_EdLQU)9xB)m5+F_r9oFhi2eRg;8UWT=5UUTz_RKO%z-~?rB^lT8Ab;sc8|r ziJ&}giIZGw6YYkkk`NFiheQ)dY&fNtmd4MD=PdC&cYIQON+BVJ__QTHBR*@>Ts|j0 zZ^T0(Ulm`o#7pAqmiPwOUgp|AiEr}wCQB$NrEbMv=EK}LhH6Cq)bHzrOp#vKfN^C|>^gE$=d_*;1 z;|>S~WT5^2TtLEF9ki zav7kdNP{iBo`v%gh;}ie#o2lbyvK4WNvLn2_QdEtY^!G*|*( zTYyV;qnA~{4+NI5dyK*)8WzFF7V)Gl;fsW@6I-11Wsg56jWqa?eND7NTUOH=hf5jRNIUCLPY_{%T4EfN50HqI4*LQ>7l9KP+rkzh z^N4s6x5_#zLik@5WHj!A=*{`T7ln}mg98joD^oF2O+6{HtE~Ls3nDw;dO@UfylSO{ z;anxBjL8N0iOXD=F>pBzrVqzO7h@_@Q!1@+s;{Rq4cAG72}D&okEqNDTa}sN%y8O0 zqBK7}oS7dCXB^Iu%d^C}gYNZA^ZG;Y+Ict=Y?PPE_yl2fnY^;FrS9?>Tn*1K9sk|W z(C5DSKIi7yqi?>1H@m1Zi)p}J!dXnfZOzfmP~pK$^Tyknk+$RKzLYElmnF-tf=OrB zb0|YaVc#)u+#VA%!p7YSolpQ+P6@T+4L>lJnJ8e#b$MeHcvlKn(1nm>t|En0kS^!Y z#B>I!mrP-V+{ysU!>mlRr!p80go8bmsaP2M!gxs*UJ~*(yDBYgaZft0lh4zpg;Vp> zQo`w{#q7#-CmYhk!F_z^04DPJ;^)vN1j~7#a&ftU;saPNqE!c$_+Q2)*m4z6AK;%C z_+5{#0vIEDQ3-??!6A$5pAbu6_p!7AwU7wi)0I9@%wVtWyGLwcxzoggPB1MIaDjiVS|Dk zYPPrd6$oJ{5W*w~(UOU%dMpsP6$?ae!veA)YXDF*ofgd}MAOr&eFgiF17L`0Jfhw= zecu{nwUZKkL+=>Tme z{jtteF3{lni&Cza@W?d`)-t%1yVo(OX0V=)fi^JM$e@P7rXWnqE;qz%Zq#yPGlMNW zzK(JAhG;OvR`e%&MuwYdE(>o{%5zgRq7L1YBwn0sV@U1SV2I>(Tazp9`>zd2$57;& zoZ&ZgxVv={aW`AcYie>_aZClc2^n|%jQj1VtKLPwE{zr^PF!QaCT^wIkCfN7U+37k zSisJ9SYoHx1yCc_2Y2SPmcXoG@z6-0tw+^i=i%a}?jCm4sDy^@EHz20JKLd!HOL!Z zL23ks?rIo1S6pSGm$99`Zf4Wn8-h~0n^7Eyb`l}f=(p1Xh}dOe4rQN(Pd^5*S2I8h zXtCXy;9PxTS%ynnK0)`M-sls=Y%!E#+J^H>YlVj#|FiQZCCS7FusEMuVWHbPSq}|eK@x}$}Ay)5J9rENR81a2l zJx_gJYw+CYgS(mdNd7;f5Z6>joa~o7<3FxDL%W1&$q8swK$e^KA3C3+rVx(cmu*B5 zr#7L1g4GmgLyee;23DYzEMV=xS^=vHmh6YeoC02|w&5HwP9h7uXqpi~BFk3-Y~8UH z_UkyKB!u~zfCG~+fN`hxFj%hUK84`i7J9VPcy1~uKCG6K6kIS37gRHH`qS^FGb;Pk zO7z(|%Ak>QCa#f%>u2d}cv$W2YqX*_18H8-gpX^M1fEz~f_5GKCXW?1?Qa4;zOK-EFT7qFZJj zHYL&>4lZwwZe?@pZ~!U)LJ6m~io(>%DultZ-3c@y{^?{}5t7WmEacgf=A$CpUMBb7 ze6sKjY5xjJK7W($3#dVEBw@~ja|;y|A1xOUA1$Z&Xt~&8h&mIBqmB_QdFl<^u@wfs zQOKVW+aS=xB`kf*Y3W-|OW$%@`j*qux15TjJ}Qp-DAQ9;FMs9q@>foCUmw+Yd=wt_ zi8hqKLo9^n&e30MJA*w8I)a?f=UNxn_Hu0>*R=X*ImLN8Y4ux9ah`I~XNZ1707x+C z&aSr`?(ifqj)21a*LSz0xg*-|o&(UvT@zBe=^5JNG%A7K*m_udmfPB;z9=!EAlHf4 z4M}W=34a}Z_3cB~jMcr#hIi`@eEOU=NT-noc1S$DJt*Z+paM!`kVa-eT>j1~H&g2l z(ctzHdbC@jL`7*_yKDkoq9_W!+LjiL_L7DLUUA+)M{n_Pe{t_fIeOH^c7CxhGa~lW zGv6{g$3sxXppwB-2G@z}Epb5HV2RgIt#lRRZWK3J;vje2%-|3M(7-7?ir}zffRp+O z#nFwThO(nLKq>OTG}xZ4c&m6D1xT?2dVWf0XR^H?yY^1F_jBH!z~83}l&r&&ylXRN zPi697^5od+SP0(Vp(n(oj62KV?%DiJ!1}oE(ktxz@Iy={mWQ<(YaZ4uwM4yBORX2` zVZ~G1sETTd`lgm>1Jn|=6HBVDXyr~?V8WJBeKX&#I!%BqJ=9i7De=;=lkt@BvCrdc z2>}v-ahVbl4Jd7uXq=DYqKJdGiW8>=M-k_D#o5QP+l0Q9b6us`;v7#u%At(MMW*hA zX#E%|n9lilZt^Ay*k8)bgi+&kU(Y4j@Ep;r(={YSt(j^(5zdi!;#u)&m+vUVaiKPL zJBkY1?vby}BmpSv7|asG0dy^v11D5WCtT|qMN7&)7~6wGvk$g;Z=eNXJ)(Iua6YVI zPfpwNgKd@O;eZDlIK3=(`sm|gSHkh?z;N5U2us~5Qqgs*G>(hZuz$D`%q9b!JQzay zZ>aRs*~np^4Er;S?-AKyBXi(T=FG4^<%Z5f$HgOvUZnorXKmU19-yGX-Z-*wxK_ zTp45*0JA0^t3btgm6|L1?d;Kd?}p%zU6wLgWt7*-5SUdZP$>fP`nU+;xFYW{NVTGF zg&Cbq2sSi>TOlB_*}Qf>9#gr@#F5%w6&2CxiEjeRqx0!T6lh|c02NP);%HBNmfaJd zt$N~fs5g}2=nVlFoQs3!LEwgqQy}0`U1-5su@L`3lPe4RfU!bRD4(75lCT%bK&M2h z>T4H-eL!c+?2dKTpa-rzcuSr*UKmZD6pIqkoftNvu|?Oh zaXulHz9i<}bUI?)P4p|rMK>_Wb^N`dcg^QRh;~f1fyivMf%N2-C62MR#>)mwol+7) zVe{!ClklQueR}p2FJLUdU-`H%YJ)A9I~336BK&BG3cioU0V-B=Z5e~*hFD=xzuv3{ zuGYG}xp554CSGsT6qV>?Ubb@CG9aWlnQJ`R6sr(lTep6LDK17l*K~Xp;+x=y)ueBG zlWRI2X1Bhk#+sTdOmPW@CTdmhS%Wh!Usee$b}i1}nvTB|XJBhNZnh3*s8zkE8U?7i zrmm*(@~sUutu;Gq8laU5J&J%zM*Y@}0HpYCQ+GljbSq^-n*p*~dh7C<+RH9)PF_xN z|CmKpi72&QS;IZG>g6sJ3+T^!ffNhQUr?j3Cn*}KUcutQVGP*3dy%2ID;IW5ch4R$ zUQ8}@jLJm4>QmF>cu=*pPuPbX!wFpI7?oA!OE10{? z*Y+H2&vk9j!@71~oez*{0qS8sUpSWJi=spzEW?%?jIrl@O;lTF_i`M@zXh2y9u*!; zs2mZYEV&LW(Jb*Fj|v|?E?KgTo3a?2NgD(?|Jl!{dm(O&-)dYd_L`E(@;I~kD0yAo zdu`Q~Q6~6v*c61>M&t&O?|D!QWE-9jZ4g5g8Da+Bx+A%L(KwRZN$==3u3t5tiFWcU za8z%LXk*OZJJ3D|+DNrMYlTAz0N(B_)VpFe2?3ZkRxT#+ zpvocYxKgo6Urcfxfh3bHIcokT;qk})wkN$Os4ojy9^wpU?{Jre3DLyWCldw3Mo>f|mpa;;#lk4aHy5w@14WzY^#L#E7Xw5yr+ zb@Fipx(VpOqATt#!|$Z<>5)|mnkF_@+K(tD%mo@qO)Dot>|7wl;<-)Nb;Bh~efz*%l;OEoLlUlgu3d)b zI;vxHRi)PYtDY-S_o5$Yr))Ta`zS#1y86>&()y~-V1B}`GX=33!iN5)k&bkiTB?xUKsUYL@a>u9%%%sIClNOJv=&nrigVHxbo5e+(9-hcK z?3q>X*jS4>>G=~q!RQ|ZcZ|YSdJfK~`c|36c;y`W$V`5;Spo3E&{#PYU?Ykxzl;k{ z3;FbuLG^9q=kcWQdbdIVXv+zHEkObD`qbtlD9HhSs4(!HhBq@`4M07p3Z#`#Xd@p# znoJnn$~5E4_T}J1yok>=f8!5+lIDAS|Jt*F(hk23is!`d4DtIQxXXVGAm&eo_%lDG zf8oYo4FNnqAby7p4hd4EWZ+?tVoI-n-EaPYR5RTv(q~G)DGgJarVK=<8B7`UuZtQE zd}*CJ+?1(NH)y7`OqpiNbW>)SGSiekhFq6%LuerL*gSjzbf@aR{{h1|U;C`)8%bf(0R zWu`1QWrZmhBS+*CJ{LwFDH0=(6uI1xD}rK+yok}23|6MfRr2DXtdgq@c}c3+CPA@C zk)T*yDKAZx>tr?K)|+wzmm8VZ8b)t2Q|>n9m8N`^DX(I}UY#miWgAo6ZpuBT#H`C7WM@!D zWEX?IhTNAb4#;i>SMwIv7_!Hdy{3dSgg?mspd66bG8kkq#3P1-azyUu+I5D!-jr~F z@CSKAP`*aO!X!oB!~@$HTx`mNjJ}z{AydAVIs7_i2~<{|mxqJ$7WoEd%B=y!y^$IA zCI)XdBrIo^%D3_ryp6}doq6;QX3v{U`A$>bX3E=5`7Tqw+m!DyM=z?65H@@`WeGvxSS&*iwBN zHSt0boA?^*n_&=?w9keFySsXqB|T^=9lLBN4UL15uE-#^*kWh6u8*%G?p_%mbBW$` z>rT01YC(}k_OE8oF)vDcQ0x$=X-l|CQ-lr)*ST(jn5jHZ>~=f5J0tzB+a)J5O((Mm zj(`CD=>B?KK1|bCe3L_2ab0euyYDylXVBKkU91Y9e#(7QJ98?z5eB5>q&fCrcq#4y zMpQS9{aZ5C8wb1lp$~8XJ>~NzHOXK{&4iL??p#BU0&!i;vp8{5ESv0gIV#E-jO+yo z9Ug^7hKBol6-5WdC^tTu2wMAI7UD2&SsnERVOKT8Uvb`>M>{a9&);cD^6>hW$qGw> zJ$xMfE|8x8i4i3yr$^s>O9bzD!+EnK$zy8e=Qz!|{~hBZSC`$E&w)VC)P{qGe9V%M z%ah7BZi=1sr4R^`&~*Na_$ur*Vnfx-+lM$5u{DLhM-8E$Gx!-3tMEyx2>lDb2m~T+ zbj`cDvF0+pd#V0HVGN+)PxPs6tj^oGp?(Kqu>fxA?FLecUh`#5_1M_Bvlh@Dzii9V z{3k$jhCFS_Gx8HCERblfU{Wg}(OiL29hGRV;P|(~87yHJpzjK&$i-nnhJ3=3Ps*nZ z`LrdUk!KD0tR6jzrEZxl`GS1WlAo5JvE*mv=aA%~&H+n)UVg!nUzA@$ zYZeGh;W`b~gGm z;_^H*Z4F+VlY1KPcP#y^2hRD z4fzvG{#5>(C4VNrhVIT{Oa7dB@bB^$mi(psm6IaX39vu;mi!O-pUw{T&0}dsQVofV z{;3geKrvfzCie4gRc4^tqFE-YD`Ui&w+B+f@n^DlVU$(xvzh%cxOa4~= z4mE8uC!*LnE`C{7$G;(N)&%MgdyeH}pRk`uc11(`aQFU*P4Na6%j3KE^d@;C*Ws!{ z@bWW~9j+A3EA|fcR^WrlhmT%8-L=))i;srd9le^`ZEvaFX$h&zjN5h}61|3fi2EwR z*tD1w^H`ULx+>sIH|`mkvZnr#zE1T)R_bVm{5|XE_bmAb`8f-L9;`Sb@ zf*&Y$KHHH_Oa4**$&i1xHSZhj zzm5!cII7}3hDMY?XV*wikNZZ*cJ6K1+N_QkiXsyVX_KXKZNi>+2r|<*B!~dze+ev1ep&Ey!kl=#&gv zo-AHJWO=eZIh2n>>lLc*r12Zt2GwyXF0LxJJYi3+<;mlH=5M!qJv^o_avfTW{^5R9 z64h*UUtipVJ`qllU-nExtw&Sf$@df(p6QmSP{IQG`{Dv_5V=>eHHNxb4y! zpoh*0p6Y6_CRkGJl)7K}vWeWUcVIcQCHj05dUc%CoWdKAo)*2^Bzr`56OT#OxL5g# zt`bel;)!GzKQGZDG~qL%_n1)b>U+40_=MghPjjC%p?eK=_gpiDHyJ%G`ef9!K2PD+ zy%T=R2PW5^xlf!#^-VY}n#^%B#eJGPFUP66(bHBWJlr^~uIoJavrX!(=%Y>iEccU@ zP2{~bUFUS{W{h?C)xBMj>p?@nAZB7?9Or~!tY;KAd~s~P#_?;c9v@%#xIxlf4Bx^? zsXfo)!Y(oH!(d+Hm>>eUksRCi^O%_DE0_nL6HAK&cES6Mo&>7v-m{rgW*CVfWpR(u zq$kLslmhX_(U<6Oa|9MAI}@lN3w*+K)A;9UK0dry4#3OFfd)8N99n;X5ExAo=D9P? zhQD^(u!hcQ^r>*?QSt{SR5PI-(T@(iBT1r>y;?gSCn+(L_*hH|?Q0)uP^AmAR4|C} z_Nk4WI7v%;USGdpohPc_tZy$h% zVdzLCQ*0Q0hCP}`)|$ipPPWA7TY$j6Nxo-G^7*XJST%0EhkU@bb(9uRS);SvIa?nsGhz~ZYIGR$-Q_JW&7PFja2!p2^X&Shnmyv zG|)+_GYXSmzeMJ`Qvy^I8?6Yaa<2F4dL3z;c2Q`9E^5yEcO_u8nx9#C-WJ3DWY+@D z#S7^k+T7cvA&9{P8@q>CH0t`>Q9Aq@<3KTqkgft>*m2cBqZu~tfu~_Tu#pS>8P-BQr%d&;&^_F}g~2O?_i? zOKW}2#@g!EsHWm8kygq^CXl4q++Vx5uYWMIp?wH-Dn?!OE!?<~?G=r(Tpt6~XV9^_ zNH@0A88vz|_)KIuJrtGWoC^j6HwCN{niz%XBLQm#bd!LI@Xuo116FFjfIeV!`wQ3) zmkH`PAYNF8IOl==UsK1wgl)J_h;F}(YXJ3*Zhs5g0Ki?_WS?Q`2H|&cg_z7VXlx}= ziajmJZHEGizXi;9YUyG<0DTwwe?yFgUmAYtn(gX=2%&u~c@DH5*e=VT!>%YtWM+Bm zPKi)SC>!gra==;+V^dD5^{`qmR_nQ-24#7kRqOfisgvb7>#P@Md7e@0GoYZH<$20k zNBom&eU>`+&1!wNTE9ZA&*8fKwOXI6)}K@BxDMjm)cQQN4)?`K8`fdc{YSMvpYh@j zwT|>G(5c5-o?crNT`R#FjLSoi4W``guS!E@DQ84^3fznWhORF=BNj_>M7)fZB@*H_ zOB+g|X9IPcDsOptW(7Qkc_Bo+qRN-=3tevG8R=TW2|Rf`XoV#f*GkN*L~?FRh|W>!7;DX|e8N z7*$#MzA8w~RC9fW(lmxCnZC(J=O&>Vu7QkrNobS4XFe`=+3|DBOY)6r@EL~(K7MXK z3c=-%2q~|TAC~vSyokjYvo3bQ%EJ~pVyQH7t7Wj+DKS7*v6H2*4z+abtCXK(oi^@5PgFX#JS zfF!|VcoHiAG=-7l&1b}p6tPP`kQ6_LI}%-;=AsIK=q;v|o)KtS8%oNtf=d>%EUEm$ zP8|D_=o!_>0-kY^eFjRB^FsL6A;5G=Xcq$PzCuETltrLWrJw~4j(9a(4vtXl1eD@( zWY)}735Fa}(;2awvPoCgmuamq3In`KvrIjl7S$(uRwCsVULjPYy?s|`k6v`>MWw2wl_EVupH} zAaxY#MQDWj5SpR>CaOiT=s&Hj@SsHQhtx7ktg)=hv@?OvPZ2aewz?NI4De1u18U=h zxHj?pAKB;Un=ev;>x-rN<{2^QK_y&*EI}O_IwH<+&B^6q=MJF}eVdbF|8a4Lca5wH z=0mLfx|8Div*JKiYQCADdPdxUK2xeZBVOa7%flNh1E^C~&`t~Fr&d9w%YB>e$!~Me zb(_V}G|fwX@Xh*QR=`8*(F^sv;bXr5#fnNl^5AJN)Xl@jonjR>RPN=QFNk^hKIYtO zX^QE&8(Ld%UwBfyZWkH{#=qWM=|60oJAUpnVLz0w@_l%m!-eo_e_GrEWvu7~QE`iIEpP?2GAG5IjJp%OyNs>Q*AicJXdd*UWswi9zeg7z&D*INNDM zFy(EhwgQ>K?3iuWEuBcbhEXk;dQwQa!}XGVF1jA7;WA1}@j;gQ;wHQ+Ic4its+knx zN13y9Q*(?>%?H`k+{32kLu_j9WmEHE)zsXlnwsOPskt9vAoKvjVCX@FsiBV`v_cOd zObdM!VYYba|&yD9* zi#*yS(S+0#CY9D;Jm420Lu4B?BTN|>9t0Hv%Cb>9p{-$TlmGo3=kORn1Dh=re3+Qd zj*XLRG2GtU-cvoeccd3KZ_$}!9+|6bQ&IXS^7wY*<4`L-xKX!8m2!qkZh%gyBWYt% zU?|FdjIb*|re_v;p$FKF96D!1q!8D&zU@ znY%w6{w3Z$e=8^Ve)O0m;VnTcKY$MCGl$4s4~W$;i`OQFq7uyKisOX@c-;9E#|w#iQ#5e7l|h{$8j;fgzQGjTiE$AS zmmReL!dMXE*}=A7Nw%#9-qH54CCRK#xH0UAGgQs3WG`;DNR6fG(40LiEQj`hiwiConxdH z80dJwFh%qhGFYTv3+w&lDjHAT7L(iqgJ}}AROhP&r%O$?JYbn9x1iIp*bqCZhXX1g zL^&vh1JmZQ=xj^^Wd2r(i2kBkz^mDq;0JYWH$=VJ#CU`N3ynI3ezmBzdIF3P=F>RR?&s_v-M2J@N zcn^F)>7=JI$%sM!l{@g%_P`sRLVTF?wd!#{UaOkd$~q!e>2u3?F2yno4n@lKlA^^1 z*PX{-b6fB+?j#dc*1mL!{U|e@5Fx-K*?6KHh~$N!W*z30pke~~W8H~PFpvE4 z_doN+KjRJZw*sk~Nc*!MP6M@EV#44bP!;5 zl`SfQ)Dq&R)~q$fa&Eww3PKM2Kvo)Jr9mMEv!i{Wy+hd!@Pp><0#Oy;HZ;+G=$r0U zJ{FU8q0~3a{>-`6mh_j!-#xTRT?m`FlmT#9Z`+dj6vWrclNPExnnx&m7^2D+H-nwN z67{geH1@_^CYP8j*xFT(Nt3|?%H;BVZSNYf))1H43Sy9=!SqKltVZ`0J5P)@c)i$Y zK_CVaW7EYZHrIvY`uWhE+1PtZ+E(gbzzWa|7OSo#xYvsbc#rgTcW^d(as0%e?j~>A z)H@Kt>`kD3e`{}h59aXjKG1fe%QCK0#nCf6N-2!DiRk&A_i3RRsAY9p$mESc^|q`=yl zidG6p#v0wjdD$5TvSqY9Axu=>0GnU5zG!bl5SyozI+Rt?p`VQw$o3wHPcl9``cCdf z(C;)2#rO)1-tBXC&&J0|@1B8FGMyo&k&y=s>8kw9^?kL7@i$NG7!?IR$e zH7UONZ7F}jG5oE?p%ZCMHqp+u`vy({*~5=fvJQm-WM>8?B{S)hU5}e`G1kD0@m#tv z)vZxue?KOd*18xW@g-O@YixyKhw!>MR!ew3CPSm$ofzKzrRu*urkKHLsO z)gIaFB=nDdb5v!%g2v& zds6p&WIsl^{9S_GV?CogZ%4nygwJ(b5Pi-CLEIHz>O8S1h@gaVrCclH8ot)(u+h2P zQiHnkK~ZAxGmVi2BQG)pES@tcE|1;_*QzjV7MC!wyu-8gWl7ezIO45fuMx<>uO7g0kvN=t=ej>VCL1;7CEqL9?LpxcAES}_NxfraKB zay45lfU5PA8&bZ4_QFC_-(ZQYge9gj5QU7r5gm&{s@`x(%4RNOx z$596QK`e<$dss<5kc}(#c_BVK?9B3WlK|K`M1_eBx+^B~j$$pi8^;`t<7fh7+_)Zi z(skXP?7b_PYG0&#?>=Bw>9PFo>Lw}BT)25NTyK$NaKRh*S!n6lKy$`}BYU>S9NiZo zoPjM$(QuTQRsu;6G6B$Svm0+OD=ALnVOQWZ150XwrW_Ts(24V|n|WIJ*3Y728?$8A zN#Vz~!M2<&L_PU( zjNhw#n8`(F(>@@u(!}621G9bTkY-k;=K3)r&*DZXKNWhU402A3@UC2w4;d)W#q3$G z({Xf^OPG#P-!m0w2PIfeq@*d5d;&uMz~|q8(@wlU{wDfe)Yowv4<&pTKVXU)Lu@h$ z<$4I^mI~;oFA|%5=j=ajK>@Ii%le>b5L>y{7^Ei;G=cmOLa}cLmq=NL*kw{QJ%gg@ z+vt&Xk+_m)y~?0udIKfX8z`B+NZ^yaO|+YoNzb56`Zm!Sq{9vF+smW&G3aJ+HG^vy zKqwuqH=vQuFM3k36%GndoVg2JFywwM8mwE!w|n zTX!@!?r3hUZP>82zOk;Rxu$jfj!jU$;AfpDOIL?lchKxEF|^!40VS8n-`T$v)ZK({ zJX+qVyI2hjw0COK9xhKkb@mT^@PR^3W&+}C_hH$*xWt!2m%}Eb6#iG-MgcS2WV9~r zOe78ojTuiD+TOn(S@=AOf5&|vhYRa3YBuXA+EFF$@hRoSk2HfZ0S=bsPw!A;^IgPVaf7Pt3xQaF9MyKjV+e+p_C zb;2R>T1&i6yq?elIxL69EodFDTyKdth+8f3Mh0&ZZ??o+1kyRX=KA5mc0k7J3t7BR zc@v}+;Sgq`icumO*6{9cwZz-R>kaXCC6sOh9=D0xE%7e#ZcDs}7rldO@)K#n(^f(pv_fd(NCj7jLT=w3}cP-Gv11_OEEIE%r??M9JHYgX8*w7sO4f^Gx>?W~|n8<6zi&PKVgnXX*eOs@pr5VSC#_aPFymKz7} zvZqSGxMGAa77=uO7JQh$wPB@C-a8oo)i_z*83UzP`5D zjoQMgZTV?oQ{B&p`=zwOT_bO%LOS9Ima%rXM`Lne!k^AyiWE>QcDX9@l>GnF4U#OW6QwvpoJ(BJgATv zewUJ1pH^S?tjIqie7=WDahEyvrA??NJ7p_Zl`J4Q*<#UYQSzur(^pOaNDI>YURnkv zKmNvd_M@Ra{e6qsK_>K8q0+Zm^aX$%^fMS>a4myD1^`QjO)<1ZqgfS2K4&iO` zFWP-)^hX(djKRlw?}vHENBH#UNS`poqp%Gc-vL~FUm3w0}4y&msi+hDuQm1qQ$t`5TCci z7sMAW(JuB_u;ci$lCH8~#qpBTs*0Oh-9Cb$ORu{hK6^v|NKa=m)lp!g*N4FkI`hR! zGqJUHV=D)7mUvlw)q*o?V311p=v!L+=sO0LkiILvX9>!gh#!g{+2fpl5kI!TL;nf& zk6yGuAxH2t@pD@f>6Zc`MU$b^SzxUq0WIP)S_TQ^POSZ!H~EeDt?fMXcLMd>Wt1F0 z2cjO!<|rn94^WthehzglhKPL_6sBM?VPuAIOd(uJW7&N&YC*_!k>1;*SV#URPLC^SyoxK`9kA9l)xxvS2 zw!PPmZbie|dR_nEHSL4cb!vqXD6-wRaI?Z@Eay_pZWXPvC^Y|02rB)KrorN-znVAL3$G8upR!NLWb(Udn0xAzWc?#QN|c9sZ} zx6-Q)HC5qu7+cn&qsE!n0dP%F?c_Uyz`T(|&!znDH!tfyleqnpBAdRe3&17wraLalq9 zVGq1J+m|BinosYU^D%@R{^Emd@7spaI3}J&P3c)-&@)y}L-~t>{><<+oKJXB_~gT! zHOQ&*!ZxhD%8UG%!8}TB$@kJkV`elPG!0F{Gkm9g`3x*ME>8&+J3AxMdlNBWy5^O_ z+Tw(m^)P62#u1TTin|9-i`g#1ce1<0?y&bRu>&!_qGO6O!Rv9p8#ryK*8LGfOE-t34+lx<%DkNUL=V!(0BbfK` zofR~}!%i|wK?KaPA*{qW>Z=jY${KR4add2vRqgyZNQ~A0=h7> zBz(KpAzu_*oF0v5k~O)B3`_%aT9?`UN)rVAW{BGZXvE&-t^N-(J_6$1-18m=cQAM_0}P0}I3PaCvG7sxenVhZ3WMPs4u*5Y zF$N!m^E)1k!SKBt2S>zxhB$7D`-7O5e83bB2GCS|guz3+21dL`IpRIa5${p)u=mpZ zBN%NT6_0?M@>8Vbs5rskQ3j7Oc$~q>6jr|!RY5bc#<)`qPBS>e;1djS^eF}}FnE!{r}?~};WK=e!RHu!KFE;)gD)}oGTEVD z;f}9z^J@%VGKg(_L42Lp_y&WQ8T?Zamfhdtj&C#g4ugMY@LdMqW2S$f!4DYRZHONR zXc^1k$3bM*zcTt5v-l?r9x%jD4e@Un+Bm~|Wr5MUy}G$Z&t1pk07Q@AX=qF^V647# zMyrf+iXPN*LIk=<~3t$=JvcdN2;*JR`P+_R4 z8}b=-)c;X?@qJH9(s6Kte^fZ&?}Y_qpd+K_Af29*3ms7Yh_4kG1P?J779*C}FZR(} zF*dIkAVtK@@;H|$bWi+ubS_-_t9 ze`AT?3JBj$YC`k(;t!ViqxciODgQY(oVOc8HI6mJUo7!gaZb%TPHNmat)ahI4KW=d z;~_Y5>llWPE8J7yV~~&i8Xy~W0H&DtS<=HGMS3milYUDY(zIkiLTWWtT9!=XW;%lm z#$|FXi$RD%HiH}nVFtMj@)*Fc$kt2!k`cja6NvDELkKD zS#kzbIg_a@ma{B5Th8Hp>kXEiE9Y5qzFc6*g?Lpw9*#&XGy>(8tbkOq_^X6VZBE0= zrE-}im&+BFyohU+a-~JDBbM!T#FA^|T1#Fk*IBY!uD9d{1{-PVQW z@sBfD33x@S3%-E;TJlj&!dU2ka_Bz+EF&p8@Cr?@{;uFc9OUAfLwB%jzcY}Hj*%4# zfp6C&P>6zr0Wun8fa=$`cF{c2K_Bvx9KA2t(D%dD=ACD6>u^6L!nI;mvYQe3Y~7>8cV;BHOz$4TGu^b-91R$N zgs;KYZg^7Uh_gXqalqefBo1mxHWG(8e@T`sr->;>{3gMsK#PQXy}yxxnK%@j4b&{B9%;;B8gp7gVPGJ+OemIlr^K`-2lcuc#9jUTF-R=m z+4o0o`v{ilFB1DIY6;CaC1yT@hzutJN@O|$Pf-U@Dz_di;8|-C%&zoig8w^br4Lxy zT)rbhRe;vGETS9~ku^_f0eBXnMU@6l&U*_nA6U*BnKLTsv)&UnK$p-fVbj~$1JsRM z-Y|eV!cV*)&22rPd7Ks%TnjCBR+cy`OYN0Ryp&};2AVy~xy*zD8AWK|A_1pgq@v)R zu~J7t`DG>7a&h>o_lt7ofFplIgsTV=Iia;!2?MZO6S@>@C&fCIA$Y!h{(Zh4B5b$> zE>O)9d0MOou*jX2wDnQtBpkRU958xrIW0CYs;J1q(zi*6EIMMikATnyIcW_wTK}`xH%fLMHwome^}%&2Vp~4 zcNAPHC`Z-r!WA089&(?6L;Q%|dR8>zKi0M}d8Y-{nv5)2_CbYT6EJOJHG#ErxTFQU zylt$5crd)FCM;PDh-DIML{xL77s=d8nD|-INEW(J-+^LdPgBGUV-`P9V}umhfduH0q6vTqs^d7ARSROV(E7BEv56%ihZO$Jy&DHHjIZi9e7V4Df1aexC6gl00=a~=v7kF^|O%6GYQK{pRQ^IU(MQ1>)5fOuA z_Y}RcmofVc(QSyUO>*5$(Zi@-2B18xA?4i^111Sih8W}qh)SlSJaIR;Mc0YzgIELO zX^prc7407wPiw_Z3=SHkIvpa*>5zC`5Y`{B=gEfySOdjrIw?-KiZ?QNlOf*B2xcZPPdZjbSs%oYs7mP+`#~Br(22Z-b!5eRuY{Ig1c)- zbXp@mzyJX6tps@25PkfhxQ93TkRk3h#D}MVCuY`HU(woF-BP!;dSh!-?e3Z}z)H3> z6CgW*8FTFjx>ON|{~u6um5tX>d?izl#WlZJ>zun?OX>ml;^^*6u3S$yjsXs8>?y!F z`J*_((myJ&Xo&mJ!?x%2Um0&`G*&oO{t_%7I3-Y!JsSalcq+i3h}k zmiP#Rhr~w{=|-0LnE1FQ9u|*~E_4C~jg+3!;#gB+X$#XwE%6v>Qi^c}u9Qu2!V~S} zW3`B_$)PUs2}?X7)?4C91`XmVOFT`g)-&8ZE7lw0Sqs9n&s*Y?;!`$1=ml=R$N-Ed zMQ*ah=fxN3r3!(~VFHoqt32dujC)CZ-4fprFOz|U)L?Rg?$_XD?VrVWnQ(BBc8e=* z5)>w7ZA#Kr;?%U5ifK*?fs1946m!O82)U11=mwXkX8&*jV7CcCVdLS2|JOlf zaZuza2NGz5BJH5%{0&EhXy|OlNfecfYXhQ~0*0%OwE`M(G%%AI?%P7u{_*6>U-_UL z18~=%+a_QoGptB%QSmpxX#Pjwm;|svGqo-x9CALl5*W=u@CJQNKi~rB0$?p)RD*jD z7ob@8fKOilrJGIB?QF#1gM@t{etZy50+0vvACG`#Jk~A5k^Cb;{Si2yW+XzaQm_FA zDIWBNQ(%Ds3WSei_!xP|YzYOR-3@?12{Bt7#M_*G4?iOI6_;S7?8O!5V&Gu18=l_a zwb2G#A%i{aOvGl9;N$e}NjlQ$i4Ehkot-Y!>*wyM`yrG8ix%&KB z{F>q6`LLx}@?oi^ns*eu9}Kz9h-qLfs|POO^g?9Sp+n3mwJ-KI2>bvIak3p> zQk{NGe_%v*Qm!pkDnR_ftrpt@_$3&w zgA0V1W%dAmc{FAPrMGc?>%&kfRx2mPMPw5(6_vZfzM?kh&|;iPv}C0gpuI=bQHS;( zQG*=;f1BO~{qu0369zvp*qKwpJ>k?-V%1RrDeZKEZTej9SBE zf+eMRhN_3Wnug|qjzgPWBxo1~KuH`=QEa4RFoHrZW_h9DC96zGK$kx4zgHBL7J|l< zQ(6cEq@%*}R{DIE9QPkK{#q0^?iInXLD6V`k$MiFV~ErSG{DR^Q^JffXexADbG``! zq|(B$zb)T{cyrj_c^al-cvIB0zQh9th#B@qAIn=94z#T)!t<{^er`|Let@7&aAQ?k zg)*IjW!dyXf9E}bt)?S|1trr}N}-M9Yg?Xq=wRldW5PH6p~DhF+uyWh*i7))oZ93b zNh^XNTL`u>kBXe6BWc_*`nL#cF+0ukvcFd(7{Nb%+nitAjO6pTW-^y?8#j*lR$98e4El0s1il ze8M$|`rBsZDT5=J0Mp~g49q~oh6R?+^=f*{5JeWum}Xi4h=LaApBa`Y7M6uJaW+*r z=UQSOYwXGizX)Q&w5~ZOuj^{Qts$M)QqcD6ypJhA8;6uakv2Js6 zZ02#Wy@S>+bC)c^t8g}!a%0PsGu1V{u9Hq9rH+xoL0EP>&k}El8$B$R0x%4&nraG0 zCqR>!wSBRDGrU0qr4m^WeI~qDtPvbfRb7KLtVM~m{5DB^)I7Q}g24ij1w0at>A^Yt zJgq|`BB9cDzp##ri|X!&2KqDgjB9ClPVWL7>AO#HEF})~?<#*D(u{Cg@qE7bnFnxX zb{2x_nrWyey!Le1yH;XZ3ABt$rY{qr7yColtLHwb9)iDk*{8b-Hr)NYTp{>djlEMU zm+@GegcjpA0$1C_J50q#GznRG30XCfinvX@Cu%6iEpQUIk(0PhypO>V21gZgl_}nD ziVvjXD|t8Qa{Pz_IuGX^<^3wb}#3>T7SxKKQ0l4iJ&9K+M(7;Y2KGI)-sK5uBP4NwiY zk!tv$c)=vma3P6?r%5z?kVL}=Ni=+rM8k*07lQOB6NLNZudpQGZ`r5q75QtX>8pnL z8dLOAs(@n|KHtl!7|wr_!M6aMwt?!kr?W)qR}}{jkRAq%}M%|Ebl7;&HICsz>?LstP$IEVw z1){*eGJt_)CsEJ6qSXQk06{l{YiJ4DE3S0J-qfstVh3s%dVse#RR?Ks7!shxq!RHsT?dR;13f=9ve$x$DpQoDuVHgh&qpAgxQve`v>KqaPEf{224$)R zw=`)Mr?@Q4BENwQSaf+u#D3C_he?C=L!4Sk2~iFRO-V5u!s7leEQdx02KooVz%6FG zSWHT77WuMi5S^=SfrU4a%PMOYsk5loJX4Kd@yyz##oPMqV;>O(@fYc3GEfLM#Z6k@!7Lu>5C?6 z>ivI~={H((0n6vqI{6^}%0>Shm5WAU(&xhgrJzslab;*#4R_B^Ol#WF*tm6jGx{5e z0t;dFB2`PVq2KX7ig`&tsE^eY5iGMQ#0iJ2){THJqK?!MK36snZ9~|@{Wdvy;lgCc zCy5(HKpqn=x*Z*IN3i;t8SB@td zr9C|-n|!e6C6doUWI1DT^m^-|l-bRB_*gwqMHW$`)ty|g&*`yFa9j_k)ZO4sFN;;* zi8jml-ePKKR6C6Hh2orn@)M74{RQxeZhJ%b4RP8VFN8BwQhjrBM=woY(ZQ zKT8~fzLOTEqR>_5y4Yrb9ykjtgGE5IF<(+a*{IZfFCvS8tYgZ<45ywDGoJRgQQ*p# zCBA zsvxfpg(|&*GZ`1Qvc$QAw>2LQ%F;qc6saQs&;zZyl(ax8bJAt1Bq4*GB&n6QN`F~VK4M9po5clU zN*KXZK#B{gu$gmnL6CAvOw1z+=E5W4Pjj$TFUpyyb(in3@?4-t8n$lR? zazf09)Rz)in@@Y~Q({pFsa5P(OuU3Za4dyT7-lOfFwFvQj?`FN;%KZ{CCrAUw!~T* z=UueHbrlJ!h4kweHkWe_f+Z63Cf*O?odq-VJ_L(*_0VDXKnXjiE;UR)A}6JeESCK;SXm_VV_SrzWF zT1%Z}Z~}?zkUFE`_4Egkp-O6x7!~19>i$wXcpiV?p{_x##w^Tna8R8G#vZm*nxf3N zIa&~Ht$yXR(6roa7svv?4M?bciKaNuc|oK)Nl zB}aUzq@~VAW-t9P4hI^Gs=1~bX~;MtF2w>xYF+zEe{rt=-FGT#vXvv&x34sdb4^6B zz^#O4K_J&Gj_4J?UhyM77v4GU1no5!FJ&Vp9jpAf!MS(vF2Sl`>GSzPQl&T1!|_@) zgO|~>@e5)(d`4c5X=yk#24ZtW%)ttvwX2mRz6ediCqx6CTyJGFfT)x3W8$<1@L&i|q2 z&V<`o>U%OZi0MC&OB-lf`x=w%(iCwMw-16{YKTJt)Q{IO(A-k*Glz)xH;7wE|9k@v zyp^ZCk&*y!;wA!~e#RlJjHpqk!J$o_Uh_6<}IXb^W8 zFwee0L?>4#qGrGZx{C%;zK6Y^h(K#y`545 zTg81m?>Ga<2{gFTdm`o^HHh6mNbLT0YUe#D9^oBNq>4u=9dJ7V{M*Gz?l{FA&jME%uE=SsRltya73n%U*b@aB?{Qf|FX$>)&<))MK}q zqyx9OoFM~ooUo$c|5p=aE!H-%__$s`HNiv!^r-ziCd+Iy1unRZ@{0uBQ4jKO2Dh;}T#wlTZqo>I2>EHhcBn&Y_J%(kfYGC9w~VJOAeRIfxgQ^0wT(|MmLx%=pMbCvTfOMn zbA;E95u7ZsbqoRjr4as0X$fKY?gQ;vQK40wc0GAQ1Yo&%3Q%AOwA?gGz@_6bH8iAV zVW!e7%z7L`_RuWMe%#?SN@XgpZylvtVPLP^&*o`-YZj1ACwc2JLLq`g6WnP>#8M9P zry;5N*e-z4BTcTcEF@i`q3t|3j=Y<}hO3{NH*0+w)yJtB&`=a;07%u_iEKv?CZ6JoT>yL{$ zAU~&o1E*v-J{e4AHc49v^W7#G>)eIyf>q4TI< zIA7;a0WdzAg%*Th*Sv@;kTNV$Qii21As|%clrpS%9HVArE%UvsG z0pAA(m_6#ScTa z_+d^|{4k`%4|C{Q6=%=`LkkOYaAGt4m@W>Qkj(tqIuHsdR2}M7z$P67?V^&(_B#@D6_v`tC1( zhBk!1N%0QRhXm)ApY>6E;#qX!nnfqBAv(9pHbjmg@<1bYafmN+alpn$Wb8X(wkRr0 zx5~{3n)nr5{Nd=}+@=pWa=)Xw#M9|7vB*MIF-a)K8mPsSnfP~SRx)y+Yno2avKpfJ z!cZc}a!Z_wL)^q?fop$c@Fxa;h6tY_{u;n@ zpYv9ufrr~xOn<^ySu*f2NMYc`wWN=0{vhc^3=BvqEmvQ$|vD^lfRxrD(|LoQ1dRdNM`i%eM=M1@#s%2lSk*o38t zT+K(gguxmHYZ+XsbxyIi4jqqQBQFeD&0sx)4GcCis9~^)!DS3CXHd&vvnjW5S;wG0 z1;tEVqk)@S88kB3#$Y>xCI-z6b}-oKy|nV%eO%kc;0gvU40Z?QmGV`lyed_`TDJ00 z+8Et#$UV%f4pVjpWkhx{a<3ux1u?n%8&h^;DX(U5jVXIf*~?XkA>1eXdE@|tYZ(kO z7&7E=P~0R(`1(@&JPyg7P);Mg})AI0)%ec{6t$;^u1^ybic4m#^mq zF~4cZTNpqc;rH@Z?sy}EH!*lKgSRjMXdRRgNeD`C&4V)Eknae{cgousfNy?80=y2& z0+x<<8}dCtakuylU-=y@Lhm&sKx~k)KO`3z@(8m5VD>zDry<{O$PXlIEGNLE&Rk#J zR8v>mPy;&k)=jl_HGrC2L|t2fE|EQrgOba>vR4L*TG-iZU$nKcp}HQIPNL>2?!fS~ zzPh#{mVi9xY-brwT3%!IhAlPCwY#gEYqvJE)^FWd)4Hj?xe=FWtgD5?MJ*DG#tLKS zc=?9&@uZTH9zoBwQSKPRogNuqIW`S2WJkpLk{~H)xyKTZjec08^xY{kzO$~espAg8 zFJj2Ml7G-Px%v|mC8~_#4@S_zP?U1#IqmyuN_p0Rt+&uV4C%dkbbXQt>Ovd>4E9dv z0w_}Sy2%sTdzvD{aK}jH`wU$e6+^AQeE_$0OK4mazxR^SC3kcTH8!GsBmIH4&7>UJ zip(y!;NF8r*dFPKbnhoM|NN}#$bMM=EZ*L{p>dOaW({LjvkUc)A=D8qXbC;I(T;-t zFPSYEEgq5sEW#m9y2|BPf|~_6ygFJS6~Y@Ul_58AlEsp58a=xh(F~CjER8(%LiG?` zb0j~YMut+?_>_2o${ddx@@`8WlOLoc2Rs^mh0$LXUrRc-0GkOuOTx@bOjKFkBR_=8 z%X=;PVeyP5?~}(Zc|U^(c-e1K)#I#q(vS~Y@+0ygOMX;-j4qOJ-!C&z;vt`<3JBCf z4Eb?OJ}e(GF`YZRJ0ty?6_1WQ3Af0ixE8Iv7fqTaKOvuB9y}SHgR%RlR7-irkWX3iY59zr zh?&&fzMXC=H&X^OYg zsLri{Ara&xeQIgR&&$tQ@(VmJi%(zCjos~o5x8_8g8cCp<(F`17aRnkRkzduP~L>M zOl*34+q+?DYEqJwDxQ}7viyoAzluU9zb0R@!;KQ&Te$iGQvyj0eCbjprSw0NtQMYsDX@haBzN zOHu2F^hUjUbgOATnrIlBq!Z7XwDToxbRkk5TlD5Z9B*tt(9_@E*{lpi@sh#f$wjo& z1+Itbef!>s-aUay~)%2xBU3%7CvwR(7`c zjG%=Wciw+$D)#>?_3M)f)DL#F_O@Sd3*paCrUDO7a6OUM_Mrjz{orxk{ZhS~JFXdO9f%A%%Hheb0j+yD8@++wkeD=kQ9^P^EEs@! zi5kme2%qf1&#TNo1ZjNaOavB#xeGUsuF+~(o#dvrn*aHT4#^(sA5`f-H{l7HD;WPYdUt-%UWWD|FM5LEms|S9=F~y7>4cyGx`C?=$gzGhu+AFiL3c zW$%AZvNMMVP$ty(!cO6w7|+=GfT5dvb@%X4_u{(lJ)60LRG=*ZHrCa>cSIHbz9y}L zz|r=iBtRBEeX(N~Cp!~OqsybLbL;WXLk|XN(chHVSl`v#UY(?%j*ddFNpqoU_xAM< zMm8wl6-hA&e43NCbIw>R9Lqp8kaO&~V2(D3w-9$t$A}XjwK1qZ|7%@DOm#jDS&@U5 zDoN*R^TOIBCCeH0jU~I0tapWbIQ*wEBp&dRC(Mj;)FQ@ZNG0P&vG6*W#+ZIj6B4P9 zALX$kCSJ*lI;OgR8>bW(zyrnq4o?%=(f1R@qR`aFckIyZL+h0?FoG|<12(D#$gbY5 z*2byuqoXh{f?Fx13JAMy)tsgy&d0|FD8>w}b~m!FW(Mh4n53`mHu|=^--~vFMROk} zXeI0yFegle1CvDgFx7b&aim&!pk_HuoPe2xv;7$MKknMU7yD1T_JbJ(0ioFW)!06h zu>A?w_5$4Z38)!6*RR0#Q?C6bxIQpDl@`F3Y6-AXEdf=kCD0JH1e~gtKvdNd0H#_3 z%~VT(t7-{!QZ0dZswMDNwFKmfbiAb2zpm_4fzl%8pAfT4Z40plWF!yCJt-ww;=S~R z0EI0@PorA_SP+^eAg=|;$qFj}9;qSA@$Zoaf|_>i!2>fjmt__qS^FmaHrcELllfUk z#H&ex%EApv1z!)GEA~rHrA;|$@N^U=h^Fdy!JFi7#RvtkAX$!5MNa(qvT;+B-qtfm%kXm-PmB$5lC0Mf(r;FcC@e>0Rn7xBa9>r*jQcwfdt3~2_s>=Bwn#i;%tuX*z#_? z$VqVHU|T?NFvJaR(xhpUCQaJxOWUMrlO}DGv}yR?_net~XRhuQLg2Lj^Zz_(X70?H zGiN{F`Of=&?`YS(=@5{6yrj`@VS|1HOwC2V1qAwh=Oa@H=0H3E0cz^nVwu|f@Y4V# zrrJo3V~SW#MH|W#Z7XLS3Tr6N1TUi6HN(kJO=vQ`DK_JX%%s^~fqP??djn-lhLdq* zIJt-nC$npUa8n5@N>xkmo1xQk4^PLWMxhVRQ9{p@#{~MTZfWDyJev8{)`k;dVAptE zRvY2<0&^WrL}H}KC5|jgIuTrjVeHu>lksGc{yiE`05H24+_|_~qVGju#F~iKT0LhT zBK&XZoDd3NnM){rRF)%EMVfJC1+QY49+j1`x|#?wGyVZO{nU&rLu;aZ8jl zwjP8Xya2ZEs9Z_6owmNe;i&eeT2z2{iI`)2SMyv@a8$0*Z;+$qT73&x#_M>2Z*SB$ zkmyZ1jC|}UY@_ig)_hd9@B%4i|7HqWXs=ac=Q8X1ZSj2rS+(6tF;q0 zn4}fDOTvzAk1akXJ8}dD-gJYSuxfSa*pftkue5bbs9*_sn zo&vbW_ynh*99%i*-T7%z(Cc0nXaGo6U>jqgpVKjE!MD8WacUZR9DEU~afE)}<@l(* z8|I()Xtd{k$4BkG$vgLHl9{0n$;{ARx!)m~IY5$`_Z37OmKo;_q-q%MzyG8>fd9Dq z0Pdh5K8O>ru>@U~ph7>yk(w+rRyPQla1E9xOc6Z>#fr1$o(a<1E<=@|?mvVx$8eU* z&AfM1KCHQC-fz&G4>;U2{O(z~XNJ4nGau31GY@L+nU7Y%;qOD_o_V-e9&wOiiduVT zxbkw(q>XjP!*PTlF^7Am8{Ul{KP*oiktfMLbCHjGW_F5uW;Qs7Jlr#Q zLhhMJlgm95MdVL;xo7en47WQ-!&R1(+O-&>IR|mf7*YA6c7BQ0<4kp=!1B&-Ww z6F|XFA=ek?0k>p+0n%I}n_S|Q%q$po+p%&~I0kCFB3Ax}jOmdvv9ZZJWAzEN1p+U^+eAH`9tqkfgB)>_DGM59#$A8O< z#LnH8+*=Y$NYVZ{jhIjY9VOY8E4{;?j})Bw>-)4 zu%+&%Ep<0-sk=$k(@it#RdSGr=XroBbvLc3yJ2K-53BDZXvnCg|rjY1UZn z1&F)YROiw|CiigubbzH|EJWRI;6da#3riP!;%Xs0OW7nUF@YG?xi0yW(=;A8jC*YnWRHXVvYbC@$MLR?a}&&OvoDg8@A!b>1)9M zt)y|Y+e&EP{B`*o;1s4?N%kN(kg{kj{cX9H#?tjP#J<+@vk84)eqeJ6rM(4PG=Tnz z{M3ek2X~wQ#Dn%^2{C}?%Q*ak;s1pX9J+Y8xcoKa|Bd{+E&n0^Ne7s}!#+K&mqGGL z4tTur-|`2VFym?y`HH{_>M+0W5~yS|!4J?N6+EPnsvQZx25vG{P~~QVA6RJ&?$QEJ zmV7hcyg7uRr*pAaNEPb4z=bpz>;uZe!$^)UeBK1*gWYyM8(86gbz3^tS5*kePzG(B z*D-u@$oya3)b8UE(`9M$4h-i@KHR^TO`j9XvvMkB)V2TrL`%)kKwq$3ge-Uh@8&{A zhNcV5>@{!=ya!sLkr+AXkZC=zKmGd!R^aymikypLeih_=8fztl)KR33q6)SV>mOs4 zZGI1fdK_{Fp2c8eeFeg~me~PLocbM1yg1Wf3{ne@w85^%DvFxQaw>7L-V9(ls#O?= zjW!!9Vx!GAORsX6a=WjVA{l&@EABAYnRqXZXd)(PgcGdum5cBd>QyHjqMEUqsHVgr zsu`k*YJw?}n(sO!H32b>Cz;OG&?M*Kya?;(DA(S00}lCfgCvU{Qkx4M@=)s93z}ku zTrJ0j1+juGf}Xh;OUgtp6vJSLElHAHZH1MxDS?zic$isH2OP_Aes(hQ$b^ql^;o}y zYC9j_FNlH2c6fc&JCYYmxawa8TXA~1gteTLG3VI5A`!$LnOl2_`a7S zD{LsTg2$xPP-Klp5s#r(DQwEQ4KL6X`g*)fj&qZQ??Z(_)4#8mLWTIel$L^yCYQ0Dm)v+R-6l@P#>5LUwmJxJpxV{v<1z&0_}eqL z*T6Gh#JC1USncvqCZRIefMK5w_h_C!_Z6+GtAfEelr+_j0&^`bB}30korjdGL_dsf4z}>~`=i))`Dc=KjiSd-P1ZG!l?ipI zQ<;{_()A)UTKk4f=0k9UqpatHCd+XxswlEMZP`oRme!3N>Ncy=RfgS|d<$A8t;YK_ zIxgOF)OePkqS_fs9O^a;V+%%>q#ADll$#3=%f(0J60aH$!vNKI1u(Kts__^pz`i z5_8Y3=P&;8GbixY3>5~IHHfUkn3g)p$J50t=)@Y6RMzk|NK)%t;cXBGl=7YsHDVEJ z#3Iy)Md)#`QSOSsSLQvI?2lj?yO(#M6x&Co*a2$90`x5ypiZn&J`jd?K^z+CVo>`T zY^0yTee#izJgB*Wpc@Ox!y$PjL?Y{b@@PmNvq)n7xI7V(>mu?bm16tk>5x1VqC#w+ zJQtFKAu7Z6$qONQk+HwT15{xL7!w%4~-~sBx4$!gS0XfD4^kE0+TJQi}3m%|8>;N4J9-t$^19T*K zKu$p`!q2>I$)7X-P$z!glGDI$?sObO5A&d5{1AY`l<)Z!jce-{uU`k;Q5Iv$!YkL+ zHC(o7#R`2g=AZ+zG%dJt-P)y_mRzx7#qzbF)S($^p250d!3$t{-nMOEGrIv$o9%m= zckjRr7con}f^is305GwlZ6~aIjJu+>tx$ACo%^)=!7IDlZeFnqLR?aq%IGbyf1(&* zDF)3F<6?V~${*P1I0hiPOO%-m490yOy~tffK9P6GEU|_3A{#By-s`?d-Ng=D{!+e_ z-F$?vqEyp7QEg+v)s{J4?!GKvpD!P&=a* zP=i(Mn{{ArJ6q|4 z?~BlKv1-8YNktS6aLIR$ZuFr1f*-?I&<+5F0Ag`G^awrtWiPX;J#W4GpSSbu0t zzvk6%ll{?_Gx7@?Vm?f;6dphc_6J+#;5B&h z`yw3p@hXq`nKIzXgOn`brSdJ@UEtd}>ppz3EC;@JE5?ZV8B{GE<+Q;~WgGPYwF)q{CJyHN|*MRz)Xfx4>xv6Awoi}191j^qt0J-&$XLRsN=4EJ=UN~L` zjYP86fSC7j3kH!6 zfuq0HEqk{wZ*ShRlZN*wf9%cVw(ur~bzsexHFq_mu00+BGvQqca$M$M#xdLTz2q+! zlbeUT%Ny&B#fsymE`)o2k9EY4x~(b;Ko$*^ZDu8yOj(nBBYBPcF88|^iJFNHCKK67 zn&!(!)SeAMesvJwO(}=ixeg1U^;p@C;G7LXdj#bKeQv@o3e`AN1&zo3YdycG;2wFS z`3zHwK4Ui4XDU>9AJe!#L(tG?NFDl&DI8~l*C0{gNaez4tzLj)sUoJpY<^gBKulf{ z05!Q$K#Yg#!3|6I@6?yjp<5ma5C~<1#>3Jq=9-?gz@;bcl@OUni7^5d*a(F~n^Y2gq7rKMJ=1XX0*(-Q*TK0Lo%SQ*u%Q4Nx5n163+?J~c%1B@#j4 zNuJe!laaiJE`U%mEcKs3Mv*Q2C`A(0c2&zIc6d%GJST$WkES;}^GqVKF|~O;@f&J_z|KNm!`;^_qDMOPOq|^pa%wG&DuNS-7n4&?T>A z!sPB_HMg-dOfx0l z+M+9HKCnDyO_D8u4dB$0G(p-Gb29mUS$pXc^VpUT$%py&M{JOHqlz;K$9(*t4Fnb* zpA~`v&W=m~gucy*u|90eLb=$Ml~QM8?`nw+co?o8k&oH(C=ZWGw=I{*BAc2x8)`Tl zo|306dBzs-aognMw&ewR(S}t@k1a3r>f^iu6Sw2`M!Sf}P^z{Zl2>fluYAgeaR&}? zVr;{N<*-HH5n$-HVWomJ9Fe0ou<(d@v3$mc7u|hkYM0Bn-ltiKfPn~vo4cTD<0nx*|Whe-#%Y7*=IoaAYZCSfZ~Qr(0&>GvxJn0t4e%f6gry%^6Gd1%7A z2fWBY425POGAwLxwo+x1yJR(-9^yl(7xWW^HEx_3HWdXtKOl!o0CL=pNw*zK z=ps)!nK#)YjJF`ZyS5ed^919qMDIu13NKsUWLzn(X+1Y@3$U(c$FcwU|20>s}*9WEAQ5MFt-wo-Fttb?Wc* zjYYTlmOah;oR&S?6M<siV$OCoc?eQaKh4O%t|j!Utt{9$aQLjkJp(GUp;%mE6_IohZ% z7|SgvgI^|6QxYjr5J^6!_ipUH7v^BD31ijl4N8!E4yGtT?N(R3I+wy$BF=?xX2nI0tm32rzO7 z!|tq!j*3THa(5D|@Fbv1xHpPVs(02zM#dw2!q?-G1wE1%k1oVod>RZIL1!?%S7z`$ z^RUcKO5*$!H4+$h}^jW%+~g4ZEWSn{MLPlch3d)iqaLqO)wXL)$eqTxoq zJkPK%@POUw4tdGqUUkew0o#p^Bm>@!G~2k5`_=i}ug;fGg&|JA$^#5HJ|TyBfc3^F zxL@5NZ&=)|F6VA_Id`i&xLe)9-RchRR=>%O>KtxVzsZg2H@Q*W!N|)=d)FbK3qvLO zHV@db?vT&tUGh7W68?oLNb}ZTFzgrj>K7x}-Gs3HB}=|+$zL%WU$Nw`X+zQ-lCSdo zH6Fgs!{0>Y8}d!;J~EfzieP~LHd*)nj)%YJ;X91-yF7f4hwt<710H_J!;g6QF%LiC z;io+O0}ubm!#`mxxD%CrBlp|CAwLVr&w2i568Zgtha+IkiXc<}${$F)#iF@Uei@Qq zF;Bnb;on%ezvkgLJp4Nk|G~q5^6=Y`{EqqkeFXb#{~eM)@B{RF&hr@y>+gZ=>X+8T z8S}ag>o%=hx_I^SO)HnzUAl7prpC3KHqu^pz*T_a+HJfz=CaUH#fGlH0{0V zqM6gz!5F|S_)GL&F`Oc9g-0-m8Su(N_hd>Icz^}zkPzd+Yz23j`@C5PpGc4`vg#_b zDK{dW`#SmY)|(->Y3M-4U4Dm6$n^%?XC0AsYl*<@1}x99NOu>@*bFw3hbxmh>zZVM z`4kWH@uFGPm{N1U;CEGsEMGW<$6%Ea7g|wL#Knk#Xz0a+DF8<>Ps=}rItsVmqT>3< zymMv7g7!Fbou3l-Qj1sriXp?Q6T3qTw!)WbTNktrcgj6H+yx`|?1S>znywAP=iAOf z^WyQkt5g8rH%1}>65ItGjYYQR#n5>+xTW7~Q-f&B%>p5QM)t%*H84%@?oV5MrS5%Z zt%O~5L_r=sOGRuIRkjUw-Meh6AYp-`hS+eWk3)g%wN)VxF&>I|DCQw9_nlo8q)O!d zwi>43`ZJ+M*lHvXqg1J-M%!wPDzjBN4`WdaY8*d2UQMuRvuLY{{KzC6s0y;wWLr&< zTWkR>udOOnrLC$|wWX$N`yU?A>jKxnXbSv3?pny>%PHwOHFib&4ecHK+RLELYcA`8 zt3!Mr%nLlg!|+Ts%TgEFYPPC5M|_2v!{VB&=Gnle%(vA7wUCF4ZFPyNvDG3zSd3Cu zOBimcT4t-|YK5&X<<&|a>KJ4dgIva|)x4@#Wf&w}S)dGkqpYi=OdHkUh@>|#@T)J*Ef4E>SkJ>1IH1L$pN>wxZ(cObsH|g~ zTZkJ}C5Rtv)ud*@mkeFows&-uCDqSm=!#_>yWzBsMrCDGfnw^IYD0sJqOKZ919nqj zlTu;;3bC^p{S3lGsYjm{>DF;Qx? zNpiMyKqpkcErDmYHLZI9kZ8pmZZu92++W+;Qs3MO9A5sKx~s^_uxZJqYiG@b37_xx zCfKMYLtq;8h0wp#L(IGgaU^F*(~zKK!5uU3XVfVDFX-~TkOTu;C~E7h$IP*-d1p$7 z0pJ1Ma#MRkF-}~2GaX8 zN~Ze&KTft7(9tvLqDbAQ;5P~wntmRql)wGKSv>rdgGR5QNxC{@uX^~xpj7&RdR#aU zhYhS2OuKaV3bbos4lZm3G)-s!z7){6b~C)ND3$;zWqvUVV#aq9EX3Me-rmyI-0oKy zro=sORhXu)_bOOPlrCA6`Zh+K6xh?b!x5)J!-X9ei~QW+&^H}e*AWRbLh}m}dt(Uh zZo=IF0N^poX}FG2RMht%!Ra%EIGm|7gcyqB-8z)9mCCCCct#mzPLQ&yd9Hp87zz|g z>TjVC2|)dngY9^j_~cd;gg+~J)HhmM-x!L8T_<7@jrTXVqrTfv9h%#=?=}>9`EDeR z(sIbUCg|?WUBr>P3w52jizrfesS8X+F9efl>u7@(2#4N_64)fl^0gST>-PqIB;>nNo!w zk>N&*6{d9UJpLdW7L%N9KXe8M{M(E_sJpe*A;Yi5AGHUx zAq?VgGyWJ9R*CwJwdN$Sl^F?r+qlCr3a3$rr4*<5VHu4RKtKFt9hNZ*Mjpb;{KWg@ z{Z7)xJ4qXk6qT)}?=_Sgs7_ZyPYNv1SXU+Y0NkMH{-o$9jXrw*fWU-X!IVzFVZzt* zy$0Clg`oKxTaUxIxj|1)s)9N`1Oq{kDo}Or_9Whp`flr<#M`#-wr+V&B&pt^Tb>g~ z>aK2iP86xTrscU&_*xz`&n6w72I-5$4egc+j9*Nt3YNbdiz?yqNtN&fMG=48AX=9^;<%lzZA0At<47|~;lh3GM0$AX7+vB63bTM#I= zd=}dfo~G3dg-bOS+fW$vq1aGaHMIqaf>W}zTN2nbhyim}QW*wkH@aKlRpa>YksEWst z24@38QTyNwG|MrPaV(n$o4|6sz-^l=QQ?X^F%wWZy|SU3V^^}4t|G?It)!+Tg)J7~ zPL#*c=V;gY3Q7k)8*f9*Xu@3>fvkEuu)O+N*^bjS4cOt?2$R35xi83-I8Vcw9@C}< zZw=lI`%>J|S1`flT|i3XxxD#|Oy=xzT&``32jjU%2CobOuGupaw zx#K6}GNOwcneT}&w&W9(@>Wv}5vsAA()%HbfsNoB6{jS>Ti%PIF~1%qIh#i63GL0V zg=WKnXJIdVT1Ll%foEiRHA+ekQ&HGkhjwz{snMcNWuO`_kBid{>InR`;%^%)v2*d3 zg&EHZ(7reqeCAVk;1S!`jw8}`Sr0r|>gG2Q39#x-p)(nb4S|xa1tBXdPRk@uL%$v^ z1i^0Tm7Tbvw@CQ;#K6?@M|FwS8d z&Z(7fpREMA#RqR=>$EkO9tlp90$b7QEK z8$+es82UT;Ex&}Vp%VGMCI4l~e@Eba;19g{Km0a$aqp5dc#IX0QW0pCbMO|qaBoz( z5gDTL@F8W94p%PHDqz^8swiKudB|tLA&5i`wN!zn3L^?={wO@W7F#MFkwvN`O0{l? zWVjb;GTewPSEDS_;a*BQ+#za=rOJ3Nj>;-kZmF?RspolIR2o$|UmqV<6VyaYO@a}y zn#}J`LE=>f50yMr@leeNQ+YMbQq!@YrWtZ0vQevQBeGe|wn&n@Ma^NLxjf9XRBZ(A zujccxfcaP$0#PoUB3#19i5Eyasd_DPa@%ze<+K{*Ctwp*$GZ9yT4|hPDbxEex#w*sZ zxnlh$V~49C>2m#=wk@FBuhBMPGs%JUCiRHpe6MVENQ4ZC%2g`jt*yW*+@z~2KJ-BElD?0cNl;|dd=R>9j1g* zu^@U&d)8xK9i$v|8LiE`lw5Ky@k7a)jNU|msFUz%2ma<(ah8&&R>Pq;CBJG~d5~Bs zbNzX;!zgx~J=nSAEL+L(Q$Ww@mZEjb_#H_ys-cZ6A3!?14L?~bY59Q-=Kv;*w9?Y8 zhe?b(sL6I%mYa&dG^LW(tKh4 zp62#WIFm%(rV3k0!=TCr*AL2CUgy@~ zz4_$3R7#s4tO6iOFfL3?w-IqG-4_taAB&egIqzJtr(;)IH&^oPg=w?f42Io1>kg_q zbw`+%ocJ^_^_%~vlQ{6XIn^OBFSB=#J9`D8zIXXs-i0b@)8b4~11h}}0t+o1lsx~Z z{N5l-&p2sVomsG9v6?x+^oR`Y9>qE~ZS2cXuHL;^Q+a?hpW9TDQLeFeHFsg74T(q_ zRZMyfc*h+tGNg-bCkP=6GS?=5WhDofKGKwLhB4EF|2xT7y(1a~fD*&ZnKp1B?ftS* zwYvgjDz+8cEr{N$FUKC7w}xOtNBJTZ7SU%mlJO2O6i;%s^r>XYfW`=Sg3nMZj4asM z)d2!d4+!cBIp~@m=rKtf3{fJtsq%rZj*J4>8hBYrmy`hk%qE2;OFmU;sghXSf@zz+ zfS*uT+t`D6pQWy`f$_M`QX6fxNo{s))Lxd4+fbuC3d+QcX-dUt!>QY|4nS#|-l%Or zde?NoBBFIqQUFEUZ}Zm)lhACbEwuu^f8@Ac75~<0SH_T0LOGv9?iji9*E}@{fW=vw3JPEhdJ|s`wY^z(; zt+u*N4kCFtsQ0iSJe;-zm4BF`_oB}XpwiqPlVugdn1Dn3gu0#ff=JRG>Q0+J_91e5 zn_)_NDfixXB^RH#YN@+ybvJ9{9<^V|!hTYzW!<$H2pijX-r|d7Su2^UyIPsRdo6XJ zO%5(BvtTA;tNYafA2XuA+>+hVL}&(nw;QVW@!h%E(v*CcND5z>nP_ah|9%^MU%e2% zGnIsy0i5E3b)|X$t;8EJ`GwSA;Z9B2!nuQylLYyU9Jka5Z1q9)p>rr+U&_42`(ays zM4?3=kz+R8^}*ZLYx26WI8`524`~xo4Ch%hk!tCT=;48sZhGF`+CgPMlKoRVcltl| zv4MTcUwocVJxWVgn7L|W+DxXup2^Bqk8z~w#sRyvsMICPS~1*$L=@e>!vhK?Y|!m= zt$WJ0L1s5YSt{+F93-}wAq-;*3~O1&IDA?D%2rRPCvDKXo$SAA-9b6^sq`{s&w0vH zPuuDl_UbI*!D$KeEJ|Q=m zU{8ghg3o3dZCt7k8t)f!B@7oYI?C_i$`nvWyk9O&)}dzh6{rgtgm?3~ zH8s~3{bB3~>~p64G~eoOck&dLQ+&yQZl$nHpdfO5V>r?2ENIEv4VLT`zHV&Pe4gC& zRV^l8^cAg9l9@`vawu(0oqQ*KazWd04S(E(8To<_QjJ^}WM-f*-K(V8@Vh18lT>sG zuz*b(QA>UFXUSBiyh2D@P`0%=Ya7Ny=PUdg9P6L9NW$4rgiS>mjl0gz!X7I+a zQN0U$^|V_ZK`jQZMo8kK!4r< zlnLMs`wc+*0Beb!1ikR<+D)7RX3!!2GtQTaoG$?+sNiSKL2gjFVgi7yC>4_l9$;k;Juy}I@`3WYFo?t?y zPI_+T+lgExJqIii(}9Ya1S8~|G!p$5;LnLj7dS~a&JHIbgU`W{l1V)A!Gw6x_y0^& z?WuqQ_0fw?z$ToD^j)ZPS+A?S@|esDpsEQGL>-V)6Gdzxs%j?GE%_>>G1O4?b~REM zK*}zH*A2m6tv-8G7NBn@r%9IJb4*#}xLl;0$ZQwe3iY59CXNt99RX_%KYT}IjtLUr zGS*4=G@KdDIC2Th1&+_8HB`wO@FX~R$bklWvkx_p^QHZWgxF%T^}3b(l;l;u{b^Gd zEvO5|{J3^3m{#${o{EQq!JaceL(mFzv|6%lSC~2sq7H+)4lQ7b=+Uzf9zJ=#3IhSp z{6`jcGdQe7`4DBd0CCNKNBcC4o{|OK+RY|9`+_1NJ@YZSgk%>B>0*NPx{K%lbMYH8 zpRbwX5{J{BjhQGemMB|V^cY=OxnbZg%lUGO9A&9n-q4ab58II_4isB}w1(G=Dv)>A z1VIZ8q+0Nx)K|xIXA%YsaB3|miYs3d{CG8Cos#9<5=&SoWjTB#dTw9p+@{M!=l1?w z)pO>sauWsxl=JOjI5Y84CLY5bFsLR_1UiMIP9TCBS#G5jMMS3paeLWGSw(<3iIl@= z)2rP~^R;8nYtx;$#{*1Pk5LR@y82_%fS|b1Xl^tflQp=JOc|6@&f5zyLa-IiFvWVg z5{%euAD6MHmC-p1M^&CUC?%Dnj?22H%26|q$oh4lQt3JKbH}|%fXW%98a1TWq8;Yr zyaL_q3ZkS>ODkBt6S*wU6UN5{z|;q2b;62=XVS$5sH}m(TodftbNUr(0({idJVKK(X z26F>i5V-kL3Dr_Y;d`23; zMCdKJ7zv=?U!#5RZghO{ddEhS##3lepG%H^DeDeQ>~3F#4$WzGKS5S(WZ^GNOJA+( zbsjR$*X`cABb0n+a|^C2_gMls<=-@-Tn6OcBbl#K)fgmQASzaH}-hV2{7 zOb?(ni|C`k*b4r-^%<9#rB6FKeiW6)xwunjRL{i~v>Z7iK+-z1=dSt+wAl6vvi;y8 zd%g3dj%cSFSV-w%og8`c_0+?URbLHEwLcHPhi^3j@Ic=ey zeM!0`_}i_|6bzwFb`n{RUmOhLkmI&Nj^oVK={om0ga@3czW^UIW{NJxnKN&w64OXm z0DcSkFEvdm@<2FI-;A)#KZ)mqO=gxpCVN2;mIFAs(^$t>;>t8uNE^rGCiM0*KgGR$ z5Su|$bmrUfpz$&5o5CZtxm8BY;3R%IoKOq?uF_{_5E@%275{_m5wQD1)9(6fb+7wd z9ZKS6jK&;kPRk>SJl)JpqeJJh(2X$Cycf;!nA{Q&HokXgKap%Ow;JitG??3ZWNjh@ zGVm#$5br?m(;yQe}; z{}zMsRRg}%AZzv6+e8FfWH&`0a8hI>8Qny@DS}YLwCT@5s9`4=SSs&CD*b5->a2IQH$OgMUIM*~f6MXd0j#{U?;DJt;pa4xiF5&65<&8YSu&j7j)w6L;L$lUB7%j& zNJ~apGRBfJEMm9p1@#160s8$cI*VyM@7mGUIez*DMVDR}>;QL_fq{h%x4jcN;Ch}4 z8J~W^r~EN_GHNNUCKw7`!p;u54XSVL+R@QsNx2QN1#TvW%Gfj~D&}PyE|uY(WSoq* z(OxE?RL-;NAPFK5e!qtqHbE*fZswUZX>244U}bZA3tU#8?>3YRjipk<)&DwxY zqzug~jEvAiA;uySDJWn`qHR-*9f}zdz8`T_jyA|UaW4H;n$583D=2s=a)Oh^kioei z%7rx+oun&X_rhhNbIZIHfI5RyQXI$8_@e_fium~F?|ZMkTyoV<5GVi6zwgaV>w6=^ z$Y4PP2`RKBW=Y%v694~WooJX1T7(3R%PbppFyg#>3H*GZHvf_(WR_|M;s;&0Af^EF6({3Chm`Hh1{uiT9NRoH%XZcXb{FqDbOT%Ex`TIh>*f=- zjORpbTL2sr7THbIM68!hY!wL3M2$vDg2)4m&!ZJ%kdq#68VqTQ z4TaZTthvl*s6*xuS_pk|jYRxI=w~l|>e@C~hw^VJ0-jf+^ADMUc@a6TY>U>D0cC>; zlqQso+JrJ9dFD=`rD7N_RS};Q^AP8u#8SgT3hRa;DiM|8Y6K4>c^DN@rD`;<#xP)6 z1PcgbO*tHc%T&}&yy|MP>yCQU`AP{D*56#zKGHKDODX+Q`NKxeom*(n*U(Y zSgmI8Ff)u0vm)vuV^9f)c5@?Yo~jMw&V0UDYpDfH&BBPxL^5&b;^h1gft$NU@X8v2 zle;CBS{epZL{&sBqpjt9T2?l~vJ!_&Ew$28brC3#Z5~$f=4BChyQ}A`4LmgRl{LJ& z+)`^Twa!xOBQVHBrmlz}Sy%GMhLE}{q?&knbp)E(1R%pvxl&zg(MRr6YGXvMQk%kR zvub8_Y~jzXmTF#}t-k3(UGXl(PJFhzU^6rqjkzd=x z+nv1A6;gY7zA2=@_EN8I4yjxC@YayJjrZRZQt##c+e7LO-oG=X?h2{9nd5sRKz-gD zy!1{81jze+A$31*9|+F5E zMt6`AKX0iQB0vbg$bc_}R1d%Za!7rg4?hu7pA4x(A@xc~{h6gc6_G=#$WpIHTn zSq+C7>NQKf9+AW94NLVhanD)m2=5=|;TR8}VYvXP`Q`w|Yjo)WP}s)m8rE-G-?(Yr z%Eq0zvtP6R>>!+QmzkZ)#|4*tE2k-*1x9=cDk>;ccIY>PQvYnq&DnQt|KvGF@Tgq~=bKNcN zTi14UU<%9VjX&&Cf*>Ou_$VBnm_ zQju>UrAf?727BYRMu0Sczk%8qyET*n+N|?5)Kz~ZSN~N$c`K;^F~U;Xf(5mn6dKu+GZz}eBGL@J%` zvb{g>DGbv!l06NWI!NP74s{vTP1F1}dzQhT(fo-NRB2lIV$ct_wRnbR<6PG%LH~Mw zz8SK!qE$V{g5M#7c^_@LLmU5f`776+OxJ?PlJIZkTj#BloB`^11zQwNB9DDga?5{X zKt^?tw7kLs<2hlgx70~no#Nqh>TOH?xvf5r=+$Z5f$7>`+v*+l7r;QKT9r16R9{eE zwA5eP>PzyEw)!%I!2LL0W65ZPuxXCG(SAc~3tu^#rsO;7uWats+UhInuPyaeo9=>0 z{Ql3j`kMUGR$o^jRR4zhrltPYR^L+J&SF>Po4PFZceeU_^&Lxn*H+(C-?!Bd)DHm+ z_Ks%B#@lDovel2&cWn7r`6U*0w)(O93rqdPRzGEKFRZ49@uNEa!IodizmZS=zhTwl zO{6m>U(ufQC2nTSqz=h#a()v=Tm7T@Cvw*R)>1#S)z1|Q^A{*+^)KpQZS_kQ>#x+m zWj8!?EnVE%Ws+_NTG{1EO5^URj_f2!Zw>UZk*mijMS{kQsq zt^S9d>yPSfc9A8vI-~v-l2f@!*Hp+p+(4wa;K@^_8k3dDTW;xUz2-WjS($={5r97V z-=R(k1kfemfiq|aa@E_~_{$39*#V0^RzZFuM zYlVeU3`Fce6zw5kGkL>28DYW<Z=i zZwG8$%UW;Vtz9Gejoy->;Tzu$3{@B_6KS7a>O{y77X;wJusrjJJN3j3>QEZU{U#8D zjat8-_Jr3TFXG21^%pm1i@J9DhA)E|z|^u0Z98|;e)p!BwY$apWXQBKsntwYmE->B>ObAT8Ft)&fN&LcO9;O5;>_BB;qAh0vRaT&S zaAwMZsex(eC;?DV1XbQZtTnTl-J-M1umdv#vq0>*bPs7DTgtM8O}7&dT%=n$yNAd09XBB*==f9nZr@GL zxJI6G-l77wFVTj!PrDusxDAB5yLV1&Z|&GcyTWP7S-K_2wXJJ!S8K+!a15Hw zy2-^rB>#c3O-%#?vyA^vphn5X*;0c(mA(&>V>fQ`9+m}rfy6=efD<#CLHFOVCGZ2Ki1vo~K5*F+GC0%N=w?8FF#ACtMv zIX5%dlt+!EIZ3~JJ{QiWGh>#pM4(12+h}(oZn_NG{kLiq_&qVsa4LRI^BfTEVa|_x@#qUyS|ysx;eX=Z$@_`Z8W-R zivJ=5(kX3QJJVJ*wD`#5Iu7TphPh$zCd^$OroN0>pIe66cijg&-meWyuYejFbMjzhSoP3&6Rx3e7# z*g-(bZB&|G(#;wsfOECIbZySPww$a^SK20TOP#mdnxakFue&DRy7eVRZ$0@e#c>To*rWPs07@}MiEWVlDW@eH>!+~QuyIYDZZ6pm=N+9_?C$#`;Z z@!3W*dmcXy?>#5Arf<+m#-FaipFhB0OiDj490qBs3+zmzwzIkt__`6=fQR<#TL7?!pa1gz7VfxijmSAfs+`fIok-KV~WE<%Tc zYEqw}_)LcTHo`%9iTerMgX?e{zlUEm*(1PZfkx@1?0I2a5&+I7hj<+t^}?X{4Op!b zeS?q@8u9|mV-w4hZ{RN?- zqj?t%IYZiLH~6ef&$$>sZP-K>2QPkEhV;nj+ThEu%?rL&n_K$0wjAc0@qldjILtt3 zf&e>#L>}NcLC~aM=9nI=)91L{Aniy|J7|)4h9wC82&i0wKdecd@^~L|z?8S*+qovK zB`Gjc2^g$T%5ZWd%z;Hj!nH0QLF?iPv>Sm6;iQbB4cv*5&&g2UDuuEI>3g;3%-?!b zIr2>qeY2P@m#gu?wX#8TXP;b)rZ56HRkQ*jn_Q`C+xGlnve_)0)?o zR@m{1Y?DrXz6rci{LS=2ckHB>CYMYvtJkqj9d}xr8jh>4I&pDMO)wrTJqSyxcyJ~Q z3r5q&i0dPyCsG6`muFlEB(e+jq^;^Yw@2m8nIw5u8i`%r{5 z20(Tqul$%)K9=&o|_D$Et6=o3X8b$ ztj`%VuT2t!|3d!7`Rqs}P$5w;)1TRdoY}oH>xf)rtn?IB?oPn>p}9p7ur<60!5njX zR3NK!99z$cnp_xo#`EI22W5657|)wYizr=-v#~K8Dwdj(5WsRM+M4ROUm1fRPfA`% zXwm*W)a)0H!BPYUOOdz6yn6VKPmW_@O>f^yzTRtDQbkzdPioX3k$ zsvOH`fA2QBRNoy3TWe6{z&NhH^6jd(bPbHwNX0S0DiX2Ck3r9ZCm6$2)G@aFzK+cp zS&lOm5=QSvONEu>r%~jf&zWD3I~Rk1qz3i0fGy=j>9aB^r^bp~Xyzjmd2wrIA{U1j zL5l#3!|;CC_?`J_5A2cI0?}#bHctj1}_Z9Wi@zW>XCG``bLoMfO03cmIpBIfP82D z5xL^6{lI;lL2iukq4)dHx|;9jyom27z$4YohJO+k#oGFH1Bc+NYV#`5iJEGy(r($p z(z&`ebXcyTogFNKm$9+d)`m;@V z4n8CCcmxzICXF45Fw@A#yKBfiwY$cSN8|Q0a!EXjQ1jw8j*N(i zi9M*4Ug^?#-kXZ=rg`~@@1}V}hvyF;`e-+KT9WD8hgXN^!*()u3$KRaN=I_5Dfz-g z;X5caT|7PN?-GS9dv%DZysjpOSg)%oa?4|CJQgo{#uxi-Oc>~-_QYU3d3n6ZP2#RZ zp{cyu;&|+nXqsxGZn?CRFxLh6U4cIUnDw(VT)z|#@_StEFM3I ziY$%~%iVEQZm$_0FJgqX_|vAZ&Nbtkfe-rHR@$i0(89g$E8FHKA0aQVv zuvgxPwitUqexRaFd`2>4=gmWxU4o$`z-?A%`1mPCSlEuqw>fAwRH3Ilpa&8B{6KA< z9z3ft34f*<<0kED(aG6cPRW(s(yi0fqK_*pU{V{$*mFca$Vm|$&xVP=s*UzgC}Y<{ zw|FXbvw$}-Y>%R-7L7+9hXpt~co6O{E=@$y?_U6g8}8#e=cs&$qjw^@4qu2OIpA!= z?1$2+<2d@b#H$z^isi!?))`c-(}VkR@7U#LKf+BXXS$k$dZYzUWyQ$6&9e%I-&`>= zck`@5IdgkK!OeG8j0`$ILj0lc-)ROzkw1znX|F>RYz}iU7Erc^^9D|Tj$qskOMfj= ze}vK>eNa%IevmSq*Zav-nSm%~0JYAuS2PY#aqpz}=cq&)1bk1|Pmq;{0T+4y=t+4< z`^vFjmxnR#_R1relJZW;$M8+InMXkxg$aR|k2&5KAVM6J2QVel{X!yY2F_YL9_p4g z2?$v)NgYY&^r#N5xntst>O&H6p@9*Hr|ZBa7ep;t!$A|*E8Xi#`Ew>B#<q5>0rm_blg^yko7nFyA$MtkK6(_}>{MQbVw0+c7wOyOM<(lJf* zQF#V30}KaH6p((qRiz;; zQ%B_4YD)E(KC9DbPuP{GW>5OfK;ze~bz?ji(iLRY9$Ck`&pj@e9hc{t5)sUUN8}(1 zHO!1Z?+&6M@k)-(FR;Vn;fowVU*eC5`JqSXU3%)hyMl%oQ6vs6rpJwCAA}W>_2pKb zsL4aB^)=k7K+cKhwQz=eS}HtWdKr<&(Q)_0KF%vN05g^B>XE8==t7r-6 zZk~cBIuC#R_f`CXT?#dY4Kk;RRykd&ETf3=Nqhh~q;#QU2yoledGjueMU;5=q6390 zPdvr?xEK_Zeo+?=7*e7xha^1~Elh+cd_=gEfYCyaltbo#p~@jHm0#fv{P?q`ssx=r zd-mFL*}PpYyy(B!%dh!UV95Sw8Y6? z*nl6c@S<>9@~cmDODG;>!rA4UYV+t7gq)*hMg3WM{g}ML#@dTEnWx((Iw{vJ@Y6zx z)g!beoMs2911q#6azr7%;1y;g}^p>L6CN99fR4T6CB^91}r$ycpFh$7+M< ztsJO>dfig6m=F;s=F|cK(z1RGaXXq^8Pbyw|A7y#@u+;}HQ8=To?V$swj7xc#m$>2 zd3T@<>+l|9NYcGE|FPZbz`V=9l?ZVDYDB*|k9-c)W^zMVX39=WcF~Yu|A0lvOo2tn zZn=?Hdw2zNkeSkD$zFKZq5_BqlF&?@tfgQ+ndBPG{fjlfvS@N_c&sg%T1$&Qy7+IXB z)q{^a4BAc~Hc!c-L92v~0u<`t6kk_xmsSJkc0vCO)pm)|)}{gU@P^mybZN#wULa{_ z>mIVDr7#85I@h&t0RV!EW^E>rMEMWOrR@da`0AH<>;FZhOM}~S)f+qxbb;=M;cT;y zqJDrBN#{jS1C7@L@JT;J!OG8lJ7G zQu&^~d(!Wwi3be4LRQ;YPAv3ol&o%Zaj!Nep{3f2*dm=nojh-2Qd($3D~$Ix)1O+A zt`k3Ua}W@l74m`&b>t;B)Xa#wQP$Yd=&rS4Ccoa27j3wgdC7(kt!p!2mo4eBMKg;u z3D`%pqx)24F9kOK+^SX%%nk)1AWAi9Td5hOnFJ(6U`Dr=_OFnJG!QOfp$n`;E zX$pc@Q^lZ7srmJ?ay%?A{ zIBIv1E|@tN_%{e02u!Eh<2yS5#$z(D?v~E3)?Ju#oA>N#zGZ92Zfq+%8=gMYOkLjr z8!!?KR|GWqEm|%FVby)!QPbZBGHgX>U{~@Cx@UdehtEs3Cym?~Jf;QZvJ}RZsI4NO z_X2$rGfH1TR63r^xg)WR6%^reH|Nsv`z<<9wV0oY?dkvyeVx z@YiQdkNS+M5DTAW`g*zcDd*Jb z#C@?7H{C=>u5GlwX2LtyUC93tk1xI(UULd5V*mSA25Sm=w~=NsT$&Xn*9taYiOt3?SHuST}w z_1MJCt$LN}pDON1+QHAl<#bNvx>ti$CpP1{p&CD`a;ow3s0>SP;`Y+~}xq+XfaD^s9f<8CUx5y|=p|T-O!kLvg65+7xU&0nt%6Cp{7nw{;-}VFnFVpMYcpWXr z|9VyW>!5X!Elwe&6bi3Pz$gV29HF*2k4NAuta}ztVB|AsX(Q2tT%|%Q_JB=Ur(82( z=N?**>J4s~?a5D#LReW5*k3&U2)ARs9<7o3@<5pW@R<&{v-mKT7xU%8 z5LFj3sxA)5!#q5~12h;1CBy&MT(M%X|UuE4t(pA^D^whxq#yOa9D~PYp=zQP7-p_TWOT&Y%A~(gMh? zL1tYry7DxLpYecI1Sqb@3~Xt~-ga0flDpj|<}l@-A+y_vG{;vL&I!W*8M(_*xn%N9 z@UA)mc-KIY6n0!_=zzQn#PC9W^UaQIt%0uOfYDN#Ycag7uc1G|sXn(5IlJ0``UW=g z8Y9E^^R5A6p2Zb`1>fl&Dk7aQ2y+0ax({cC?;f+{Gd56_Z`we8t*{}%uGH!riyVO` z!2C-a@XIgT zz*yoFw9S@!X|M#Q(qEIW8v{_t-HR;wrY(Of>-tl+gy4a04{hUYATz&BYjULZ?_uU8 z-_4|C`5t*5za`(dvD^Dy8-PV5`>Z=$gOLn|EbqRhNVawH z0BsB+?tn%k17BPaYiI|>0WM{$;|t+J+!116mIq$@mCQCh=j3QP&CA6(0p;H^dC3GQ_D;AJ~83N*&j9CZivj!7EedV`3x>EG2uKOW8_J6)F>v@-gFk9DLinq~9}8m|{s=?kvoie6D!AiN;T>lV#q2}JCBG>) z1e%1Q270j(kE#60$A>U&J4u1INjoHdZq%ERhKduxXHl9tGr6`s4M0{fr#c7VfTL1S z{VG%~g`kB1FGlWhi8UoaI9Bvl1@WK2rD)_>Jnx`fts%FDk^u;><(m8@9tNL4kIYSy zz)U3x%+#7_HIFuqL`QCpNAHW<_r-(vwF5_2+|sClLSNO$t{0(^ffXfG6BRnSMq!}K zO07n=Y=DKPqdGv%qCpsOvQ3oGnqkdIEEKu6VC$) zN9j`l>jHr{^3$k*QMFc8!YVx~rN|fXG^2?d9Yfq?S+^YK9bH9t=mIwN!)w-$3sdCp zGW@MadF1YRGgKSNsfos;_;nCz3B{vR6DR|s9?SPf0qyullolRZS%VUzIMxjczo@aM z*tjDy{;f*liY8PtQ4?`}0$E@_CRLUMp%ckM{*vf-KQOTg4KctXLgThYrb+&M>yY$QbI)5^>J%j@{ z6ddiSNuR~NyGZnG-kMt}gZY88u6s6+XP>>$``Xzfm08w1*;ZwP+K+ZCawdyx_25h2 zQ)Z@@ApQAU_wJ!{GPm3K^OFpgN&?yvDB%a$minf^Td2<0APU7X+rX*|G$)#80B6lJ zfV1Hl;KZ8Z87RX<%auqmr9ef4&KC95O@LeJ_#x1 zDuZXz(=LReB+ZPrfXfs$ z0R^xxYzlv6KUOXLTY#s7tKT#k?6xqfYc&t`JT!nDKpJ_qhKI{}SZm2TOV*Rc<%$UP z&pcce!OHdO2uk1@B8ac$0eoxi;{Rl?r2LzB6IE zUCg`1mF!@Br;UL~KLs6oyLRvOd9_$JkiMyLDd{S3&-{W`qWz3-?a*E=Je!0`S?N!R zC36I!^PHGHn?!)r!^zWD2nt=T+CzHZd}i@xg6i~vm(5<~Q;qFyAyHxJ*(TfsD!q(gVDA8*VN*5pl1j<{t>vUgMd8jw+#Xrh3?G?TU^+nl|EZ?u>cS-1;dIw5P?E$C~mWc2HL~c$6RW1#SAsj>A zEvzIvZ*DJm#evhyG4eMEuONjgpjgWQ@vCtXHwhRvO7aBu;hSV#578+}F37lsV51;- zDCZC!3tqyQ;=Dv*AM%`rzU7b*8p1YYZ7S29kCk)qaYB!A@?XSY^s_G}4Cq}4A7Y7EFx^!~$yv@($9eBEoSBbH7!shp!vKNud#gdET?_;0 z%9BzI(C4f8Sz>|R;G4qg$y%MoIB@u!$$*uKLC-%Z38F^Gjy(R%5NK0RnqSX4%tZp)z zYhLovo8Nv6cuD@v#peb(51MYCfuIta(0r;`ZK_x?Y4ZRU%7{#{1l(tNGJ%$uV5+Qg zw5$=WWwiv_t0V#Q1tvgpg+2og&{lvK+@oq#EBs8c0G#C;k(1Jgcecb3IlR52eJL$F z+O|N!)4qKz)N?NWZxxDTftGx`Dn-d6!m#Z$>PSg(8}@||g8T^%Rgb&*Y4Sev^68NI%0K@}XUHg^fm#xpUT^4ZLD z?|B*JEwk+E*KhJ5ML~S--CI)|8OLX5H04UnZX_Y+1Q}p?W27sZBV87NaT&)E_~o7B73cT>Rbb9!h-!grClk=iuNgE`A^9~iednH(JP*I7cJ`1Z855#hXVuTZ86g8_6ttS| zfKHW_3C=m3Q%?~h3{<`d!9wSex;PWqqsto zw2Ay9jNxo=ryHxK>A)67P@5ykMm#Etk}IVSY>XvkVcaRVWNZYY-pG)Q<9R#}m^nZ` z%3zZ%?$}L~3QH<2slrgXQ|rdDP2ebU6yww}i?$obr2H<_+R2C4<#<}za?_goJ zIOcnm<*r%Xptngpn;(9qzw@!|iyOzO@HyGkMcO*+GzI2X_{Gf#>fuvVIa&#ujpB$M+IAbQ48yq!(mPRj5jaf&;VLnH@!XRoMdk`N-9q|s9SY<;M_!ISCM>LMtBv)!dAD02M>9+3=cco#za@fYOmKzFvbH*eY5img4W$CCn}Z^)t;R287vW_U>VSKrpP9%+*U&vm`TdtpR+%s<`?TFoo z&26XCrrksv@+&+tr@|-S^%tM!On3EAx^HM7(Ifz~oG~y>xs~yQzH!nS^wM@cGQJ0T z56CJuCM^uQSQuOMhM;i?usj9f{h*rPg&%Lz*wlckfZK}f!;z2WV^D6lH3)t0?%f^4 z{G0m2^8EhV> z26C8TMqF8vPF~ZWW8{t+(KO6v>pXXXh0Agl!u)k6GGQxefO|8zY=cwaIBa!GtKkip z?y@kzW7PhC*n1DaxXLSS_`IW$?$zkZmd29pah1C*S&|zDZ zwv+Gs|IeU1x4gZc_nhaPV~5w#m}@>zl0StND+f^~C`mGkdS0l|$&tz^u!84eak85VF7mIIAScqWR4D=nxchm3FUFT$bAd?w+* zQJr91A!>0VGEX!7XM^9A2ewn%iG#as-<0`p>cSC)e;W{Zv`*bL*nKd*ZE%3_9B@S3 zK5m9*k(BftXxX1GV8F(IGjtJpKN;1J-rQl`>|_IZ{i*FW$!8C2GkeOUlj@l}9f{-MWiZ_?~%iFle>mpJkCbQIQHiI8JdBy z=W9ibI--LiQ%4tYv~dmN`sE)HzLm=iMt)8VCU-yPIN_?sZ)78JpyowGpTG|RFvTN% zoG{WyLpONIa%3fvO&L;$?1`7wLXO10280`}HOUNa@9(?C@GjkP)fn%K??(@(3@k83 zA~LfOvvF1tYC4;j3SMv)DIzDOP-gQo*OGZ)rr>OXI`7fG$J~TdS=L^c1ab%IpV%2w zoS9?}&n3=IW?x$5`7U%Y8j4+-9^|0|@^7*OIuOLgNQ#@9oi<{ZW}GGgp?k(Q)|KChnc}U) zAeC7}j4&G`JIOUon%Us`Og^DU1Crk5YU^Lau`ufM{F8Xg8Dc156UIy*O8pQ9l&r_b zBs9@WClDrIxi&+|SjdtWv;w@m4F8sSm10l9bkV9LmiO6Ey!^~ca>^yx7Be(kA~mLM zVy4W;P1FDO;ZGrP{*7fmnzMvEZL-Wq2)YVoMj?7&W)Ws4CS`<^GQvq2kvS3Yd);|x z$wExUeOh_nO*7k63}l?cR1AjqO~o-zxf~8qW*R5=8C{(bk8>B4g}~vz$id3zI3yxm zfsJOh;>czZM>LJ@Omd#Efu{8OJogD3h;AnA_)q@lmpg)m!#fUe;ovT5j=sfu51ojo z>&`g-Xga;$gTNDhHmLZI9;V|S`hA>z-ymZW2J3|;O9NuBqEF27zwlbJSgP)S; zV4QO;le}+fNEMS17oBaZ-W%7}W|LA9l8z-;-TcUvSe5ukp9iBv_Jky@^nu%`6HHTE z!h!)hqY&gzDLIHyK9Y8{q}-CJI7-g%yr~zAkk;-)R5hQkz3a|*EsW0h9PG~5SJHLuBqbK__?%T<>UK(ob_Gm1S)ergtG?DLfb!L0a+Q{l9hFNQ zEXVmfn;V1YI!Cy!5Bm%zx&b~LLpw<@C5`PE0h7l#OdvXv zfiMInnCKnQ&4F8cOn|8=(Y!ARTWrF1lFvbq;Y9&`pP->ix9NRLgc}X%Oa{@L*m#?6 zhEH0ihp`)V^R6}WAh5d;+HX#KU0Q$WsFLYlD*k835%z)hlQZZSW>M#EaWEE82$U#g#5GUgJ)t$^*zm8EHcwH);-}8a1l~;a zC`7_yOi@$0KMN2q1Q9H3Y9+!DSIP9ON(H!#YyQ*(T#OHtjC0E@L$d_7OwxzjfA#1; ze;&t1{*5F;_PSh~CrnO%aM0^a^6kmCJN3r=sQh*%|P1?ALxb3Dz*wA zg^_WiNL_E3A;xrK$GpZr)^blFAaYIYfDQgN*pDVmZpG(KZ8x#@4_Wjany&M0$Wn&{ zl*5y@!;?0TgY$WT^eL;nb;Q2PM1S~}+h7xdO_OQ_l(aym{YXhxn+hY82UNEq9s*6@ zd7zs{qLl0iiqErkRMtV1vHTc5i*idBTS0JN#$uYw$U(3y8Te={jR`c8ECrQU9$gI! zC`l(18IE~rkl|2yJ>@aF!W;qkNMbr+kcf!pDTl{--`KjlstlgX@JCbB$>T$Cn2gZDL4sQ4719Dr1c37cg;3_{ z<=yqX!0}C=9JHiAA_FuZd!r1JQ_g>Di?DRSdhAAenK>*+81W`P-fYwP&1+r5u^VYP zb|YQiywNorJH<5|OY5<3WhQT9fVb1y>pLRyPI;F_2RF0jJ(k>Q%X=}$<8sTHtoZHP(EzYI_zP(wpk)ai{QN0__e8)dkf`0xu1uE2MS*Nttl>FJ;+xN@$O;f z`_Ur#m^@Mhc`*#cZj{G(_c((*!3&JUR?CyTe1ac72~(7?*a+*4%=;OO1{%?APS6%Y z4k*F007;pcQ?+BBEyaVwhZ6KM=;9JR2eK05uD$-mMm;uCJh8F|&O&p8^C_@eH23ct z(2I3)mCkAUK``uJgrCE@mSHWzDcC&*q#c+7rNFB4Ct1qIa!{KG8ZuC5HeJg=PxtV^ zASBGg13d#c!e_w=j_q`It|ziNy+bWHPi{ZZ-QPagbR%fS?E{eiX>!0Eu0{gNOdUFW zC_dN#^(}}o{hPXvQDR`)&C`%HuNB(j4Av8>yAFT_Q!{7cXZ%{S9N%>zpghv zysz$1H$<>Qbyyp!59}R`-#lE`Gc?#!t?Ny6D*r`noAn2}=TvkK9E<}BSaA>o0LD+j4?IvYd>~$dW*h8@gAn?$`~-V=ayLpl zIrtCww59qp7Uk!b{KBE{@=@)II`lGb$=^9}yGqR}LIe;~nh& zTkr>qQk6g=qfA7GL=c_;%(Z{A~X>9=%g1v#8 z2$2M6Dajr%TAPg+xd+BaQaMVg5VQl6&69Dn_Hh83K~sArOZAhKTK^@FujGeq8Ex^;J*mmbO!a7Q@7yumODMP9+_}4@xoyXlI5+|XngO$owbNj> zN9PWV4~d^uy33<~WA7mCXOX>Dox{;T5ggmnNM4uBC`hJV+}+nVaMMsH*nXM-$0m%{ z@NsAimjtikT$6{I_xBGBVu>B%AU53;bku{`V?AADQvW!ztZ(^RA zVXB}7UTnzJjJ^>*T9WAT7%*3XbBd2ytL@DDw?xta*ymD+oWQQBDJ&&3xk`CdP+9cndO#rQ#lAs=G?pG9Xsy{9NH^5tvOp+Q2FV@D;GY&4S4cSz);ct$mP6D}mbu|O} z2CkuDL(K-4WKB=n9Zd~8+uK@T$E?cN0hw1T|BQ1n>G0jCcg+!*T)`Qr^Bp6ASz|dt zC-ujd8|ConcDQGz#prCls%dv~+wP6c+mTmJj@B}P{y~xlt@PlauVE>M zG<4Ai7-ktkCxJj9zfg9Mq|Ab88Wz#aCx~Nx!acbA#?7I;sRibLAX^n33BK-D{f%3-J5Ul-CikGy9 z9K$;@AB*7*8ZNFw^xKrsN^I92n6AKQI^8ArbV4QUs3IKfpC6 zO~HI9+Z>bGRg(m|Gf22nCLEWkb>T;$Hxz!cE*~YZ5q5gZWBFB2A$kZb=n5oJ z0lN|WWe*wGPi%k%$cT*@LxE?|(^Dz)a;6`gwu8sR7tyh1I2xnE%6aT8sH^cE{-F_jU|%91YhGfE1u|58Bz z`I72RlXQ9KBLg#Ftoe7>LsaeManhnXNK;V(i2jPpU6!7 zJ}evYe%YnrsbPp;?}o#t6SC6WIa7i0Uip!Gr2-*Vtu81pK&0pixd=Z+7nwB22)d(zHn4Umj;vsRLD~jI77APIxA+qjKLDK zPRXTE^g1p-h!vcXI()I=E<9$xENfw2`KYXp!4xyhB(E;YTkVuP!TAcNV_jgvZxI7YiKx{P3>d4e0 zw!<+#t-Q3Tyci!?dxYVwRZ^lu-!GS$fG7?=+%L<{N_7`gTRRnz$|I*_UEKua3Nv?W zj!HCEVD8tSk;|yc0ZoWM{2mU^X*Q%DQ)1~$QvV``B$iXPSXIdebfXPR&fDCs^=Y(i zJS`2+$O1ES6@-?C14+p~{v{>)6i>W#PyWmh;Qjm?$zoj=4x}rc3^F0*1^`U8M4lr3 zHPmle%L|lvXUh5_uthH`Liy`0*%-m=21^?GxyhDI5iX4k)@%u|0mcj}1Hn;9J0oqg zb5F7OFhcuhYdwp@DxTgiraG>v~7BMiW z37!}j`{vQzx%=XSI}YvD@b8LX#AJY`BTyF9(dP`t_X86UA0&C1rO^^$u;;?4PqGoV zwr=to)>X#!_S_zqrhuKTo*UeJb$&j!Ay^66do$!qoxFHIg(d4pJn5oi`-f{gNz})a zh4NzS?4~1!)KYr^Kk+7^1qHZ$3G7nrvg{3iA_M`v|7bv2-9I~rj??M_} z;q}@+gTm0wU}z$3RSj%h|B1urg=kyf;r-41K8_Uh$doKi>YRI{tHR8m3SHO=UD^sW zbSyG@v{$0V#9{`>S`3`vT+rjzl5Wi|a#=rK;SS2H%fLb(eBRxaJa z?ukKnK=KpU!Qja}`3B-fAx-gmElO3Pz zv9uHHD65cZ+;Qma<5WTC3+7Zo{Y+w3X{49Gn9cYt0?lWvfDo~;7{n*Z<{2cJ6^PFe zH0_~)6;9r|;><7?0uUFBwGXkVx6;8_1xCM=RBmICUXxWxdd*hg)fXOxRkBzCY@CtE zhD9$}`6ZbJn%n4l{so~QDR8!cM zAU|EhRbkF%H{J~(uu0?YN*1#|rI^dpi#at`5Pn|Dv=`NI=NTyvK~iYS_*MAV05R@F zCnLiNEHHgnwCDndwAnZsl|w<1F`G78l}IVyq+}?uYJB4vipM)+T8^=Zd10(VQ1D?? zZ;D5@VLfnbl6J7+qGC>AzW$W>8eqptFOW0{lRjO{ox984q6z)4^#Ox0+U zb1@u@c#8uPZl{|9*{<<8#`4jcQ?(f}$An3tEnk^D@y~vVy74b(+OqfN_@HlXOT)fY z6r!0+i3|m_xkRA4TjGJ60e0X9kQU^&6lRrErW* zC`K6_2;xO%xigv;4;9Sp_UxlyUwjnHF8{_o ze^#WN&8{V$8YYsoZ<8`vNc|$H1eVkAUO6Gxb7^{Su2dBXtnTryhEuH8l4ZnQ1BpFX zRupl0(MW9V*km;wo2+&**z3;g9DL0<2S$K9kJFD9z1IeK>Uy7d&s9le!v(>gt;ej# zsR)yQckr~8DA~5dL5Gh9*8C-IhkE#vX&sZGNok7E9uSy66|cFX{24! zGX>JcDGt8uofCL{k5?Gq0UO{}iEuJ_E+D zz=>fj{JE#`2k8hr@`XPa%cplfgpJ^IQgmE)SARyFqjF{SOX5H#V;rWO2K?Q)P((mD zfIK4;X&9&kDFi$w(!<{@q*HoKrr;-fpOoNd5~L-ueB2a04FYKz=mHv|t_H_~zbl~$ z#^1dFioOBAZ;&_ZUxN3&8pF_;z6ZcsQ!)lEk5{QA&$||G`Z8LC@vyq*2#8H3eUoda z?;zna&(h8lusp17!{ie|Um#O?G1g&bXx#W@I#(mtl?=P&hK8AxnZ!s2!H_pFe3)wk z89!sBVx?_Bo#R^1=8u#I%j4O#ylH&1dgSy+Z4lqVsDL#4Ag@v)U0c++;=C6UqVGZY zAUG2DxXa0Wb8BU67zPqtV4z1SfFo~hMrVwRuECP$ovuRO=?cG8;skF3f5tpYDekC7 z#Fcm=O;5O)1n9~Pj>JPL|726^U_rWK{wns?V{VJU3A+t zmjGCJZgQlX-}dm*LxbtSxx#HzDcv^hlKp&rz>;2@sQ+@gfzN#rq$1oF@gTLI%uynJ{RT^WM0C6*?*NWU$IF%keAF6}BSH1~ z0rWxgdc-AT#9Xx6YeEg{{|IK(ERc*DL{mxT_Bl(^Dv-m7t)gVtICq{AlQk@RWPT27 zUkRcIC}GH%f`|2VTA3SKW}Sw4DPo9Br*$B=N0dB*_u&^$rDyM>5ymQUV96n}<$f{Z zkeFw}jM(}k?mUxB0)duweGOeE?}Rc$@>I~$+kZoRFNY&_uivFjO+$mok@v`*j=Wdv z4mt7x`Jf{olDi!Fu-xsyM;|PsZXefzolPjbYmh!OAz7Y1N(dIS!2wZz%#lBndmOn} z?!$mc)+k{;mLczVt8-03K)N(LlZ3lH-m%DvvqxxIE#&TFR4_e8Q1W%2N(pexI=98CDeBuQ2RBhJj3SGJi%_^@*@_8y2YyNRX)81Z!vzIt>n#v@f66lYdV(mXI@47G~ADj4j zM_!N@9UPUOu;eq2d{#aOV{woG5{xNla%rP9-yEO)2um>)iIZyq-nc`fxbSY)S(FkkFT|oo}8~7XIrF@ zj+r=!Bb&p{2DG=aQV#=_KnfRptAMB?MKvIe5&%08Q93(2uoq$;ZZ+&d^Gu8qHhZt~ z7jq!&A7|yW562AKjCMagRz^C_kZOV?-LB4g(@yc4;sWzGbLVUZCP+g!tdx(449ht6 z$z#4y)_juM)U@)nwC(DNe93 zH&Lr>OR{ecBzZ4}=VR6%lct%LSq*e&YgYhAOnglu8SLRzV5-153pf@bFgc8OKiUxp z$y%^h=vt5X9|cNg1FrRWnhRb7nJtqIYX#7n5RgB400F_xpo{zgH3=)1COnLGf*~q$ zZ`CW1UmH$yL07BGl(t}Do=oX7^MM!^a-zX0rsWkRUfgD0S=F%T9+K7J@-U##bKRHa z9wXXmtL}PMO2XGYCnd*a5kH@mQaUk2a@HyB=37hA@r0Dh0FYh^4tS(4e<>N@Poqi` zaWJ?G1-%Q!;V=I+!m*yI#&%SjY~@Q(4H%>;?}|=7B~!>b&o`CH2U=)q2$l!vf}9Ut z9(LQ(&(T6n2;7ufG`8UHBK=FTAt+`yhp7m`hIJ~T3lMurra_6oV^~3|>V}%)Ha}bu zo)Oq-fwq7N6qc<(JDb8z!LLG6+8g9)nRQZTdv8RKw@)gN z@*Hya;Y|ge8rQ_aFH3(c48t{WqN2)V-bq=YwH{{GKW1~lqoZQHO8 zqmVWZBWWE4*8qv}1|*suZ%0kyzM(bnEBe!rxu8m^V=W?g%KK53_hY2-m;c%mW33(IfMabXlr@$k zXWs}zHb=Dsu6#Ea3xj1TlTQw_B4F7F6{CEGzZ_=U62ojJ7?>PprKU>NTJ@#oq||z2 z?TW-$^FjUGv9`=KSfU4)Cybt7ge2#p)GNTmTZIfv#=W1TAvB(|G7vNf!$!=b*W2kOk z_AqD<@AmQnHtBM*Ntd~f?MtNBBAYZy#^x%rNteq(-u2ru5HW1hL2^hB(J;y(vPqZ8 z5r%?wlvQ#wFR+iYTwcq&*YN^2=`xy0Sw%A`%jAtka+|!V2okZk@N&CFGbziY%c7-} zs)VJKDtRZ9c^8-+u#{rSd%-r<+dwLI$~`Yy^1iV$RxgY^X?kC}LO_z8IHFqSsEF99 zLn(>`$%JQQ`vl4np!#S!mEjY8?aaP`k2p~4Gl4bykbD5Un_+K#gp}W_Y!KDi*OBRgV>=o z`6jbE!Xzf3j9`Wh-(v8KG;e8|cTc>#f2ej_;HySvYg#8d=!XQk#mR}ES{8_zC`UrS zBm=wB(=QoO2j>4Q9)IWO$Vdt@_Nthj99Q!9ekW?B@I>-L4Y^kGvt+f85w`$R$^%eZwdZ|ar#_=gJG2P0?v3Lk{9|H6b62yI37|rfsT^M zZz8Wr@MpM8D=VR{lrUOBixku|%Lliq;5k^+1-ggst!eIotRwy=oDG5=aTB`)nGy{& z1L_tiwSu7GYq!`BYx~N?45Wkh- z8yPOTFaS*&ZcEtZ?l8nUw+zdvj5Yz~oJhTVXrvWEFTVtUNj}251s|iRGo5VP_$@QX z@-QhDw>s016bk}F9WZ|3hMVji-)RxVwBaHYpW&uQry!xJU@9HOsb4=#!;9&#IN>D@ z%Epb<=JL5#F!7m4+%oJf@PH=jtZ;!^*Q_MV!7adSwje#x&qtQ?p-jhLwjju)Oa-rS z)G6-KND;9$|!q4U`rrgt!n*pSql**R`&OnyVJ}K1(Z3Zj4u!~{>CRul0z#1=* zF`L4{v>t6h2GI)Ea$V*0Q&P*j^)qJPFBLF*dkW;v`<+bOg4k4W1S%>wO88 z{d40CWEA`*psnW&Vsg*%qtXC2_KO457}hekX8I6<-kx^B2>)6Z*}H!tTuKU>SUWZf z&^aD_)$l0Bb!@@zU^uljc5Hk+LWxx`yfl_>TNVt zz(sDr>Cp8JAC>Z|mm~~SCniJa5!X+nHBuE`lmP$w((HITb-&V8|E{mZm21gEdVj@XC zEPN;BBKk}62|;KUm}BQiHf6knsUBp>gLSj9!(VJZCyv>FJU*_+!BKK+~eSLcca9%Y}@XyExH6%=-RdpZUNaQeu|zMiNX zLlgKeKw!n#+Rf--&F=GAvdO?nH6WT)d*nv()SQ>tvVOdD8Xm}R8dz65298U>B9O0h zCi+_6l(0YeX03koxZ!EQ7yr-N-HQ69z9w1{(Ly!#9tS@I7! zuo`K>1;oCL#hUr~ayvDPoR18HE!85z`OtekM^nD!CVGY*gKD>F&W%gamh`Vn5wjtVBwsL%vQ1ucB$tXgut{9|VIos7(rF*E5Mm}|Yp zwK-^r=`G+Of$X*9H;%kcUT+x}82{{AI5g@(&A_nl@9wJ~+<*8WOrRv}C_;#0ww{WE zhlhqM_QWgb>Y`$JprXfEpV#JA&Ru^0FI2EO5Au6U{?(C#RM|Nw{g(WjLl;zz3<I14Vl`!MuV2o$*eo6%IY4px{b5 zu+4C*Ll0i8$IW=F<&WcXKQo%=8JG^TRLD_zf)SmY=NT1N`D5@rqY9M8YT1q|R1rsR zmp41|4yqN7i>K+RBIS(J$*M2IG|D-hL`_~j&t^+cA-tGWitVL zUOa|$Hnlas?)F7lZIME=qT0^b`y2d~lh*Wx`$F#R2bntlgDO#g!DKprOC zK7<41mU!-k>;TF^as#e?2z?6#CKT2jgs>(8QGF4;<~kI}o|WRR=mc0|g_;N+N+828 zeNGB+8^!G;iu2FHeyaB8pekWewvZCt$#^*hFQ-B}3&|@jiyor_#`Lb}3<#)Sq_B6E zC*1{IfXrD8LeMF1U0l@)VbE;I)gcUm#I>RYk8_S{TSpL$QbB^|isqRV1`vZ5mJZ<$ zw1r!xq=X2%E|4V~;l7aYNDG1FAVM}F=FkC_&y1Ut1IC7S$- zY(gWJ(DTJ=43o2RaaZ&bcxGrZo-fwGO@j7(u_n3>9lTyW#Yku6GJ3t(a7yaW$VQ{G zF_|tAjMoc_^2{)Q3*OxhD)o=b)z1ACG{9{?@CMOq%`StN^E&IMD!*b`jh4?vnr=wg^8kNmI!bs zY#f*Xl0l@*bN#BV8hvtqOHZ zw;Z$N&luqz27^CbTkhlI{rvU-?;hm4hiq!Q*zz!6f7FtXMPL`=c!bDjOCGo7iG=&y z2(}sspr4daL}=E5k)CD>CwK?(vn|iUuLysi1w0!9>5zpb$NOR=&!|ukrGAUcSN7 z{Uyu(SG@bCMG3S`3A8QWvE;8|4Qx|W{q`LlO}iVL+S;2tn_RI~!$AMgaCiT(MqF~n z!%bt%3)B~yEfK0T#od2 zHa9eN>eU0solPzEn~}ygH*bF14ZntMJ6c*8M8W*L4&o+dVtXN=vZFtyB<}m%(%w+N zy}e`iwvP7g?G5cM#&;OVo%W8#pj^;}irVsBWSJIiYyHmp&h{N`jkbIbEs*xTeOpso zXG>Ej1o)YvZ)@+^uDzDo^iMiHE&8?{EuBqn0JtBWgyL>XX%&=KzYR15fU^2!N&}?( z0G}NY`UN!MT~B%W`}(@~Lt^2;HAC;dTMXZw$|@d+*yY_%489m$9K75oel(&^zrId- zQ7AK*0GWY4J$Wt%&x40SSE5J|voC3szm^Uia$kQ?yo7)=+sQB>h5Qj=v!)TW;)pxa zw2#0HAn;t=8WPJJXgO3PBbIk%0I!>C^RtcG0>gmi^uIxVEJFfe?hcM<+B*b{^bK?; zL_ZA~S|VkDxCS6R33Z^J?qJF)E6sW>M^hPsc$ zy$NzrwxVP&|5X%lmq6VpP^yF;*eDT8QzN2@C%J`4U@o*C!m8A_IkX8%MyIa+zD8H$ zO0XXu@@Pym zn0bOndPx4sb%3nd?Al2(?CjBB4X}r|${QW|7x~u|C8a>0aX4zm>+j^>ExJ>NCuP?X zmDh`|R8%iHMl6i=18#ep>S4Y6ko>nL|KrH-bRGy{64%mAI&{#}Wdf0flw{LG8?BGN4W-#x-j;vvjnxWo9H9Z3d4<7FC z)lSrF2=b`ukHdjAj0Dzn6Ex)#T8^?5j1j0B@B-1NU{ZYKEHWs9B6VnBJm!`q1IN zp}3Cal|?VsKH&ftH;O=pbMQQ$K?7zC?uRdw2Wzh4{&qqe1UP+ZY*sCT-+s%X_?pqT zNPoiEBVC^yX$-%S`91-5pfx<8&AlmE?0OY4JRr|*s_`@wcn2ZZh(L&Bg|ckOKAS-! z+e%uRZ9KNQQ>imPc%-){zGGNB>n1!zXYRfx7!f|PMo_Oy4UINkoGs7Pu%I{+T@4am zd-LixuDEm1=rcVTh={M(@Ubq z-^sO^Vxl1nXoRsJ8tBy-y3%ho$WW;64uXjG@PK(0kOJkNx3MJeCE@8&W@tqJD`b1_ zdS^yA&ec8(YAYs`3Tf!es52%M6sU~2Dc(H{?}QjBMI?1xrO<>Q2(#?Cw7hRI@fIf# zQqZc<)}s?q&%456A+$Wr08TTl8W`@HY^Ijr)ZU@32lsVo=aYlC05r_$(E|D$qk~jI z?{IhycmkVo^qvHx{l?7BR-XI8?umiDL$f>PxfRcCzUOvuLALpxufTJM@A+~(clw?g ze>+(5UV1z6yvz4|C7!!{&sX93YTxrUcz%uV`C2^h_C1&3`8wb80z7y7o|m9b^yACA zf#B1>pt|%gC@uYK82i2Y{(3O_3&Ga!Lx~UK%_hX7SG2m*qFPidP195beC^5{&nenT z=vX#U!sBaE z2)uB|WF7{2cq1yp3i18sbq$G4oW}TMVGZA3oO44^ z7o^MaK6-#YB{k7nc$Q`-;U~Hr7xe5hh-g}>F;rHDguVH)tdFjWK~*#Fn5=@3=pukQ zF>}tyYN|EPHoalG?Nw?ex!H!qS$|6-mlS*LK5hN_tB#;k;OL>rv_E0C^c&oDjyLLc|J{X*MMdD09(~MyET1aATx)_VzNIO)#o923 zUW-t#MIZ2&t0fL{Zq<8GbFgVJYo4@=yHh6)}zHPs|#1h!XJadxo8<~PRa&TfUuTlnRTQC z1z`c!W93?#w+_X|IHGc_9z`+SxPu5I?zGhJ3a>l<>d#TElGC#Bm_*=59OY_z8mYj$ z8}wouk(L?h@4!2p^)pm-uCJnVbw%g86`h-@qWOV}{@zrSrsd{(6>UmZbb-I3irj?^ z1z6-Oz#?6MMQ#BWWh#IbD8PT40xUrR7I_8Olq|p!e*wY}>D}SZ^*QKjO6Fg{w@hpt@py=S{uCJp>{07(ZWA_VZm@dA`SInXgZ5fKoPe(<*1^ zYM{eY98f28U{W2mz=@6}vs@o@(08Pc`CQji%d{jLsBNJ0aL<8Fz45-iO@o62-~=sT zu!S-=K*i_YB#;9_JkZ<^7vUO(LDJaA=kPROSB$;6N5-cGo2mfbgAOxmoSpqlKkqc+ zwQ#LJ8qP3z^=(}MU-=mQqs6emJL>K4#xWhI2=q_5p}wUBMlBkfIxpYezOAGJqoEMP zOO;H;`cEk*`VhF2V*Jtr%hgyMDLcIw1mX*yjyxlw6Z{|aO*q_+Rp4^{h>a$kpL~QX z-*AC`d>YZ|S#k>2o2l@_vkdic#h`}J}W z{#}BAWAB}yz%_JTM9!#Lg_5UcTdE?W=BT-Rn8(Zfh+3c)!uyI^6j6)S5?fUksVcS9 zR@Jtuu~n_5mf31KBduVlmAtHqsEgEUTV2fGOA6Jcs*aa6ysYJAovqeK)MaXet?K!_ zk(UNrHQK7lR-2f{W?r^LV6S>>k-A*9*s7HoxACFfQrq}@MUm=IoxE(1NTu2lfisnz zEXpoR!9~n+HOp2sg{ZEw6&%GZSJ&9;HT=Dnf#4`6PoeIus@qa~Y}Mlv|E^VgS$l|h zTh%^G?T^5N0unpG=U!%WJ?~%=u~oq&Vyl8l#8%bMG7VVj5Pxs9)F59D@iJ_y!z}#~ zUSJq8Pu*;(TPy{mh`ZD*OTErku!`8F-e9X+ZS_V=-4>B+(Ix6l>dkDYD{S=^*6{X- zdaHUHU%#D~J0iI3EK=`K1H8PGrF>VRoK^4Uhxf1s5TWO(_iBaXR`otxy+5Kppgw4; z53wY7aoq9WUR!;bFYacPkJ#!ct9Z;-e-=^qsC#+2&r*=4zfnEFE`88a583KrTYZ#; zL)Uzazvz`m_HY z1^w;26=djlt1|@~ZZ*Z@)29kH+-{x<@pP7#Pe;`A>IGZ9XsefO^%*{WmY2`j>ht{l zb6dS^t5?_pUx=tLVrby*OSXb!Jx_hvR$t+$`>L(JW~;CB_8YePOI!Vwt-i^!e9Kbb zw$yhl1z9?#V#+dEre(Y75?vqPz~v-BbPMiHQsxe3w27M{_boSX(*(aI4Ldrwx3})@ z0IIL4qp7143HbS>iEPRnn>N+&XxVNg;y$teRXnOe?mjgbfWm$w>sPWY+o#=|np?Iv zb?k0wYTLYh%kJj3-L1_nFeL{e!d5V~yl6X{8=Km9Z|bOTZR)7suCWGr^pFH`b}-16 zrsmCCwxdAm#}JzbzqQt1xqBm^1-qIXw{Kw({5L5W#QPMw&6A#+R!d+U%C+>|y!2PF zI^+B7wJY_7@9gT_-qZ>vVA?wm`v8HO{$`rNKpH$rep=J`gPP_**Z86bngJWK?~|@R z;LDvmwh@5P)QC~h+1|2)Pz`iRxjQbpZyK&`?1d)85Zr-arz|sN2!b-e1=GS2Pr$O& zw~=NfAvDj`ghrZ$`v$uY#yh%cUNHw70nsD9d*cHE78Y2#0giFtqbn9J)zMnJZ{FD5 zzxSrzz4TjIsNZ#J@okxzZ>bedi1Ur{4i_lk?CZU`1MJfHV0;kd#%vg{qM197w;JCY zC;>vuOAE0xLoHl+aYn|s_cD;OTeosDv?-hmd;}ZYmGF-gcXVcWM({vkXYc-g%>-34 zJ|ICFj-w{Pz0P6a(0f6Uk8j2l+I#G{jR|1n`o<*|GQY5B)Y53VeV{GVI~e6!<4<&C zA~S>R;F|Hr9$mbTNssnSFEx0uW6gG?@kak7nKE$=-DZ!fTe!>{=|K=eF%oU+Ie_sG z|0E#FwUt(aF(}jQAL!*d%7J5HUl7CnpM&(0Z#QYFPmA_y+uYyU+t=5NK0`=sP=)Y) z>m@a1P&3JK)`2eAz(LC`CIw2rGDV3A2Q9~$Uj)>M~?bmq!V(+IvnBhTyr4ayZ^wjrGDb5pQ@i> zrOOp6VWPX+%*A7irME-aRK%FA8(YkS-8b(^?rsJ(k&0B9z6pZQ_+Dx*_9oCv6$drI z!%;t1zi`w9Hrqe4*?#G$zfl0^5EW80bhy99gd23XK7$CU*$M4?$X`sMINnW^}DtwgDx2{^(!H*^};%8I@(jsV0-?XqkgCU-BSPIsQ&~u zW{l&>FrysxU+TXd^*`$OqoI!+^#}E;1w(@&1$<5@6v}f#;ZVL4Dp3FIgn-$}4h;e& zwuwDj;e_l^A)YF_hbp@D6JkxS(0%2pzE&7!S&b7aV(Lz)*l25pCdj{x1@ZLvp^1+C zM1JaoN~q>(#;=y0Cp`OMY1aUwP$_eYh9)_oGAOr(%2kOIn#{W?yiDbw83Sz03B^Lw z#*7pTO%Kh$!VrS#xtte>jS&$py^|kT1}EbMN#96o|pJ+NZ+sx)Qk&iJqu zn&*V(hZb=EJh*>I+ZKW$UnjIMw8#oAc0x=HT$&_x;S)+lFhkB zOXgW)U?4$)zzJO%s&nLX@_7w^3#|!F!pK1{)o6BZ3TE#5gZr>!rmUM*Xsr`k7h3Ox zE(_)1P({Y9*IkKaBeWq@?}Rpn8oZgHSMu!#1_y4UV4hI=#7gebBNaWGAgS;YsQ?XB z0haTDimk1iYH&ErR?Gmm*6;zGP^0=irc$WM32h2(c0yb9g3%EN>l5dmy%mT04)3q- z?XLilG+gI|nnT4_XsZ*toNG-B?JJoH+&fU)-0p+QEl(C3Yba0!6+H*K`}fC(xFroA zh_k4Hw6U(VVo3?Lh1#vqHVy)qjsKPWojYM_1GEiCUWXIv3~hHpJ9ybCUv@&fKoEqk zbV6OB{B->L$f$NFbQRaltJzVOS?GqG&^3Hqlk14`P5K%)2_*|!1_o}xRI0!Pt?)29 zXjUEAT~dcIlc4f$g_|! zwCT0nBzNXog^c6a-TyTOxE%-J8@zD`9sTo>a62GL)SU2=bwayY=$M=DHo`J>=3W4d zaPQl|pgGPZKW#g=BI%X3W~+}1aA<)sfIiimmGQOWfr1+J;MT{LUTUo7V!7X^-JbE_ zX}a0tHfZqP{N*^mCASKLICGU`$Eh$IsM!eR@Yp_6lJul0VB$3XC&ab+n$kONdvi^< zTShz_hS&(U{sW%&T%M_69_`8Cq=o3gIK*Nab)O%nv@Jz#*+qr<_`QimUPp@gw})+5 zba6E8_CY7jE9L|9BN?HS0p^&Y0oHh4KJ`dR;3*v!mZo#brket+*yNO<*50|pU|Azj z(Aw49*4VzQlbr6v!^#!dVv>)$cfyBAeIUec2*-`c&{rfJ5z$?)qt1XvjfbT}VSL$; zh+z=`qTg{P^SrR|(=-ILi&5r`Ga~~_c20mwN+A&mlQ@h2)$;&&%oXYw#6r3w9A^N} zO+%__fpKF;16Wh9Lw)nWWStRf8t#R91zXD(+)Dx6jSRX|BVd%%^}aIV`Nx3L&!mJE z1de9Vn#!mlWiavMg1gTMVoc3Wz;C`_NW$Wh0P=4h|3P!Vw3`Y01K95DHQNZEfJ& z3;YX(H)MTlhp`=kZt0KT)U0K!Jvd@f!qDj%?$myC%~xT zg?f%bd1Q2yIL7cz-Giun0a~w_uEMo#xFqf=0lbT}Gr=U|6;Y?J{4-;kk%YGwE)KPf5Q*dS@RvJjhnd0B|Dh0l9NW zdozpW5h4I#<-zZmf`#^(K$^cGFXH|sh|)tarVx|Q_?{oe^Jjg}9|bZVtOkUQ!It~W ziFmKz`3ot}Uz9H;z8}W-zmP8{p1*?Uulk<9hUc&Qp1*vr0^p#@>&)@Pr z--zdL`<`z?{O|alJMjG1zURkKkMH`P7vcGPzUN{*f8X~^y9qz=Jx{>%4}H%L(#Ppb zx66-x?+4JPU?J+Zg)~9`LMEVp!GzMk5D(~I@DT7j6Kw?H1FpZu(_!=!k%ip=?5fJp zb3o?<`+i#cYvyACeAeQV4PUi{L@%m}Mk)cD&y%XC^{yhg0q$Kcl|T7mG#h-96kBSxZgbwGog z3{ha>mZTiNM5z^`%=7T)dPE74yWj>ng~HM?@)PjVvY=J90X)4>!CBxvXdt3~fdK`Y z-id{yfEh0a+8VIxSEO_)0QpM@$gc#D{$gX6he&2v<00aD0q?3gM=I;ASbhx1H+tQr zl7xi_1;=0g4lvV~uu%c#J}Nc5J1fh9_g)cQc~VwY>j%D*852gn?Nq8YaQtgP*dt}B!ES}$M&s^8+G z(|?E0A^CSC3Y&#)7D)j9vr_M+3f7MM`4vPUPW&vOz#Lb0)eFbqbm^(H(ttWOwx(#0 z+-$T*qD{o2Z#pTPkI7EnZb55VFH3RE(%o>cY$&n$z8S#$0(zOo{nk1=W-|=bJUZf?o|qW zDz{QJZ$(_#LG(_2)yFh2yZ&WuN2(qzy^XImVz{1n$q!dxG%s_<&&#rqA7KRwL#X47 zbP@i&g3XPN zud`t%>AH_eXUsk+-E2vB9ACyecN|Bedt#B3(sNSwqQfwhPe>d?`GoAND~c6iuKal@Gs;xc^B#&MqOJ~>j}95 ziT2ezjz_7-A7?W0Td=C5|L7O~AXJX#LQyAvQu>Kh*K@bDIx#!(InUFWQF)5mKAZ$s zxINp%B+#>$@mF`{LG;~{MBmNkyyrLQ^hBGELnjFLn3`^<4OF9qUXQ8#(dXkKcaSMq zqI8SGt(CPZN2W9qHF0V5#_6YJP-o!|2572}5PT>tIILT`sZ$w+sZU1gE#Y;TnZ;Gn z8)ux6;XGM4Lz|L9`@@c<8-6|-hV4I<;mhQ3y@_#C#TmIdEcF#n;v0Lcc;p<0f;ogJ zk~KM~JxCubh1z6xhnBo`C*+o(ZrM9L-Lh9W=?}*WqOUzEuRAI+Z-sn47DG;Yu84I7 zD56uvM{EjPV%Xr`a8ho4N#2OT4ZV>wavL@QjPf^8UqKetS?I&WTKg6+rReP@IWEI(+fJyi-2^iOtJKA+4i=)=KND4n+oP-85kO6+g3tq0 z04r=M1*gsQ>;&}GhcFf@XV5$!f_P)1R7KqsE^$*>S~*?Q4|m*~>y1Ps5s z^k{{NJv{0)&KtOs66ILoro!bggmTPaIYMqJihZTfE}XnllqE{B+KpeyQb1u%mtywx zkS;@Uunfh4GL);yZcUo8oO5)qLm58&imWnC@#A%+q1&kQG6lqtTM$q~Gj+qPhuyim zyJkWS@FUO3hZ)bC!Z7~eCOd#cImvq5Qf;9p=4O5;a(b{e`VbV1 zYL7{I^kH-3L_f-#qfiK1iVz>e-y=xpxLg-KZa&Pyt4BX0tw*J`GWu8`%-U$N2~(sg z$>SgrBVMwO_XTzvKYUzDqZ7;vTT_{)|3ichxaE8WO+<}?v#5z7dK}(GABQFyHq$3a zH9T1L!cn;gPjy@gFUeb9#kuF-wq_-^E#&s`qhg2GQ|FYs%TH#4;!xD(y9)h4owUYk z?zkk{w2ItCRV3bCSY42}+A6oo3m%ervHWst1?Y(|H@;0~TZ`G)GzxDA+4t%XkeF4K zx1zOjDKs0N^eP1?gj=bXu{D!={1iu$r^-|1l8UX-CKM7oWf5 z3pxkH6}lK-I^- zr?*w7Hp+arQ7S8A)+zZU^5SSg*}SItKA&mgG1&A^A%9aRTg^<==_?=*`R_CK^KwU5 z-U)dc%^W=er49v}!+m_lJm#N}XZiIx^9W)9fk`muM^AQkSzFTkh^E zl?O`pVk&9kg^y2_%KP*)R%AS@4W;r0{R|?;eg3U}w#@T&rK&HrGgd}#HmUCQn~`w zJgG1+fLdd(A&2Udc1zU;$iPz=n{}HU?ZYHgrIzHPDy7Z5fTyC-@ZcQ#0N$DTt8RoO z>(C$|^EG_Dqyk;cX;1AauS~3l7k%{}_QHf%KyX5?``=5e_xHj?7?p= zaCgBS`K2vTM4F&rW@>^8@sfuyDr~8ITNQw?M?%Wxt3qBPycF5W;cu~}CP4j3ehFJt z5xEYPph2n#Xd<|EoS?A4Oi*QfR~}K5)fC=MwN%Vj)0pUVOU;PDqytJa(}Fds46`){ zb%ip|;AKZsb6fNF=K7ZAtC~PjgZmlO<{<^7z$;BN0NK#Iv$+Le7a#N2WnkNCb|#CF zKu|U{Z13FCzROk>012k0*xb6gb9+ZqeQR^uW?RhxMlUT$Yg1!$y|IPa)L|>GeraK@ z*wNf@`S#{kDB8`-l#QP3tF$O~g{|getZTB@_WHwa`(E z9kl{(Z`4Y)%25}|T@I`kyxqeh>PeIU6Fc$|wR&tQCr3UiAG6fOj=Dr$>Zm$i)~K~W z$ouupM<4Q*TIZdOY2|`P8=E`pH?}mnI+?ECo~1T8s$OlhR0DrkIWV&` zWT{3+H7Rh?rzM)3kih`5&;bW&v!k}idmQGl~5(4N2Eveb&LI0Ak z+F+DYC+oc`tI^W<4s8T7KIpxkRHNaNt6F;d58u4PymizS%&Vm4io?AgyShqU?a1Tuu%)hX)N9nWj@qrRb5u8HkWVEffiVM!CRs4Njng1+ z_wWHn?coqAPr`MRle@xEJ!-F`;u!z(0A?$g@^_(R$*_ZQe`xuL+~aBj7~5!Vhx_`r z4fI0hJD7k5JG9wPBc`{|u<2n3Ce=~fjNoV*2Ty>XeHnFEKzt99rx3a=)RXRkDbjr? zs657n;C@~nWkC}_UbSBVIFJc1uZN3~>1Ph0M~Vqxsa{82uWqnZpF{Kb4xI})>Y(bk z)PSQ7aRs}P`DR8$FG$wKMMMYmI9;%xqXrdl2f95x=fM3p#P=HDpYM>U7rBu^s9Amf z7>dj_dtwGIk)`=Py+?Zcu=nlNV|@r?9h;F~Apq2zrk{*iRRUcLZ{&O##(Y6gy&SCS z)6>dphE&a@Y+$lp)NEP?ZI^#OA|$a|=~04U2thoIKy03iFn z54W2eu*e5HNuZFjfu~c!j-vn%Jr;@Kbc~x_m1LZZh_p>WO|a@G;U*w;fjnugZ@`4b zO#+S^7$H8wcoYy7+jJYi{V>)_z@;CYTA+OSfBCC@md$nzz!qW$Ax!I3KYhJ zaGfjY3n;0^_@2Z2lPIaZd>kWc+lO0r;ZWxt<#=JS%^9%RE;`(t3Ujn7dY++W6qj6fpeE(WpRVXy>`;GRyTVz59+!;R+owRnD=@A>t3euMA%Ry@Da_k0_k z-{gCKGoIh#d%hjdZ}mN21LhVECdls&o&P&vK@>y}?xUoD^e z5-z)7)(~)psu=uh!FVU&4BuJ$ImrL(@|S)tmj5D6j-uqx3#6Su*hKsM`3aeWI?b(l0uT823HxUD1`NWYvp+XI*5f7vb^3R8QT7HU%_B^|GH^KC4C)5G?YNG`^_&yXmOR#*JHw=q6t=h`8AtEBuU1pc&7?mmvISsR(P>LYuM^+y^~I zr65d5!co~u2tsohmNqx=ZYwiJVcm?8O6H6&_h*c%Z6*%l52vg2z%Q!$T&(EDr!k)X zOg@HFNP~)jr#wd*q(EJ(y3q;UI8Nag|H3#g9mV+KurI?CS;KZ^)l!(=Z84pAOoviP zi(&6^!)`!GE)J`J)oX<~75(3)`@j7~c9?$Jc1qf{Bfu*vmp&&Ql{24{PK@lWsp%3K zcAq;7cDm_qM8NG7E!QnIee#m*c&e>hw~JlvHjCE{JJA{(5z$?^U_@XAx>C`7Tp_Fp zm!aM;b;lza-Xv=S0jE6Z=IV#cbs9iJsq1`<4degZ@f2S06}U4QVqalChk2rOKTp6f zCvONv;=eMUVBKcC1Yg+XGf>?w{9UCDx0ZN@TTjZ>w2#VlxCpxn{FGsh=CAlF66QhE z&8r+CnO9+D^ctm3%4gS>zYx!^u-)|rXkQnMWIymf{$EZ#35C`|#Ch8bRZ zR<7fHH}3NlF#y+Nrte`Nb))fn?vtzX)-OdJ_MVpb8Nr&(1=^j9Fsv8}d0_z~P#jvSW~~ zX%Hp(t01xtdB(q+q4w!ny>BiGmhBZAxI zT1$3Ya-A*R5vh8K+aAI82a|!l0&9W$hv8Iy@UAlJx#T8&4IPf_- zY>~%vL~e3Ocv*CHubr~LLA%$n=rS92l;K)FTmNP?fWXw>;z+G58;M!Aiq?5&Ktp=S zD0pZ+?BN5wLlrm0_w;lhtgE1h>$kf6V|(#FZAU@ByaT!>75xLlUex&BC3J-Sc1zw# z{?)r35N>xm^f>6y#t29 z7It_P!DF3XHr^VU1W*K;Sr~f*d->DM+_v7E<9*%>tYT0cYsfZ?jiG~D&CIMl5C@$m1JA&Y8;iGCWlJDoSX?nI^^f!mz!1eB(CJ%RU`0AfO!GnrG}wUbyD&HUI#`M7|}dXuT?Ls4$mwPKct$gX08C=0t}0b^CyEUweMJM zsXDvd0#>=~tQ2;YTa)wefXDPY`?#z;A+Y`KfPO5F;y5}{$1TB4v=o=gV1PuUlW=!Z z%1%o8arq^}pOnc*Wk83V!gJjVt0Q@U0!+T_!C0#Q!+QKSqL$^ z6UtU~&=4_YUE<4q0U{xr8PSEz3#ZIQ_%(UO3Qx;op!9Fg!?E)eQ18xZSpvnM(^7d_ zs#5#K23YGN^pNRAo=?z=lLRNb>Sv_LgibM@|A%jX;Qg-vxW_+saJDtnB?Z!jpeeNX zZG{+XwYDsa!2bMl!pv6MvZ@fpT5ZY25wYZwB8;9oLPFQ@vNj^?NTjcm%PiSoNxdZ- z!!O>(!$OHPSkhPsd>;sQ_@lO5nth5i(;M70rY2l^Sk~W(}^-R+2ljVwtbR-D& z4%unRE(?d%3r8`hkjs{IIdYX;og!0nWQkm332gsdE4#6=H^zr<7#=uOk&rCo%-~43 z>~RUZR7*%pq{k8nKjX5`bqm=m2Q0bXp{F7Tetq_3qqH*6iQ^;0mk9KLXOKGb*4ll> z99hTajb`b0fKWWdn%+1%v724;y+kVAQ-%VCK1dIq@FqDTd0gxlUxGkh!js4nx!I!p z`L*&oOI}aknzuUO^Hz>f`>ca~tVHjHB5%*p>)~hwe`n8NJl=11y=LvXFa{c--aF*@ zKZ8<$tzbV=CJjC8wx&N8NWiQ@u!M>=j!Y1Nd1O~ja%IXT2LJ*{)@VD>SuLx23gtv@ zCbZ0rkc1YZcYn{6+Ydnz&nhomK_0u7 z5kW7t01lBNu_9cqdk!~zgt96wcr3cT5VXw~P76q+VlogJv;dd;;lT+Hh>gnwb-FC|^ENVK$M zIw;Gi)_R$Q7oihUhL;uj1<==Y>C=tt^wJk5Jnf-G9BP_nPJP!2pGe&Y?*CI1#jo@ zGS`xM5sn^P7TU7NlEs!Rxq$SF#T_sOe3}IUnq|uS7KK8R1KQ)V1IBrkYdm#mU(LRQ z*SlE9p1p@^5}|4W+yxpsft?TsJpsk)QXIGfpRvWHnt^dhWI8y@0LYYvC$MCNgQLwV zZ14nP21+qFikV}avJ%}01nAg$d`$Lfv(agRv%7C09XkYq=f&3e@PUE7BN?qR;61bB z__+^*@qK;3K-QWRu(Jit=mf`v%VThfGm~U60c^0n{YM6Fz&Z9(|JmJ*X-?=SqQ|iC zZFBA`EU(3S%5r&~i1PtP3+5%4R<4;*91=nh`_Q)~-@(~kWfYPWNOt(I9DfW(ZYzBbnpa-!KX#>E4nacG-Llm>D z6;(7VlG|EQEwG-dMF$zyiscT^sH5xo1)F`W2LT^SHvx`?N&V#dl19^N29{A>`6F|` z|KCb8yap=`J-Zn~Zi1fQC3x}(IXDNz{Up4}#w_Eiz{Q4w;>n57$;BoNf4^943b48m z#KXm=&@48QlTzd^HpxVMO9m;Ex-b6b_B;re`A23?avWu(O!Qbv9_P}ubXzIEhpKLw zEZ}8f1e7bu59&Bp+ET^er3_QeWuu0VwG0C$Pnj&Y1PTIrM&lT?T035sTt$;s-vGzOmD6Gdp zpN?CzC6c-I8{>WP{qSV5?eNfnjfeN`ix2vxCz;XkqtQ_*;}e@F7!b&VmhGTz5$Js- z-RCq&0#bs^Rm1>Ulv5rYaoI#MX@>dSgW`B$v&B7r0U-8{+$s|3?&*mS4b5M+43cx# z%<(AG%TEQm1Sm$~@PN4o!4rV!CPH|I2LlAGN6YO5txkv##$QPZClc=R@dsiBBa$$f zDOga6&?zE@Nmarzv`e;;l$wr@47A1-P1FJnl?T%eK;DFp!j2j4&PqPciUm=wrg#S5 z91AH-Sb*K`7}AZPJ}$|$4u|RH=Ic+gICGK^LS#u2e!?=AZDQtxAjHU$kiTr0;kM+u(th z9zQ$f^%2=2Zz#mwt-QPu7!Y7(xPiRMmTMT|%@I17jsQvfwg|wpcUbZcU@k0bhk;e|$l@FP{Y!p<`hT;0)0S_s@Ce&1 z-{u8jzr&XJYfHYHX{FBrP*fUNW$2487e{>K(z8x%`eV@qcK7!!!R0xyL1+hhJ`y22 zWvxxIPcmCgAPE{$Hml$$OC=7ICVKnf;X{Xq{X5~jY$+rIVV_A;6`qmoy_>i#U&xtl8sU&kWn~np_a+TC36oYf}`qWWf<8Km^vfJb%jxSZ8A|1fBag} znZXhJMpRzE;&69g@9-_#fCY;W`>EBmiUvcv8?S-*r5j7Q`;U^T-vmQic{4QbdNl9o z#KAdG9svp_fk8BsJ;8>6)m-zUcjQXAbN=7#y$O6&)!9FO&dDVA z&dkliKmx-$Y>Fg+vIGr_U;qhAK!RZ0LP!RPgd`>bw6)c?YOU7V)-FP8wYC;fYh782 ziq;mp@B6;j?tT0A?cVzPe$To0&b_lh66x>#|39B!VD5VES)cQq=R9jcqhHAH1JL@dpRK zY$0Orp`I!{*Er%&;`a{Rz2fj^@fS<{)q&yA-z@QW2i{u$X^DSX;@^&V88SmD9jRoI zB_ob3hD%DBij1x0NK5Rsr0qyJmvrbc5)3J}(U|hCZ0*~zwv}qML8-JQ zOBsz1-<3P`T;s@u9B#=Gj;!PjT-I1}lmkNo_!5kE?1F(_Ykz;QB}XIXoE!_cH4aP+ zCO9%BCpvK9GTD(+q+`jcjyyx2X~}7hJc|v!O2Bd%e6=cFpMa>&j3)&6p&>N^rFNjk z^$0;mK$6uCOvPvL3P$E5Q;0#BY76c_JcyICPR%FJA`~5Ywglt8upXk3r+8o(_`0y1 z@vIDp=U^?9fmUwRt50cbXJ_}`z9z^5u)EZl1cK&qLGTRqj#=ggV@#~K!5$9q^+GEQ ztq`0OS;1X&O+Br(0u)H*b70;f3w#F~r=!p|cSzxH7&SFd4^KK3Rmc5y&c6B;^Nj2! z1W$)wBxGJaD5_+j>|58xnjdT>?+#g8`!+7E-`KEeIaXBGXI)RrCE`-E8QtgQ;SqInJ}K>& zn>U&faBh$@yK_H~q9%h4!V6wwx_cMnqBf;__jI(SFYfPPcaq4{Q_p>DT2m7uG{gC1 zr$!wIV-<_?mUqF}fy}M$u5BILcOy8g#!XP`4!~fzP-7jD_d}FFr%;Mw2IL$@I9OR-RPY~9_TM)ile zFm0A%EW;>wz>!-5Bbn2p5XElPeKz>Z)QYf&_qn7YVRWu6I+&r$voVWMALE{!xTa5BZLf0p8}QVsZOx(O$`lM zi;QiLh}C3W1H205w=B@W+J$2b2GUeSx^PyYPkkxrBrs<2R-7oU^o|n ze-34^=R_%tQJuyaYhlWbBTP{zKQ1bciD6*5Yi0ZqCUGV7@S&|W@_;y_`gtnbmsLL} zMwxd>d~t~3P2z~GP;o?zVQdXLbR7#OZJ9n#MK|!T9s13tBPQWY#fmDwVx_nm`76vMP)MqTkSF%ttk3p#$qC&aIk z(Dw@~7k_@xdmQR4gljMq)C?peZGMyqpm^ zsQfrBSz@}WA48;EcOrY;-kgXtL8ua4w1VEvW0-dr9)L%51Zpv##mJI!ldnQzPOQbp zL<9O@6$JjP4~aFKtMU2TL!xnWbz&XwrymvT>FWctt+9Fr8dd}7M)fb+jC_qDe1#1U zB3`~3;5;JSF}JDT?iO2xGyh=v(R4&?d_q)sh+{LK;_U?eK1=#@{9iX*vLCJEk7A+> zE(?>P?&7Z(4MSu!LBa^?HAk;td=$+eMrltXhN(T=qVI3`{2qmkE6sAJKqfh-Ah}zx z9N=wVcu*UpQwLa2&G&aD2^H?9s59MraZkHmXH(%#3+Od&t&m{(o^)5g{y0}hAgPrC z9B5bBbTY2pjl(p*AW>eharDiG5y}$M=O`{^Ik3xAG7}84pp|vOvQexd2-bJDUQ35> z^TS=?i^~H%h%lGJe24)udKXnaI-^YOOdpFB;G!6*bkjtEPb6lFt3sV|5)L2p%mT?d3-K2gcmC?7U;gp+D1^VE0sQQ+ z%v1b7fFAiD zb@m~KdYC(i2ob*A5SxL8ZSYUo(ZATkM=sLOMc>mcQLXjQslPrfs9t{32obZXg+7Oe zxnh<@hYB^K)&WI@Ear=I9rXUWLs|qtJ^^c;dJz~3jvoxG+>a?S^Atv2h8pmA?3gM; z=Bj4=Bw`K022N*WSfK%~sNLZ6N(ab>{f|b)@S|W*R}^$3qF?|B;OJ%);R#RB4y^!1 zjZguF51L#fj2`H>XP=HeAz=Q3|JZItBI`i=t=6}&myQ%?ZlT!}DaqVIw<%)jTSVH? znZ)4vO4}DZUM9FLh5nPt=&yxFNaLcG~-oq#Fjmo>_`*?K^5BKu${umDT z@#+J-`e01nFFypofVO-9n<04+R_pRX9v;HdDIezH!?t|Hk{_`o^vy=e$6Pb`krEnb zBjpp!MWGelw0$?pyr!+m`%}Ex#L+-;>{G?mvjhAIcwD^2fIP2{ZetC4UA@HTiR9 z{|g>ovgI#r`70LkYfJvdmcM1yerL(wLk~_Ox{EFUz%T#Hl7F-%g3xS6&!MDaw)_*H z|4&^0S^gz1|0@5+!{06WkEqxp|H%*k6_@`;pWtwehtKlxIZGlI&31UEJpKnj5B@AA zF&;|A#76KTw!!7{L0gToRnk@frf1X`W>;#fv9=n=bReX*C=gOxR4T3}s!5ib zjMgcTQMaq9ygGxa&a~7tX!*&zSms$#8CTO;TyxeHlRSwiK)42o~>#vH9w}#Rp(i%j+rlDlNMTPk*yZ<@_b7z;q#@uxqw&owpzyX za!ajXBQA`pm8!u~t1v2RbzD5DU^cK_t+CbGm}*q(Y_+~*$?+w+t4o%A!CWxKMNGTF zQcbpmwbJwQU|elfrIxxFk=J746Y`*?HrZ;ktuA3*n{5TP(Q@{xtuAA0F6Y%1JY2~` zi>f)iBz1+jA zt8GRVvQ;k=^zo{nW3roH?y=QgTU}$TYi;!^zIrte*YWTg9$ss!>v_I`hu7J1gsom5 zlXt5(@Sq!TBd>0<)y*8fH}a;Mhg*O~)SGy?)l#>`5S{fd9{ymfH?v~5Tk0)r+#QyB ztEJwSk3RZ+{G;PGYwxC`JWX_?rGXGLMD)dc5AF`*t1_RjB=zmxnm@Z(pz&%D=Z$}R# zDUh$`&z4)TP)aV_hQk4|$f=l1d2~$py%Cwfz@p&yxk8l&I7+~`!SF^G4)XJb)uA>T ziHr_&6xjv2CNd{ILJ|ogpFE+J8ujO1B!RyEpf2A4d1F&NGC>zRishwy*~f+jmfatbn6m83sZVzk%2dC39!gaUAZb(T`QAiK4KZy)?g)bD8R+Rn0l;tyQ1Q&494 zz${>{G!ptSF#VyMr>t@#h#UmE(Smf0GY*U__z1&;SZg0diLQT(3&K;w1;v7J%lF8OyS)-YE@17E)%FrU6cKmq%{v=xSfl z(c9O*wza=)2b4q%CXnKMHxQP$&v7wCXl}XB!b9#pG!p8piqW?Vnqu&8);kJ3J(w7P zrb0eA$BKeX{Lb{6Qc&wCsOue8LkOd=ZN}?RKz8k7;D(UIeIOqd#=EafaeQ5lRRDEg zJPa#EOBe)vzzWQlplChZl!9FR3<{Uxif{>ecABR`UAgtU+n5cxo%^xO>)(QxN zq!@s}t&-JA_ijkTvI0x6UtnQYJfIHb0xE3Q%|wXz_%LAogue7Up( z!+nr%QWu~rTyAm>!D7wh&mDxcWX&^w&3=+t| zhaoSgRpC1L?}LUmVN7|FUd^&49&%&xrH6>c-c^eh@T?_|e;vL1BZ2eIPcdHRbl z)Y?JR%EHhZghkqR*~Yaipg(w07-5=*uB|Xc*oe@78lzO=Q?3kQLHc$itbm-l>#TFyTSO zRP_P%K}WuwFUnlxK6{+;OGC~*8@oYX=~cIVd2erbuce-F)RU-|dWv;Jq*Mon zM(FLeve8n99Cesk6!b9J)jGyHl1r#*up3QO~GnEp^DYK9Mb(!HJ6rsy^%)fQxhAeQP#gq>F(cho1;2}`}`s81rE zsQQ%p^ed9$IqEa&v&0rFE%mwlNGK5F)KQ;TUw{r*p~>Q+EnkfsgmrrWhdJtt#DQPJ zfnkjuxtfP@a=at=%4<9T)`%z&cy?Q+gRo-m?t$T8s=EgvLz#PO7j17++8`y>wxhM9 zE43Bgx>NdXZdjsc$&yo9bJR`Zf>WQQvjc_xNrdf(?rq7(t`P;}$n@5upn##s#UY zSBp|xu*Pj!;J(+lh`_79uO0=pvEIuk3*TZ3!i@HGVB-alc$@5U)DM8))eqH=EcIhY z{Y3rL>qo6F?pv5T>Sw^lKp8)G)GttLd4UA)FUz>JDcz4yxauWG{ZjqPQNLCXS?V{A z`mOq%g9x|)x8JKjIO@ODAG09+;x0ElN*ct|?(Gd-ftgnp8ordH{#*UYQvc(qKdVPj zRfIR`!djE=)k8x97PC8KD~;I`-V|!3NlX33QGZo`gZ4vk&iNgu1M52SRqF3qP>t2c z&(W+uaIzS#W6pdf#x#g%rlbBr{1ietS$jxbKg9CI;K)Cg}i z#ZnX@uw19^b34zNZsd!{Y!wx|<7Ltm3R)eq8%0OKM@8=c5l$gYZk!|)L+=*mp14rH{ zZ*t^jd5IKD3gzHZy`fD-KFfEf$S#U9vt}-`KyFLqQXPldDT)yfbmCc2yvX6(-3~(C z&v%MSiI>kQDwARr_!`8dp<)bD%G6g!Iby4??MbKd)gc8NI`sII)ZQH(Z97uCTCW8b zOH=n*W8+ZfKrN>&$jiUZSswBCp>;=rb~f_K@ig2)&WRpPi5NZ$UV$rD?*x!XuGGC z<`k6|RXFkv`BtZB7-?xx%*M4^2DHMYi&K;UYAqTLY+5t|n~S1KTEhqI1H*H}&xQtT z@Bjkqulm+5MwR0BDAnU`RoVDJU%1-yB$!fK(9)jj=y!^$ibkH=MSX5IPSL0$=n4%k zc=!;scA=p-7)8Q>zFt6=-S{xY7`68HwqDCl0(v(a&5-$BgJI`tV#Br4G7ir}rqr&n z8h5%DR&fZlzzfb2vlx`MfP2=VI*9i?(!&XV_Fl|2j0>9{1}ksu#8$A1u?`5Xd;37* zqn2)?JCjkZW6;c$)Kr#nOYv(`XRd)2#m33$d_Z8_lkYa zpWNddS4i+|4EKU=`H3EkL}nn~NDg`y!dQS9`9_^GUs zZxRP)i@#ye70mA~qi@Vd^&zL4dRGnfnfKs0S0eF_>cIDb!K`>EM0$TP=g)$YIq zZq>>uo;1@4wHn;#_((IG!cT#Dfa)95*TB{|(xp#fmx^v(pkcrjgKK92_0te1%aFXr zB)zGX5}BacFx+O~VLD@XUuj4!fA`m?WzDG3-qzkOBPR}WsDY!V7IHcfOot|isBQE& z$>0#T8^h4i=Z9h+p!)Wpogfzv)a^#W;P4>@$OG4&f&t8Hlq{+F!*SKt`)Mj9@&lu zbLJQZro>2dfQYwY8-OJOyOjQGjkF~z6oK1GxqX!TgcH;wDZIdujbRYTt&GmbTde$n z&%4fRr7y*WbO3%>e9;Y-#h549UR))V*WSF;0ll6qn$N9@G*-N;N9x4I49_5P2YpniSKDDtz-&6$fERncwO_KPr-BW(RCWgZ}b_`8-0dUM4us| z(q~Ag^ceywoFkM`;k*b}=SW0jl#Knb6qXaPpAqw5@hYbm!5(7zF;N8D@yJu6n2sPy z5HQGk3T}k)Aj$+VkcHVeO($G8$5PIf2m+|HqnCPSS2BGJk{b)!2)PFC`%V~X&=tWJ zSkRWd2zL{ar{m2<6A)0o^f5jPdm|VLZv?aEmsFKZc*lPDk|v2qGBNtF7}GcdWx}PzNMpc{xJv$TFaiMkPnrfuio4tfFp?8Z zxW;3o#^E;}?T+q4#1Vuc;y|T%m}tIJl=8XXeE=g&j~#a)ed>g`6{krjLA1 z4Lp0mRYMI<=j{`TW1_AZPCm{%EEb@&Dm-1dPm~`Mi}-ZmVX;`J-zO??doIdVN5%Pw zf#vlz_*-r{zXLqb;Ox_sB%-!U4j`ZvBHK64I1y_91!#Zu5mAp58jsd5t9can%i)`( zLZ=UW2QMXlzg?K~-2t%~6Xsm${Id9Dpo5|b5yL!i~+os_<5~GUg&xb zK%y~}F9xFq4jkCqHIJg_BA8!sOzSz~TzD@x=Xyk+XCH&9@3#FRx9xYJN$cnmi0J^&)nL_}tCC z9W^Eptwi$T<~1MV=_q}|uEk(pDG>pE3NBhC+;MLqmTBeGR|ZqXIf} zID(GDaU0yWpa4V`dSQl}eGP)s2>f78%-n$|!6bLHM@%AZHuo?l)^<3p!7SQ-NbJD8 z9w9m!@Nnlo5yQis^oLUyna-eX&(@X{)moKSWyyVFce1$Bnq6lnZFFMiKGBl2bw<_G z@cp~@i8V>v_Mt zK3oR;NII8U%w6+(8_T)X51cDc^9gf zs{W8j<2-M_xDwCz(!~!1r{P6)S;oZ=n4h{UtCJ;1#j7AGhP$2T#YpW<=+$V{m<%K%Ugh>+7kcNAcw9TGR2F_&_aKjwX?F_*>dUI!-8S!O}IPb8|bt^sZB7q$eNUxrs$ z+&J`lb({tNKtb&MMpI9KLQUcpR@GlExK!ftn}C}6rzo{?tGELrSb}FnG{wz&9vjTj zIK#yp6L4WL2bY;A#jO}#I~l2Y;n4#xf1h(YR##l}LbCWc2BZjBV>S>zBYF|>GjzrI z`fN&V9&)L-4YAY+?5ZwvOYH|zp>6JZ-PXnomSn@+)}F;Hx4AkH>tom(U)zPPet$Hge4Y`(E^&nbu{Z>iYF5x~+M#8LN!mCpIPR%Gm6>_~YW8pxfRx z^C6VI7(Y#7rUTgxh^HfV5aQy-v~H7o)c*F2(1X zrTE;V;yqG4T=Xy!5x}pK@E@mpz7+SmS!M?iq2#vEt6j3oeRUHCg!{3pO<&W|-j14Q ziN1k18xixhGE(#GePUxxWn?xQa!95%k|fq^Qn@w~~bjj>3j?%O1B%SD{LzZ#JRTAJ`}60DXS& zIdMO$Hie78hic?eaX=4IStANg93)Bp7>3|MiP}uWXAkWYqXVCn@w11K;KNd|+);Yr zeL$BBHH<>N)azI2)ozuxn<^~`9=a@P|FzwdyZs0Idn{QK#kt@a_&eOBp9P6>t zclYW2SV?7M7I9~^GP0NfY1!*P8uuRIjMItUk5BYPSUy7 z95&S^b)@}1k>ulXkuAxHc{Z*+(vAevlZYkk?zbZpq!;Q=2*?Y)f_j%h)6&M!(*?sn z(Wy5y&d`(ck263p)l-zU~5qm}X5jQgu=xFG4UilwTum~o3s4~gTv0+Biq^%_-znhoRA z9r_ZFW69FG7)K?JQF+981+?iE@HxP>p1>}8xE5XZDhWS(dXA?6hn(XhfEnOT^7-b( z#}11Zw5!ccX4*@6oqUa(`jalyK22nb`TcRaOMDHQcuahvIdS5!c=0&s_)o6o#;nI9 zZR!G3`BRv>7<2&dhQz0Nt!MRTIIBNvZUMd+C_uYr2%Lb2NuY5}MlBwPjo-Z@!3?;r znHfMwj6m;``0|5-#5svUt%Flbq4C+oUggk8aC-Po{u^QR9 zx(LCg&a4qLp1n`rG$VV7kez`g;sgf3el~KSC`(#JN5vO_#pD`U2Opa6Bs`dP0{y%V zKaEpy)+{=l7bNYX*?QFLlZZEcM0}Be^`e*uZ}d`Jy;CFfw03_g4bR)+D})D<;~I_!_Rz zCm>%e>rC~$%N z_p5?Xd;<_Xl&@S;Yy|q02;Qy+f%R=Ag3ICS0lQFHb|H8UQj$hL6L6u%+=FEiTt$VO ziEC^0l2}m_=R_k-(E9?3**Uo=q; zcdg%Rgon(Pz}?^9Cx&CjeE*R60gxo|-Vga|^f9re8R>pRhGa3?q$w<6&j5?`))^%K ze~f)T&p!#$i)N>PiFV3+865G_IWH>%4J5ZRSE2UA_Bvng5KLv@&omz+f!u^!@#3}@ zfs{=}ehO^Da(`yZ#m>R!Fc_B53b9JFh5+W&m~+cL1H(hGAB}8M)%RnblG}*Zq^2i+ zE)fFn7hcD`$;as*K}}iLI|Ci}!xzP?c|QqKM#HT>qd|k0eJfj;0>7O-b3OuxJvw%hu`t=dmJ?6Jj#v z6^0VK0-o97un}=Pd=fgGa89Sge_qR;E}5SAOAYS=oqfA}i<^E4QZxNre;xR%UI(5; zTvsAovR?iMo;^tqY~KIAA1n;_`X6TKB2-FqbL&K2oR3?8ME|)@kMF=$?6b=7UHA9t_|CKlZ|S{MO=kC4Sx2pc_C- zvMf{%>w`tEh{Q~@4~Tm6bm8>JrP2>(n+Mgd#Duh{`@IpNfL{y-l3sl=UN0UmJUlTP z4Y-|@bUUf^n1ozLMy8KBB#RCGFXcPsyWC{8=t=hF^lB{@C`WG%msldO2#|6s#^d6n z($W|Kgq%;a+49{!Gc)7ISK3Ep^a(N5>sRhB0HugIgxvyM18;%&s|>ENn(&-|4dxVf zh;`0|zis;}`jx){M0ae2m7TUG$Qx)JF~*H!U%0i?4%sT9GqPq~{nCx=HngnYux{hJ z`gLHQ56GE}???lB5D=`oP8vfod#j*+-`?E-UydEFNc_|>$0A*50iE$ek21p6oJ6bH z)z8gpvlP=a0@bj_l>0%TgRn`+r~?L6>hr58iirSkB00!IvBX(8bK^%gX%T*OgsU{; zces9*70RBQc7`%7#gXG~k`gL7Z(M0rCJ~e&z}_@Yb2FjpUAN|0PI0e$_{oMhVy5y} zi_A{Z0qeVa`vaYj;{y5|wge8a;$l<`ErlG z-g6CI*!zy#`&ork+`rKE_c`a37Kqs&2SBf=cQ;g^3^eBY3e^GZhtr2$nPa?KpXG?@ z0#B;N@DLREYHqIGgHe{l({yY5G6eS8p`z$|_{n>*Z z7XSw4P&o8+9xY9yucj4gHtg=|q6OWlr;T4vPoFnyt}f_G_s`Okqpzc9R$KS3UAwzF zpiJ4_J1ab^dH_wWyW0^`&(9KOZ0lQFjNj;`ds;g>S*2xKiQKqofF7;aVNii-4TL+U zC*Mpr1vFg&D23u#x$19&&|d`f61>s5+L<+=0<(sw-^{sTxXO4r1T7JAW}N_M0a9C} zIoDlRrX2Aj8)K=U@U&zfD2V6auzQW1Fzthtp$PWM5o2rj9oD_C~b>wo_lz>ng@7fs}z_C z{g&8mi#;rPZ^@FM-EspP?0fZ#LRfiC4CKSLtktXHaE^~y#IF&rwZ-*3-@qrYv&HLe z@dlgmhZl;Qc(|F(dZQ(7iGg$fCf4Ux9uSTA%?w4{!Z^e&j6>Wa-fA=A?%SE$od`sn zZ-NcL2is5=%_Yfc#(aluLS66+EH2O(y+#w_X=5N z&2ok~@TpET@I+l{ZcH? zAb~Kt35CDxbxqr5Wg#H1!OZqOj(D%Q+Y;|{#699(N4#I$=ZFvR>Vx85biKxL2GMkM z?M$~5L-D%?2LYy$^h4r+B_43#|F_9ujA;k4p&!aJQ?gvZkSN`O*yzbOA1MuxEdqxjn(d zla_eO!A|n9C5|}asQ4&ygGCZ7bK287##G9+l69A}x|Ac1iKqF=GthA~Nwbqc0iBCJ?Gvc$3_?-AWpwCB^gI+Bi1oZymX`wW$@~C`jUE*@gOjuHOY`fMh zoG_QmR%Q*FFB9l6y$2KU()CkEjZHUvC7?R25UFhp{MeSD^IsWNFbq_|g`RV=`tIFb z{hDHfiZlHjg|TyJ<4-aEz&G*fcK`d0HL zZ(G>ETCup&^MRFR7ZISejG8I7B#2hG3)=G88Le%-MprDOM@yf7XxGF%DNQ{yNr!B( za|&ae{F@lS{nl&y)7oqq{T|Sh^^~wfHWsde?Xm{`xgo^@D%&K$m*oNBklt(vio!84 z%~)&Y@ElVOqfK8mEoh77nS7wwLeyZ6X#f__OJU{Gp5D3}imstv31$~;h4&oa4a4*Z zp?4@r4|mhLt45y*Frz&md7f=F6e8)+_B2TpYCyFwhgNWnJ^uuo%PyEknW-lJzn=E-7PZyI|S*J0+66^lU*Qbf(jZJ;x7HCog| zwE%nskowec84g|}6dzv{#qv>b{fgHf6D7@K5XX&-KnD^^dj>ddwh>+9({*0C@@Y`J z*iOht5foryWKl)MVu%f6^CL$@ytV|P+-j|3q7-8OvO3$lF!K2^_sL5tV@E{!{CE{& zzE#wfCQB)pDLo{H)s^y5qPC2u;kD568_}Eu=d7~%n5aT#BNL+ziDYFA;oS}iRC8?P z88NQ8=$IJaoS0Bq_C8S_sf>-SLM2jQ*o_bq$Bl)}`UnP*n|fHB(R5gxSy#by+o2~= za<7;JsZFv1G0%#?ZUlq-tbJ7Wf#R+y44so?y^<&lTt^5*AlpIm8gSFR^y32Q(SyPC zmF1=&iv>kbR?y7whb$<1vVvxX(^Em=-w#Zu!q(YZDs&Dwf3sf%U-_7rL*2}|PidXp z*+(d3=3fRpVkECz@HmLA)Cj!2eGG@ExT-k%j(y_QRS^@$FxO*7H`K8hM<&bwq=kun#sS39h77&xl9fu1yT zdO(yx=b|q002KQY$Lof3f3}vU36~hVbs9UE}Rp*`);cVslT;rOK+KUfx^| z>B-qtIwD!AACU}KW5n1~Ta;&4cfj$;@^X#}`hhCYIbdlTGc;{DMGMKYzK-o(t(|M( zET*%&yN3uJ)-hnZoURCBghL%c4AEBx8$s;b>XApk3`Qw`Ljkz#_+d3sEF&X%7{vqp z;@d9EluQpYO)ZfEs}y^;J*}Nn+`W>!x|0DP+<=0V0L7b=&McxJCwxBZD*|D-yDYT+ z7Z~GU^jL0?bM6D2Si8;VYjCYMyBQdT0!UO6MOk)cmPI*UBMFkLh9OA4Bj-Ec} z-sYA*P56 z#EpuJCoJ)#EuNyT_n{bc>yOytD9<0Y#j%)pt$5lJ&+zp;yIggk1{5Xi|3j0 zW0rWq7Kj-&+&ugQQ=Z_P7kT)kEk4Ebr!DcB7!>n9%MU-tC!gox3%vcJExyE?FZ1Rr zyh0GExcC|mUyorg{S8Ze(-z;d#kXTvtx@(_;yZl#U8en>ExvDyAMo;rw)hdxKeokB zc>XC5KeNQoW00Wz!V)hbHkJ6LC4NO=&M*1$*S7c#&j>6P7r*1x?``pixcD#eM@#&- zE&gPQ|FOlNW7xzW;?uua;;%ga%@TiS&HllgfAZsh@$hdp9wDUS6tW$bP`pr#(G#&{ zu`Nq%Y4NGeLzIUY4{=L6F{rTo0tZ>jLm4ua<$PDc15_yv%LEU@qp(x1BntS~$hvUQoOb_%1`EIC8cG z)iYQsgvHEt#GAyet_v>1d3N1U>Q3|PMrrAtj+{pen?Mj=h_vBNHti>aZWAgCcN!Y9 z$v1Yy-4xK?CT=wj66tk-fuvf|7L7-ksD+OH{LkPkoDDoxz{_kDLiym^q)m6K6`8z{qoN2f(Xk2id~JN zHc#NW2~XC*4i;g$e2~b~eT`_6T*p2vAOnB9xN`{oJDdHxeh44Vq5og3LK6a`jy0eq zxZ5TsbmYYnu~r}9U~J}EGcNlBpYCRIOJ3&Cit*GUd&`xVfCEFGjOX?xD87O|US>ko zIr2)FB<7RJJ93L`g|I2Fw2K|I)q$VOc1Nb=Hb-v9LA+7i!UGz$gJUugYF9IYYF9H` zdoW#~fd#)Sde|*^xTN(O*6r+9XhF{Bd*HYbp8}}_Q@c;$rBvKbkG`86*(JLj*#mR3 zf`04idbihsY1KitqL0o$@!f77_VBP*Vv)VZk=M#sIr7!8rxD|W9lFg#fy%3)AYUV2 z%l^6EkvA~s*Re9M=iv=RDx)ye{aP0<-QKdxT_`jHfk#)YVx#lE$87Ee*xW>bzgc6& z3|4@@Qa-+g^?nl%w=%(hOow!!TowRY0GV6RbQiZNvUg40@V!_2a z(UM_!jtZ6Tt8$URD)+v_nLz>o%%Q|?uQsgGl!=!(6PhlwI(eh?pH~qXlx|3Q&Kgw$ zLRsr@WV#-m1~&Gzd@avIKx6S6m|g(sW)|RRrs1hW|gr1Rv{- zT)w5tk}%uJ!#-Y!mJ}i;vgU9WH(F2N;h71nOEvyeT@@4`UiGW2rSW#n4Gy!Z>IPmJ zKQ}VQbyae-I4ro0+|@(B%0>^v^_Yko46fDR?JA;7bE700;?mQ23;?Ar*;D9;t9-*+#-zJ4GKyb)}tQv0P$!R zUre5Gl6E(0uciGWLh+*TNTSD@&Q!@6gwunU7-;kk^R<;Wo0f%0qf`R@;}tKtT_Rdtcv5184iP9(~=2pg@-pMMjRHE$EQy?3?-c>X%{|9PB{Z zIl+&n9(45UWF7J@NtPb3E7KLVSkZ%J?x*E^SAM*XUM@^|sQnoSD;@(wd$)L}xC=vZ z7kDTI3VJ`4{TA$a7Peb8Z;P+*Ht`@%(zrp=)z$52*q%5XMBDmtEJmXIy$9I{r z0EgY^xh)9lxt*EObDIV|x3il0GBF)`NC_BN*Mv0QX1E$}lG^v4=M8enn6XF1toc@zl^Nx;Ifl{s7@~xyCrMu01F^^eQmCna7L1Su6o!`4vQI=;{l|oJHV1@g382f(M@wx=Hv(QdvIOZU< ztn|0T`F8m6x)H1^-&#k+{DUK^q8|njzZx_3CbaV=%t)Ra#Jw;*5coZy&vT&c{ygrV z7bo-?c0RZ(K`)g-a5Dv_5bpeu*F)saDM4SGGXcKmLWS?VM)zD7p-0E*GiXo0pbp03 z`fXi_cLDvuh0Sm&lLTNd0?Y#BClKTp&ySiGn{GK@cMCdr33SkqXz78M|D;pDfA#4h}F(A{t_^*IsoldJG-B z1qREz(bc=*c8%wIU=;Br&QHPwg69jxCt)cd@cW`Zn}H!3d>1IWr4$O)u1xRe8!M=)&Q8&e07l%(v zTzo`q;v|btNNk=#pif+aCv@`!RnrNHW&{5w2T8LRHwR*2YDZ9aY9urhFZBw6QH+_I z;&K353`y2cJR&ZmN5YbOprnDD%j;|$uYk`D8&2nvQMiTyq%ChwLMin^D3x9bh-^u$ zJS4WznZ}kwq7~z2`hTnEl0^f(g5iy#ZH*}ro_|ZB_9J8j*|)Jo<(Al9YggJ{@#)$q z-fydoc|Z-1RNIlV0w?;ZvT?43UgZws#%4IKDr0ZF>%BBN-|-fHwzE0WiANO`l~Jw9 z+VQy9by#%41x-BZ92MOP<2u<~v%;7z-qTWZZJxTob_r_JQ&)=P)pcdbQg%rh^lwd< zU_NDaNtxdzC?TE~l=Jlx*y--j?R5vA-q%KE*2G?}Oh-gta6RnjM8xv3`@LMgfFbwr z!So4FiIEQo=YSa9_yAlj9M@iokQEj$B;I=vsyGVzGE1Nq_v^lIc+tg50iQjvoAhPw0N1Q7^sLBN4z|cVA{r0OS4y#e*~N7jL|I zoPpe5T^q40Bln2W<9HlV0cTD3(p`{?xPDj}c^DPt6#KCM{W-|37|*8S`|D~W`pYCf zya)F1;m?1R`5b)a{1tqSZXYycKLYdZ-d&cUUe2|4hrk|=ye9+piwUxIUUP;=?Q)!$ok>|?DTosTKZ-vCTT zFWTMFwsRxIGkHx$VMIAs%(F#p44^ST3Oe#UO6wO`Vj<6qEV0-U=f|*~FR{f^o-g3@ zdR{G~D&%rYtgys|F|1xIEzv-Qge9~yT@{7?-|85&>eupvMq8}2#rh}|s5iuLXkrE% z`TF7*l#Dm?>Jpnqt7~YqdKoQNH;F4O+N-V+Ef(A3*( zfZd-Z?DfqZEwR-RZFDIcy_&sEVVEOkh_ofZ_}?yeSfaxbS3yregaT0Hh*=%cDZnr| ziFl%rZ6S-Bi5mOm*EvuG?{-9w*yTVG9ETYKzU%Ya7Z#MU>8Oyi7%Z`S*3wNYdchDd zl3wP9O=u`8t;_b`aNz}+G_bUsCeDIYumg2;NCB^*Kf=`J^wzf4T`9<5jOjQ+81{8{ z!rBG_>X1tcTaP+RyvhN6RqcrD#B10Vhz+h6H(26z4v4NdIM_vD<2uS%8Rm2(tQc=% z;+rXQLAkfEb7mIWKDvqpSu@3zi3Xx}<>i7e(<t@aA8S3vd*Q*Ay+P4*UQ9mht~h13&s{#rE391}KURP%IHYBpg13t($X5lpPl3 z#m|Te8rBVKu7I6gqNy3X_2Ec60ycD&bo^R%h)!~w_|>Rv_q&UH_q$bI2{574CBPG` zlYsFa_AigqsBY{bF%BhSbFaPZek=)2#DvX}MY@30J^}MOKaYw03>laYCh4#sXN-lX zUU0GC&-{p(Vu<%l2iY*+nu)G5-N}tAx^uXgdPJP@gs3v9vrM~MpML1N>!J70-wGr@ z#qt`86qGN-PFP)5)KIl^JO>LplrfRwVIps#MHv^9c{K(8iAaQ=VTm&>F%2Tr-gH~K zV^13B5Yj=+ay{?7$&efW2LurVFN6N*0|bLTZ6vqUI`K)uwc#0+n@Ok)2%$|}+I%ex zT8f?a*hHb|h=z_GVt^)UF`6C(_MV;{?krCWO=4i@O2~g{3!L4dt}lY15@KgTDk4t- znHY!5(w*t;5Zi?H4^R3DlouWN+JZ+Ym?QCOm;-z=#sL$q+<_Hmr9U#q$-*Yq~x0gq4)h%M&dy3 zc`?v2N{D;y=aOTZ@5PRvzX2EkG(nL#-DQ^I2CR}<7;QTp7|pfBJf5-Ro+IX4;#`Yc z?h-g(#$f@k7RJHFSQJGkFXjQe@1$75w@Z1z{u{>bmRKI6kvk77x%tMysBT;b&g3@1u!GMG`33TGS2@7Th>;ir7AymQLpVPaM=K~?o^HR(X zX^{`KU7nx1ah^+xJS`)E%`k@zrg^TK1M#H^3h4T9nUzfxGO+PUHwRiZm7?AC-3USq zZ7`SMWJdatAB*h*I96##*ZJ{HnFNb#KSHc`rqTC4U&8pyv*;5DCg84?o)OkJc58Pa z=)D!pZaG85IjZA=meukmV zT`q>s(*xt>U3)ruySsKFOe7@j7`ipw=jDBy3XXW56c~?0N8d_#7wiO)k%{DK_Dfu# zgFS;`9qX;Pp&Df-*4~cx{vDWwJJKE7cc6NPBa{oOM$6CLm#)?PtWm+b2Hv2KMn%{_ zt=`F+F9_I#7(|W;7RgtOFH<9-I>dC7h%92WZ1WK(o>7@C7BJ zJB|ps8eTBgK+Ss1^b=wo~I??H{3?`IPMt6 zQ3_`@-B=`b7>pmlxh_N$aE2Q}_!F*8jPs&}Gze`p#jVLUJYlS&OW`79bZQ7?ZT06!G^9XDlxq1m@8X7V5i2Nvl!U;yK?f35>GcGRL@UcR5zt zQo0RC5QwKlxwjs|NZU;qTyx7jt~<=P-Pbi}5!*u__T`6Q@QxNUkP*Vr4QqyL!~}lB zu^sXj;%aQ-O#f#>5a}-~y%gNonG~!e^DZ}eb0>w|MtPOM%ytt77k*TN2~BP`Hh;4N zan4bjpmNe?bHC^K+e9Zs)7udr6~_=Zu+YZM{m?Af|9=zr;SGXWI>uBXYeBMpkmRg{i|oR1aLUkUi7^g@VShOFg!3MYL5etiL{ z!0BPR8gg;~ykeg>J52YR;n#Z|@494k+@8O%WyRW!z@WjD=-m~&`oSoq?>Wtb8G2$sEKS5JC7vPUH_xi`&SGrMJd!zHX}3nY)T=jN#o zcv7MIX!B6)3E5}52b25HR)Ie6G2Ot5RM4hW1fthf?IIFoR z8HHHr>?7iw&5?)Ey~Cjs^ac#@8$c}b92{;NJ}nmjObsY=>!?LCa7{Sp2}TFke;Iz| zL)g3=`SKMHC@^ICql?T8N()QHgVc={?YZO%SQJpg$Z@(iVE|6|&J9rggDDK#0-wAO z=`#!}lYrJv1vvt+lI~3Rnh*sbK*L;e@DL@X-Hd{YC#K6Z+8Z8`0;VKxhx7ry$mpMp z_@4Y6I-aDYqHsJ1$}dcsN_?Zg0yjZcBdCL!L)6A5ie+$!DqJy3$}8{}o?UaI6QgsX zV94Jqm|fW(1{RN{sg9CZeC(AZ0B~vBCi+rmiC$&?9=lDzVyuZsOXZqlDS{ zP(rz{R8rsCwWk&PmmyF18G#AEsiSXqYiE7;t{%9e=<0`F3-oGs!eYzFZZ!ipBvJ5_ z`g1+N3^rtEkR@ykLpcKV-JRXQEX5bBSz5n31X=nGvK!_%(PNl{wE`;L{W2)}FrR3t z%eIcrPBMN0wzNCeekU`fYT$rdg@D+kgMe(ndEHh@G19#YxYsiu>D}mB1pEOi+tq<> zYVoucE6!Shb1x+#+}^BU>S%j!>s~ka^8&f+M+;aH{$)gAc}u+%7|h5|Vb2hdpMn4Y zK4X*^`d9=|Vqy|QAu1D)5INWxE^WrQqOacqX#o}`lkk&3gJ4;Tr^&TmghTP-YS61t zU#TuC8Vh1Z2TI2CXf4CnDqO{Ciz_3M_agvqapXS8WD!8xITxDJV?QX$BDE!BZ?25o z+=U0l<31>cDm9*0;HE~_h0prn*2pIM$P3{vP6GP)KjE^7uaw>j4 zC>{P@0Y1)l118^qFY)|(fu1mTfGC!`N1u37P{_Kv~ zwR2}JORx7oJl!a^cjzd#5J_|L`Ufy^d2bpDihcdimD5_noIRJ4W134=89Is-Rm`QW z;$i|^=xTM0q2tmy`EY5#U^GXH*=C5qSzeW0s$*$8!fw1GGHWCiLDRj+Z(GOq-Mw)1 z1#xGZ8ik|7#Mb)WZaVtt23Epm+|X0=hBOqID8+zO;0}*E!kM&@!6rlupaO7r3T#3Y zWfBHSB?aX(Y*zTEfV(&~he4t?8dsc}E!$H&<$QAvyBI7K;W;K8RZwQ{sR?@ z^n~~HAWrLc<>J!=B!Su+dexO&o;*sxWCwZyQ|T+c!U2YjyLyXdR9+k=Du+I0u|v$A zvH|Y0rx24jY`~CrAr)rgQbEcDyMd4|ybxw}6Xpwd_!w^y!8)cj5pmXfh&ZDkG_}m_ zx>?`28bSPvyECvtaXmsjV&4<_IC>(lguQMAiVnq|dV^6s_28h4#s`uII^S4}v^7(rObE-CLPC*S2`&33~9L-6@Sgkzk z88tpeN}0DQs7I575D}B%eqTp!oo3O={%M^Vr-enAOD=-?$xAIljSJc!?pzoqW;xLK zIOin(+cs>hU%w)qZfD#@Luxxve3;{4BZ0#(G0%bAfLfOhWCoBCFAxg>IeOK~cEdST zMqllKW*ImQ5Wr-py@ArFQ#^WggQ2*IGKb}PHstBbFjpJ;+j{(7Tmww&>Tid6ezVE* zdj;@-0rytsxvwxQFuA;}<}oWBrD_#vDev(dKHf28v|iXN@zSl(e`{^)->`8#@EGj} zK+wZbB{Q^PMs~jRU|~@TXm%tfew<;;NHG_xbA_@B78(2s#anxOJNnZbVOKOYjB9DW z;6~DG?RR5*>HWv-Oeq6}MW9Z@TrJaV*?b7OFk3c*fE$7Au}u(lMGHyKfG@jG%sM6_ z&5>c^^X3WFz3~DD*E$jeByZqjfPoQN2zl1pF%JVFbBfP*mDb6{HRzgFMAY{tXM}%c z;w(`ew5X=kqY^T#mlnVtv_-N~8QQw(do3EcH`Zx#k$9>rn>EImx5cr}q% zK-Co*Rg=j8R&RxXGjM3#MR7Qb2an%7jQrjTF_VW`7L{4C*|j@c`&^~t5g7_}87z;x zD8eCg!K}L=v_ce>sU_c^PX6w?ArNO=ksctcf^L+nE-fDo%#YbQoGq@&{-pq{;Jv3U7-|?WDv%@XWEiH9Ry3qE6NDyBy8^!S8*F#L>jh^B zcVm%`Xt2W2u23jYRLFIORAlmwbyKE++{o=|)&@0^#pCvCmE~gNAZA%I@|@=T))gm< zPl$Oyoe*JDgBBiLfHwDwNz;?XPicNIH;<%sp*kEhCy2wHafaCgIvt!?Q@N{AITo4L zx(03t^yX?)5Ot*2)*y@bi51}EmeF<1q8a+WmM6T5@3@%>Ztl9RHc}bE!+1NG&&A3x zpTTdQK?*%iH$LUilja}HIB+DbT>+67e0zjx?V5jF{o6k;6M{cV$cHwG!g#tU9u+Ui zOL@4Ahs$}mB8CIBYhRMkuKktVV#!wQXXRGDYb$=){j+2{2y_WO+n3}v9$@TKDxqxq zE7=jF8|Rqpl)GZ|z8r)1<*RMk8xvoZeUYUpG!h<`ck`n?QE`pj%fmG>x>x3lSM$Yn zF?vq6{%|NBQ!YC7-tBGcj0zY_;UGjMlL= zE|1ISEcv`GKgLg9V7iZ6@)Nc^!OIsd`AJKDDlR(Yr+N4cd-1cp`Wz3R=iv*i*B5#C zQcQkXe#MqwjmxjeugBy!3PK>m=2AMx5%_r$v?9G|82`Z z@%%sR?mt`dFEQ~p`Bz*1jVb>glmC$aB)t5~lK+m0ce5K_j){F53Kb^FyOp$*iix{b z5gsdPs|XsbijkWtv6O`_Q+7;zKpw?GAq>g~R17(*I1@OQDvgN;RT-M1%44cR4YL$N zpFE<5^JWAzd1B%*RmG~@A5$aMC?-tufDP%DYK*0@Aw7Z{HBOD^0i@2A3LDZ=1&-}Y zYLcZO)jp2lR#Vhe9zg0`Bm4O7Ot$SoTTP3pvlK|4msB^)HyNn1@yA~hnj7xIdL^t&9fBj>As-m^WnL?IxnW`)B;N_jEQflMV4A@tMmCB zJ+p+_EVa}Haq&ZDJW18_$ub_6TWUp2{7hXKS1aX%mTJJ5s8yDNAoJu4EYQ>d6yU3t zEpJ-Aaozfsri~kxFJ0TvcwtLJ{kleIG8!5#s3My!w+CZ)rz>7@cM8}Y1oj34rP@LI z4f8VcH<6ZFlYbw%VhAPV?om-@T>Hu}L`p%Lba)_9)3se~8@jtex&=GOB@MtF(n*_| zHq;v>hgkRSe#8zpL`VUW*fAurN9D{6v@J~O=c9_yhFEWUS9gEf6zX6r$$n6wfP9GMy&(Fccgo1LfzeqmRAQd)k>*`#jGjLti;H%a$9Fdk5=!| z30w;=l;l}9LfhvQ%cNJ=fKr&=9lDIm3V52(d1us-&J5<6T}LmO&SSVyN2m|RwU=VD zYa8Z~l=)PU06lFx(rr7JxlS%hVd>EW^=%KDTpG;F!aUYxmTl|kP3szKZaigh0a?8- zJXz47rIpw#XZk0*Ery-1;~DAQdaxOW4$jzQdNuLs<9xbT*~GM4?N_3dHKWZ}Z8N%W zs6c&2>nlqMWI&2>qYEpM&{XEqfMs8%JK>z8@MoygAaqa0xMS_Ybx4aPW2<8nPh3%$ z9{EJ@I}cD8bSkS8u=hxK=81a93A30?L0<*aauOK#16mH3Y4u`!mdGuEwOm!8o3eJL z9^{(UAlxWq(=#N=a+UvCmRe*Xk=hV;Nn=eJS$*rvEnUSKZ(3v|-u6=w`K^rpy*r zhd4B*6nNxdtF8-|;o`1Y8^KQ9>2~Fy>z=PPGxt2;bE_c5ou|L}LaiM{t)duOQ$_kQ z2n<~g7;VcLJ>9D#wd?kD`!cM2ZS<*Uq;Ak2Xg+CnX36(H3U+)>$yrG`mRu5{ok!<8 zhC=Y#;MsnA-S5^~ugNBji#3~|mKb=NVcq{{b&E6Q{4c2oWGZkP1uFly#T}lQ<#Y>j ze2ZJ7Amzv+@oz``3kMmI#f~hImV>Bwa~(NOj(22SI$#%Rah~2vncV`PH#_1V;-7Hx zQ<%WZBB=3|TI)z#MjaVrF=evckrfhq<3>lVQ|m2tk)t-KCQEH})WvF(r8Yb25(T#^ z4s@y^6@m*Y=+!#vQgxZ7E_c)w>PknvjMu6~ZE;kq+G44#j%riwj!G-I3jLkxAZ3PPYM%*&gB z9-h^jdK+L7;Nn_K^*HKke$%V^9M!LOJ8F-Dm(7Ymc`Md8)um8{_Vl*a-JSi@y1H2f z)K8P0A=cw1H*IMd&N8O-aXQ|ga>J92f zs5@o4z>P<^w0HY%y5$JO8Z0ql84lM?4q|^IVB&B&!jYA-%27A7C&#YnVE?5wcF}}I zilGKm{qT*MveX+Lb&Glvh9%XC4(;yk*xu2FzPwev$x*i{geI$$BOUc-In1q)*N=XC zLOU8q-LBpOMdZ9at}(XT-Hy6LCLK9ij&;;qYa{ymjq~5u7K0kbbG45I|VqPxRRHadN;x4E=TQC`?H#f>V_2=bq`wVJ&t;>x*ItL zTj~=Xj(VTE$5r+AI;Ld#6q6pSOZ)=AC_=#+r2Fn=%f#EOj5zxW+}Mo&IY*~Ok#Ekg!M^|IzZI+H}Q8z zJ%B59kcS6xkQ4D1&;{n)Lyme_eHbvw?w+|z2bRpwh_cipj{1mt)KZV}{P@syjb;<_ zo^UI!_es9g$5BrL*{P>+K$=6AI_#(;@;pZ!<>901CQBW2IF-E+)7M+8waNe z*g}25QeSk`mx!UitiB?}(3FMYbStw47M_5*;8l$c%hH@`a1Qm~;!irD>d;|g4jc7V z=!|6M2q&FC-7q^=&V-tLDySxJFclC-3PGJZx*RE`a^x%tQ@k<3Ns-Yn(^JM#U&Csv zzD`K{1|jVn36MOS!!uN53L+z}zUioMsc&2AJC6FU2AD#9c?xBLdCcs4j{3g(K?oxT zxK5cCWfm@e^+QYj$WcG$3)E!`_#`S9R8D|If|6IX5>a z5H5spSrZ5lvJjw@LRiWYme3HEur#ferpX1;h6IyP+PbvXPPKMis#b@pwXIdOR;5(7 z!2(*RIF6$;I_fw&GwLilyR+zQ-+cX^=Y8LE?m0K-W+P0U-+Y04*7v;o^55R)|5GRO zv&bh|+cIbl_zI;K{$S>sIMqe%1==(QLh5@mgtvozzfH_BkPzNySLYg{A&cchZ9}B zBSS$>)gDHlwIl!TME)c4p8<+clTuFP|A1JC{8!}PoXG!;ylUr(lV{~c2Ek*5jZb$U zs}vU3YWFC(RQ*6H$Pq25Jtr?OFY2!0+4f|!706myds}yRPk$L^mNFWvl_^;3GEh(o zuyj%Q(5S;eH02#I9@bf~AsEbh$KMfrtUgGzJW$YdMy&l1=fc12>e6-64Ta(AkX3pI+=wlOBD%q|wVRu&vkHpKA9qby~jv^Wu zdMUWJ0CTUhY~F&g9R$kXxCK;bu~_L`5o1sVRFi9ZX-@a3g}g;$GVkf{q!k6_n<@w9 zF~vEcNf39gc(Owy&m%x2(FlwLg?0%cgZQ>=kR;8_sD=4~?~wSA1|hzl9$dU~M+?$k zE#zRDhOklbEKID%jOj_vHc->Du0S<>b#0ID14M1R7G>zSQbK(& z=N_Y`m|)~=WT5Q-4cInA0FdZCt*U1$*hy_Kr13C0n#`0sv~$eucif4p<+x%;Z@b4R z%F-RdD#9*K%29m}xtSABeHq!*)kCu|Zh=0U-VX9`5`w6qtPwKRd!$sWrGx<|rT%bw zLCL_mD`R4J{_r5$Q%3jY^1S}}#K5q)--LCKpae541bFSt5DypFxn3L^8#Zo7Rr{ud z+~H9HLk&1rGOh-K9@M(qss}nzDo}=#JtP+}1k;tP#G1gYr(ihkc^sIPiO@$hWk@At zf(-ud9vul|b_ZE-jvc32{!G9a7JFjp6P+`_+k>CwaP)KWm~`j4h@EZ=wrdKZE)Wn! z<9=!Vj0#OG_z=CYL!e*kyB+Q}Fre53h0|e89_$p}w@BzJjItrhEdfz(MkFj*Gb)!k z!7L37qS~ndrPuNTOXg>qC^%OSm^7~s#+|#keqXaFX)I0TTF<&OFiL%cdH12-o@10X zsVoNghDdt(IT(G0CbGlj!bc(sTI)y(RJ`M2xs5+|X0vZsl z{86G42=cj6z0~+pcDtK;rwSH5*4B#vlQ8!&e*wXRCD^OzXPCS?9uPFkDt3^7m_H38 zjHWOyW24#+Y@!1kau>-Y^luk!ZBC{`xN}Zd=N)%;_V;zxHFe&xl^39?P@Pa6Dk-6! zK`HVxBn`lxLMIbQA=L+cz(UUPDXQDYGP@ZV#)sg;ktG8HVC;|s9ntL@ea9eY)Q|&> zXiOw%q+?kxz^|D8Zbm1w3Qd>nU$FA==X4*4yvXLvbw~dKvK4R;WCmq|j}xZbSFh>E*^% zS78ceZ#&kfbx>#pO{Z%)4#wjE$K`SCkAVMYP9ClyMx9zm8qIU0uZtFViXMNct*<$K z4`_#Iw>kw$caKET4#+v@>r8Oq8Z!WQY8dWXp zHH*|OvYOM2R`?ev5X!c7+a|@ns&*;XHs6g0yL+%ZzKtl1p^HAuqFxhBgKUd$AMS}C z@#LCp{hp-OUSr3SS$fSTp0Iu2ZXmS)Ow|*-o^4t<8IdvU>{mFLC7pe0iKAUuTYvi@ zEQ)|7w`7lBEgb9xhNsFfI-0&S%y@9~1(y*GyG3pWbVOli_uV~rrJK;LG00pyc}08e zI@;asEyp!_T?$#dg9b2wSz)xwgxdO_IQEcec0|u> z1GYR2M2l&=1M^7`GsZ_F516Ph<*G$}fRPB>+I{F5Vp?#Q)i@ZfoFlprn@d(!sWzSo zNv6@?>ch=+SSlE%6SVDRpSQ&qy(*xw@Tgw2jc+2r9o8B0LQMwGl0p&QYqnvcyGUkO zM>N(de}6F?f~NJ@tQqFH(MJF(wsYksRtf1lou3_T^k|6QiT0e}CZ%TkZEZ)8P!UIy zUKH>EZH_OqcvLgn>-9g-gEblE!o4W5h{n{PidfclbYM{SbQ6&YqV1M+e?P`5vN09Q zYR;EQQ*bYfEKW}8gv*!tEtW9TB6TxTeS%Bnh{M2H!`hp;B~V|CU>KGE)4@ zKw8gRywk+ps|)*5O=Hu8tavtyJ#7C(uH+ICK)QS(aXX-oD8I}*~47&$)hUo*&Ng61qd)O%83@2%{g20h@FYB=zo?kEHwjCP~ zm2n`0!iR67YLXPfS&u$hRe9VUe?f{`tMbmuICue|e`|Q3=buHx2NRzk7KQ+$6LgR$ z%_4LVs|lNv0MBQw#cum#Q}rv>a)g_>twuWquxrl9q-MZ~0;9h^mMq17pDD-TRxPzW zdP07U`;(^D=VK?*v{z()D*p>Io!2-$D^qwoL*D|AiY~6F)#q2Mrz+$*nOSc$hFK3U zkDe0Xhn63gB`NzAsl^?UL4gXItN;dR%0^6QWFFBz)eT&$0Ra@qo(rlc3U)9d$2FIw zsy;uJ|BAHJ0eLO-BX+4>`1q4DzBF2D zyy1*2e}W#MSF|SU;TZms+ZM2XFwIqg=I55ODTsU3Huizl*sA4J#cE=CXJn1R+ltau z!hEq6U$A?vQRTStxBx@UtGl%*2fT`}!zsBQhZ*N&15TD)%B5i()!*F8u2&;py$bKoy`TlJS@%W)~fMzbyF;cgt; z%wCar&BZ5VCR%E%+frM(ekl0+7^acR1{Y!>i_#$}`@dT6)J> zgz9pW8TNDzz=A5~=8QDyAW_>_BZFpVC>|VI> zfR+!AL*~hLWG+IhC!HH>CHCiGBCy6IH~WsuN6|xWzAUZVYR(H*XjagjwQysSuFdu< zg8hOe`Ab+OXq)2WGBfs)+)9Urufu@3O}R5vzTaC;$OKfedZiznm)q$*Jnw{zujhzM z-oZ?^*I4JJ14F@kd_d(L839vvLXIGVhmK39&R{1qcqcOmKPh?3Fbfn_MQfvoXAO4> z!et@e-^K5iBYTO~`q-Co?yC7D_Agqer7IPC8E|uSR{t`vl@azZmc;V{DF}|Re0l+m zG)sErD12hPRUUyShP3<`GcxDke}UZu&z$3CS!JeKAH@LRR>vOtL@8$LvqR0m#5Iw% zI7v-flhnKwNBbQ)sq+<8`MQEVjClA4CS#o@W4E1?Uf0P=VRf?ay!1yfFs@*CANtu^Wb|l#^n%>o zT9v{k(qqjRW3`+m-=vOju1)rxk+=A>f%K8!9IL`4d&o=)9Fbd- zeQ37(RpG~1#j17QPskEg2hFMqw$-ALiTY^m%c};cx^RX4L;x=pey=0 zQUz=e!EdoTv#>DwFsVL_RJoqrf;oVbSG8(c9MQ5kqGgq@`_(>Q_g?2v$@n@)K08M~ z^TMf5=lRo7_KXPj)Y31|EaZmgI^cn?$9cVMR%h14JZnC3#?^E;!gF%mazWmTvGHIN zI>+12$V12F23-Bxd3l%<)OmTkB>=R>#XBsyES=4@D1hFZ>r|((PCUZF@#^>W6mL}` z#)!25DOFiqy_r%uCQCxlmQ(=?`<)yc^r%ySSpq{v&qN8Dx|!g+%L_OE@55FRCXT*y$@{v@*1^FntaQv)1c}6~#vh&s4lZs zKP4$!&r9AD%t#aTjP#V6df-i|_Ov|x0w&K=^qbFME?@y+L}ChfBWjz=({;@3Gnk-0 zeq0tHBTv7A=?JGY^6V9?qL=04+p17kpTO^v_?h}FEoSrI?WrL&oE9< zMGr5>v{m=mLOx?z0o_hb zUzR8-h&~Ni(S(8(Esd2V9=@}r09c~=dCLlMTk!CKbMl*vcS6)W=w9x?1DCVhDa}Xd zz-vC}US6bL7nKwOcC^$fEjlL`mXAYBrQ_~g&IEYQPen^(kDitpIOpR`>XB_%KQ1-y zirNDIH2cFBPskco+SE8?x?|aRRb<{w?^sq`GCuOOl$4B*eq6?v6yv&}q&WI4rVhlV zzSh-i(R9W%SvFbxk{e{1b%P0VSj{#fZHOj1?PGE)R~G`YVu@Rb(?#a*f?Og=aQU=c z#3Kv`Zr=ZJgs;!bm-4U(R`43Dk$ydaC;j%zm{YhQUUZX&b&pA!F#co$ZomZ2r3kcj z1$=a=%PW$?)2aIDM4m9ezYIE+48T{2L@>>bupT6ao}DrdH1XcWC$LsotIc~(M@(=N z;`?y*CuA+pugDafkoW9NBMz1!D?p~uZu)Di8@=>3F_~XA3p|Yber@=BOTUlO!pO|y zKf=nw5%vcd1;5ptdFta(OzFQLjgkwOQh;q`u&WL!yOxklL`K;)YKwuee8mqYvm&R+kC-`ukr9ZJbeAE z{4SR9?0~6gNH8||H1HGZtiT|?p-OAklnt2UU>&4OZ55&il2iN#(4}QS+Yu~ee}J(brNe{oAk23WCQ296-$N15hs$xo z-1CQ*<@+2Ye?;OBzOT!YKV+c2c#8&hQta`V-TxR~>2QTQopM1GG0Dk{PcS<1u7s0) zy^TB)!lEbzv|&6=#adXy-fgsnAjDIvQ?^+N#@EN0?XXQ^xSM3GScSwF9 zzbAi)BPM@SK^xJbVE<&g)qBxxxx7Dw`Ts}9H0?$bPiC2GsMtcbS9G*mO{+MiG z5YW|nB~gqn2=7$BW(-eACBn%Uo)tJZNOXUbt5ua);km>n4*^kTPoc zbCSXWTFTQIIZM!xbH^o)Dm!=5a9oxJpNr9b~nX%-&{FG$XIZaU^V<(k6lb`4)i{oUyOq9Nf%Jn9U_uH)<=KVypI9F<0)oDx> z1p#(iyG#JT>q8BJi`OmI?vU4ciY&wHJ=R|DwdNt&u_K>FI)c~xLSI|zH7NL-tyc3j zSaNC-6+Y#@@3GMt1OZp*^%!nm z0Te-WtRewqL^*-6%IO86oL&&%uaYm|1;LR@UcnVYxm4LwZPT5r2V&*luQtLALoVp; zkYD4MijOoNiet@2`IvDprV;b5X6Jj@&T(un4HaZ&tctQ!_@1J1prJ|12);d?q-%qM zYN4onyMk57#0(PpHP~QioV5c0%>k6sB%q)o5g_&WM{b4Gqh2I_IB7H1s%SO8o4U4qd2r@kB2L!kQvPEQ#92;SQKxrdAU}}7UHDVfDw%;UO4}&GqD`CLky-1tVxw_#3dmBjOOMkvs?q` z%*~K?k-<-=n&p0+TJFjJAU}ofs#=Q>L>qIEXiYZSSfYN-4jUE9-;D@3>iHyV{rg}7 zk|#I-nnUNmbLjlHLU!78{u`5>eB8pr?m`F#_woSuzc)*3f!rdu^7eIwSgT*p!+x87 ze~Sg!WW@pms$1y%w?onle}D(zk=;z^zs1tYFYn~ryLjm0;V=(y0DOz|F!Ce3dIPV3 zQg*ZS+0t(-PrxId@XYQ^OBM|^1Na6|qc$}u(sP4n`hVRBqR5QFNqtKD7qDD_rqy^n z((1c`kRNwx<+1mA)lg~Yo<;{Jh=7IQqd%@2a*oQbrVygzbwfrn>dZ2=oU`rlpnS&Z z$$A%dFQ6zQ;D54avdhZuUk`pNVG+Jtz9W!8x8(ENtGivw90U^p?* z3JS$w@+w~=wuV;5sP67nZMA^Dd%)ko1G2Cah??-G3xhov6Zq-kAwn7>2CvH_9eGH8?b>k%j;xl4 z9eKN~Qoi7Ad8a|0e^h?mk$1_v9eEGgmPN9SKH-sJz|r%gHOd#f@j&+&^Z7pJ{QbQ8 z0IwdGcf$^Ph?y|=BtObc9ZNF_4j85bN0%O*y&R zb%dtQ0T-P^mCwJ{4i$C~!{C99MEVX!R#=|&k~T`DBX`Ha!aZelsVqAvAIFNQrjNDI?MqD4?{Ds8c9w@;1wdAzi>`+ zhQhmr>RFxQWZ=yLPnO^bRlelSO2Br}7AppEeEw;QCIQu~d6e0l15I%Hu4Zs*-fd`P z3#k9W<$1xr+T)VKbwsOsB4@zwK~WGnfymB^(T9`?J!tEsA3;oz`pKL5(G@vhHJuV? zn~trBrWxmD93x$bi}94b7E|^L>o2W=OhB0gIek+NpTQII#BC>D{bm(DhZKGi(uIPl zkTFBERKha^(UW=37)KzBrJ7xXmP+W*n>CWn>6Hsyc9?gwO>IrSAjMRfO=&`mtcMip z!2^)SbZWv+!rA3kk*%pZHSG6>pB9~3R)}eC2s#K44Kdvf0Y9OrK<3zQ}op|-n`4OsnGTRa7nNLVz%_;iTp2*uWeOu03hD1hZ8`(Eqo0=R1gy&kzR~#33 zJq;;9L=^z9;SY7dYp>5?Ll{b=5xr@`j=;J!mW$LcbW z;EZ6yZCk#*2CdBBmf=Ov&=L@*RKOwW9e1RGPuZ0|2)ZzfTQ5$a+ZEVSXmdb#LSs!H z8p&_b0U8y%P-xitRJj#q>kb+-X0xf*52IK^&H+T|V!43_AVOp6;MGbVfC*hJtNFN?)BSadDDCS!QrF&d`0&y0P6ZH9m$U0OwCJ@D zR7Bp9ek{$_R$rGgxR0h!MSG5Offd|+9OetI8u6O+OQS zBbeZ;D|0wwyOz5quP)+3P!;a*wPdrOG#I2U2Au_zjJd?!ycO8^XUV$Ctyh&}R_$8G zeRah~Hm4r!n^-iLGe*lmfPXUMp8d&}o_>nC8xVbmQ7PIdNd&TR<#ihK zItBK6M$dSiuEt!?d4CoO#wu(Wh|DVZfHF4EYfZwaG@GbVDqD^j)pb=#1(f{ZO6J z71bHN5og8;g#)&3EQHZ1v?ve)xOGTMlz;KOmt_2lQskCu5}uKGN}>@b`q$OxvWO>I zvgR7cMx2&el=<>5g*gj>-)M2(r9@OSdg6ZCRy!=6O_C794>o zn97@3SveHU3c4<+F%JpsllOD?SJtgs09!f_cDMB(?Zt-Gca1PUgBR`xp3o`ypRCDB zb(kM9Z@FfI0L+n@AsYBWsbBQszEJxsmxjH`s*bE%M)<(cpAEA-!N`aC5wmc8SQgAK zKqb}A(XekF#&^Ta#;EgNc%bth0yTH1iQ}|h=g76m2y;C%s^@oHa}6S{x+T7y_A@YkRSJF)z9JXO;;1$@v znSS#a|5uw7b_+v+UQoW>CegRsB$>s-jieYVjF-0cGLH`0a0{kg38HP;;($E{ot_gx z(Vvzthnyh?k&v0M27KUS*@jye-Y9S@S(i9#X34(g=$R5a3iM8H^rXzT-5l%&x6QY- zp`dBqw-kl1?zywNv3othJz!DN30#uiK3Fo~rYhLYO;&?l+dKpvscQ-1e>KRm$~S!c zqjh^48n+J{{|KEb<6gKBYoqpCNe`2gutt$^h*woxmdgjL=d`n6h*E^05C`@a=OAW* zIjXUiCdCy2`HI4TT!2ay_bC%y5rluyR**9>k9=ZU*qEk*O#&0nIFV{4C^17lF$CSi z=~QiHNQqP{OQOu0ksmV943o7fVAsjXJB)_L#a<|#x0!f{QDH)tgFvD2DK{G+Z3sAc^j+o8S+&r}tit`ijL_lo4zi zL4(sRdXf@|iM)k9TM2I_+foY0>6X-00K5SZ4Op-U>s6r;aw^OmP~mQ))`kUIryRM} z&tbW;0z>_b$KdVi>4V66Te|;HPY3+6!-uqSL|GsSvQCO+nvEUk8D6Eir{!q-p-r9X zE`yPa*|7}nX+~KQsC29~L3=nKr{Z!(K8T(X)bp^%f4<@$G5IW@tRYjB0TZm6jaj*n z(8NYIX+Rd%(+dqj8zz0d?#A{Kb*;Dz&8~!G#ZzF5&n;D8i{Z2u`?ZzWtidoomFL8| z_{GGF5;?{HFszS8x1-PBq;B(Z8&kL3M^}JxT8aTb1+6nr4g3g1=QNsvtrBJx%``yv zh^`+G_VD7V^Zxm}7!&-hM8HgKjG*ST`uDdJhzgDqVV9IJc1dwsB}D}u6K|7tTRPxA zktRxMIgo$p=SUWR6wtv!=@5;RO65)-V4Spq#z`w^oU}r^3#CVn6v`W62qoIyYpfdkW=Vxvv1@^^HvZO;GzL(7E5j!~M2A0B>)+na$W|%UcujpzM#!+jxE` zf9*HdGB1+9_L9CJ@9}F1d05^amv`{|2z0m!sBB<&)gzB4uu<+^33<1?Cjs^CV@&^j zd~u&G?`P-_*z&k7AGG1GFQn@a!(E)m>jWgsQ?yacp60 zy@B%?Mu0Ix4y3jrgkl(Z%u6cQkNhKpnHZ48HHSmkDFvUjjrd!N9P8+8 z(=;O}l05)+9N82RQpwrIb(p&!z83M0#%PbIy&hz*Zz)09U4*khhY2am-mt-t9d0yv z^Jyp6%LZG1!-2)a6OMdXJ`yfZQ07&-?LhAx)vGc6x_{J>C*_Iok9^`uTR!H2Nu|^wtU)==j1cCJnzV7<#UdFUQWW2bwvHe z0UX9DTV8bJ3v!xq!_@qYBWD@iIXUmhZ_0(y2{#=1qP)byUmW^-RdK%7C!54iFWGV# z0^7|uEWy5>FUgmc9LAQH9r=oU4w@JC9N4syjVUASE7+i;ePxT6!5$Nyd%Am$cDJVq z6k3KQx@_}870qwSD=_y_ERB)?uIue>yH}eFUXhR3@>NHETfSz??>O>x`CVJS;m9}T z_Z*tr2f#u{Ko2|e`|_=T4#wqd2D6_VNLCmo@@n|4;X*=>l)D)cq&=57TC+i;kc1hd z@y2fKJwr2FVkoyPDbUDQs@a(V6l`PFLHB4_{qdZ#={Coks;>jlI?~BnOJs+XqlJoS zuLXQ5mzs*^D5Rg|7q@-neZw7uVzw zsBFeFQe9ILT~Z$d6pymWcNwoHTQJ})CBg?` zGhl(k6YLUsLUv1_3OFaJ;{p)ElP6w%#pHDxVvh)L6_DC?liE~>@u)(;cFM|Va;ios zF?O>$Ja86BWSa0VBfNv~XH^NPI!J2tpqO>isxPqW6GWGoz)ViJcD)EYRp90cPTonQ~t_wedxNlMUq_j9*+Rn z=N*6rDMa5{@S!KnVXv@xtR$h>Ijp zN)}y^#V|`pC$DC=y0{DoE%B0giT#YMO68Ztm$0mEE)iL|D&=vY$l$5TZ4tCaxVsK^ z+7HE%V<6%AYjz(p26o3}ZymZkyV&*TWa$~eV@3gKr-t}4cJLc$e|}z;vu{sSZ!pR; zZ~W2Tf+o7vn^1hv8Y|98{fkoT+SqV!FKujALzX*0Tz+`h8-DR91nT@PMZjFE(Lf4? zEKX2PZUM*Q{jP+VCaWI;%W2E;1j_qF0>%F@44U|t`N3ZpXIyH+46bboJ>GP@InISMu@sjPVwD~JbZyKPV?EB1P1Hb z0$iQr;k+%ssbu#Ra)I|>*xcnI(|9L|GLjKa0pW5;>&@&sFwr{v; z|E_hrH}2ojyl&e@SX2!p4M7KD2`9JFzn30@;__E8n((*>rrei* zgQ6%}p~XX)9!iy-w|h4zk7C`A{V3VVwvM~We|7jDUNhdzXfM-2Qh1Xx;aJ%atkZ0A z*v| zMue8rBnnK>;jA#jEWzlCjr68u_q9xRu_ZpEk~WrV!E^?+JtDk+$gi$-kxH_Qq=deh zY_h6WF`dh^9u6~ehK`m@A+r*B=D~FO6#iK^{Se)`s*5BOPdZc zLcNJCf9uHK5s!KZOTj_-Z#}&0lt{)W93-jdNWc7jc-%he%g}L$OUnD@9~^lj_qG3A z-r)et8i#)QC+(pbSHIxxFKzi(2Ob9S4h{xv`A-M#1^&yH|LX`G3n(wj0l_#ejW)tj z3HDsa%sF7H<5+q0yA0<8Arc|S%EwDuUO3V%Jq|qpJ60UGFmPA7!;buZdCUO~ezPOD z%gv^8wEn&s{ug%iD8oR{H9NvvuuE!_I~>`^@DnoQZ43H8^2;cH-2rY5qD^Vxi)`bEI2^?-aQt!aAHEdCT z4Zs1oD&wKtrYCm*a?>gLJj~{02M+fmB)|jSWLxtct5V(?XcSl9Ff!#3CQBHJxt784 zbT^1bwaGcgE=$nsABEzKnt?)PGUQ zore#&G{^29_bRJohDHsiNBWN5(Fc;8{^@f0BOQTseR8GeIM}Z^$Ly<0?~P_O7VP}P zH-mtp@cFoE>d{#W z2f`(y7Ej^Qhx=A_e+%xhe){fH@;YDm+wlGCefRqj2bNl2_(@z(z58}-%);X7-QR+H ztfRjB$;i_IIfy5Rkb|`lJ}G%B00Av-lB=oul0=RZqCT&+>N2%}ME>uRE|cy%aHdG{O(=j3nQS58DGG3oMHs?fFvNU1hxW>A5*W+6Grqr+$||MjENLEt^^zg1nifk1gP1>N1n_Or4c-tLdm3x z6Vgt+Nl_0l6_VM!=TE%)<>>QBUrehK7#`Gy$z29P0%F^0=qRQK!xoUfGGV`lGmVKa zBHxqg+yeOp*>PN($LBqdLQO{D92Ca?*k87%~{AXq647+1lG`S4ADeW=}()^k{-mKVG zqb1}PNncY-8CBaCWWIi_OLIR`1Z8Z3RU%!gSO{zn zgmAS8Q!Xar)zhONlVUe8oOm_v!^>pS~iy-*~=-!OLjcoHIz-yJ?aC8*_* z7paWcQ;4;EUjdd@nDO1htq`|z^T+G>?zRN3UeAL@a7}QpM1tER5=3wXEGrLyaZM1$ zHNj01bv$6N1g|<1awqpP+$mj5J&)(f&K6z@wK$WUS<3{XO6x*gyO&;|j>Lx-n#pt}s=z zbSB)I%3G-#2!>vTNBB>eRiAh^*uaL7BcSCwY4?6N8T5ba}f)>Ra92nTZh#DKXp;~va zM17bWxpDZ2d^Et#>f$&+FKc#S-~!B11w6V!o^-$fJcSONJ)f*U+SvsFV}~r8BTvgS zke}5k$z0#+H!53hTR!2)C*_1qWA0DOqqN^%H!`6sT$Qb3RQ8&{uWF=6>S`HbjF$fRY&?gfV;xL^K2R%$xh0ouC#d=%5SDh{?P_?GckqlOXtXqf zWO8h0IY%g1L!nWvc}I>y8s}`5Z0SB46ZybPkPjpWgjFy^-(YU^Ex8jC_S z1%No>mI7BpJ&IK}ZdkAvTi!`jfmMYCV+PVQ0=&+M!P&e)y8wq0>fz2a){DDrV z5M&`d63}TKge6uL`Db_(J`cZLVCKPC<(&|R_KY-{i=CEy%^>I)SAm|zENbFg3}TO5 zrgA-KyS%I~9`LeJ^0L{{tO1X)0-g;3kA=@OQV5D5;DNEgwU45CrVg_RvIp`k6&K)@ z6>NaFr61Sh@EZ@@f#N2z91{#4XVjQBlyOEL%=jWOD%Eo^81(}JMW}#P{RsOm6RVQb|O*esSQK&f-pH*mZ)4A;W^1Mj7xaKMFnbV8k40#LO(pK{V zUqbTYHqisf8M(sw;Dqka<_aet{r;r{I70qbAm9)te_;ySEROKk^Vk03-w_iNP0Dtg zK0l(elQ+AfmmbiMTWs0Q$9s6#%L5#LMCIlL1hTCOAc@^lfbh5S>UB1G$fUg9x0gQ2 z50l*4etQClA8pufAD8w*NPE+^9Eg*DoI&=pTJ|#>ILRbA$!c!AhgT5Bjg9wFIjqEu zd;wk(f;k?J*ou<`mEEv$)4DxPyZ2}8>A?Jf0Sq#KLA9dCq2*fI4X+ihs=(ScJVl}5 znX;6QJ~n-&0>K)a4HAA!zxU_`aj=9(#|dUp=)Q&8P~rohtWi4CA@^zxVtVzfXesvp z&B2uV&{$*nwSH)CFu$Rizfcl(^jfW9P}~EIl*R-q%s+yM1r?S(A+My{xTQmKPR6<1 zVsfjC<%X-_QIE>qh6_DLHxJ4$#bO%DET%VyMY7NV6$sKe=RO}}F_B#oZD*vQ$yUjY zAWpX|S+>-H4EW6;vk&2#CM%ewkF>SlmG1AnPi;i1Jq)uki1!@1UmgfyfH8qDazF|` zNZ%7cLt7{7=_um?C$ZGP-f%9Rlh4Nq+uhl1-hwg zbzmzLr|ky@*dOQsE5VT^LAF4L3)(gXsMUqI)*Kqf1cx06Fz(rb6G^I#G2HbzqVffy&jqGd3cim~5u`0?2SC~|;ULotbUnyD zvWE+hUO_8})&zcq_&N9$l`7P>aT$M^_NhWavkPSWCR$NbsQPqW;6|n{CT7j<_wQUr;_Q-oOvl*rl zjt9s$mTG26=VlFxf_ch>?E*(Y4b|<*DM&f>ggD8myf`jflhc~DgKDU*$CJXJPKEjm zsMv8|levdp9SZ#9Oz4-OY3Bu=&^`cKXK1IvP@j`Be-757CNQ6w94tT%$hOTuvXk*E zhw^l`Vv)|uoFI#&3$OtNz?^74rxgPWaNB?aG@$^{E7N&)5wl<6X5Tzx5zMn8ieS{< zI(g<^v%9S82}qs_FM1X({yZ+I7S_D1?p&D2@r*cla}{phyw9mX6QGCYK1K%e;ouof zFE*hm?+)Qnc+kn(#{&aZp;M7zoQVpYxCNbsYEgEaEnx5}p&4CpMyfo8sxC-#5Q0o) z%N*w7oQuKgJbbWEZ4`&;l+W!0HFqm+o^*C5ipyX9aHD8Q_ubXsbEJ`IltAmtV$vL2 z5^(dtoilAmi1^zA%q>Fj=T|n~x?Wk`S2hCG9Q0NKCRq5>PtA>fQ|21tQRmcoxb0xN zPFpIaI~sY1MZZFQY$Rs6gZY3Xf^ybCtz;D`FmLK*AfMfWy&kIODCB^gfz%lqI(0^u zR%gr<>J0M|buQp1!G`8td)3qX)7=<6e?&x{FWn%Hw^t6xMLM3D4vikaoA)^15G@PUo59I|R=pj6P&B z+EUOf6=V+%Y|i%6rn}9it#-R~&>9vuzHZ-cuYu&?yZXIno+8f|65Uhb_o``b2xUs9Ry`F9 z`u(xaj{ZZKU!YXUKa}n~cnGOa&Qz!xCEHu}Xh4;CW6S=g#^yb+>$fn6=HqtTI*8U2 zxY*YSmsgi3VHRe0>?FVST`aHzZZDMcutVs2=*3hZ)l`o z=nc(M-pfD&=RtTJg)a(C9gkKAO02}D>#R8CaB<5!5F96|yPf{^_!$Z7`)^dr=XN$~dwfKl6b@?eNd_u;< z*B18T!*9fKDV{ccMoF{;@W|Nz@0vI=kBiNxbto>^)Hwq_O`1<9V>|sh8Snp?j0&?m z8^&l{#3$?QHdW>2Rnz&Ia=7L}8e>*9;qN#3?6c})R((Eb!iZ8QoRSIf7t@pD) zpuZ>+bZcf&7tPrjOE2hYc){kwcP#oTU}@XuRvV)qr|tfy62s8u&r1k4aOTF0dk&z({zK8N-b|WH1H+Qr!n;rguiv#+re^1 z-rln!I-OT}xXRah%2<7TN_6}=$%jy3NUdPd#C`%Pq|n%S#v51;r$Kf zA_#k&()aZHnC#DF`4<|DPd6VQCR*MgQBeGrYxoADIMUnG-_zdH<%^3v|5K%J`(Z1% zR{nO5I4&1|PR~$=8qz+%2jKNDDZolSgNK=%_-FB|j9emCjA=5P&#-1pQ)`Az9raLB z((w>oR%ls9V|PdT9z!$tAL{I@z*=&XkF^Z0b>a0gNLlOkTZ~n$j zp9C|*-`LLMOR|XnX$2@kF{%6saJ>SDD>iqV#E(&8obIA=lE>_ zASuJ{P?8}a zoir**##l~sMcPq@7dNTdL6bLg8wMyva^#hlEu@ z;Wn_>8i_MkA|EZl)ss8`XRcA6vgPRn1RT%s=Hq<)EG*h>`6RqL%L(3pDgou`r+Ije zVLrpd^E`aE0G8^Xw+T51z;QmoKBz_l%~caqJ1t0t%STHR|@5;^4mOo4cOg`7LUKq@V`q~IY4;xqu)=+ zx8&P4QREusJGOi`0YSv~67q)zM{Ws0Q8v}r@Z=+EkEYXPk8fZHX-De z$Y1d0FPXca#^q-u`u>Vf{+frs0i+Cb`**hdy)FL`HX4SZJtzqP%x&1-ynEO7CWt~S zf=gVkg}DGPx*_RKcWAllxC06+&Cn2_xF%@lF#ZHkZK=Sjtps1bbzs2J`CGQyUj zsGUiA772WgSm$LEuSi_cZ-Icw>tyqNR()DhnMEyo5oCo#9HW`Z9G$MNGfVEQYz$B+ zUTXd>67W%T7473UiCjIrgm=4iuV%`0wh2Qxu0!iD8UPf94u#6_J?J?CEswe146}UQ z256oVw|N5Fogn+k1lA2@Np)5R^>ZTycYB9<2sEoq1Oqvm!Kl%W&OX#RhbL&Ejvi!H zUppN=4Zc@)hg;5kUa^3az&!<+RJ~NX!WlP<1A?IPvK)ze+%)&RwDcV9ZBJ*FGc1w> z(|7rhfOQdC39?pKVG!ITqF{Nv_VBZbR7wR#3EGR#bep%_+ugpahdR_CWnO@dAhgSI??5+<&jfH=;WTW9~F@8X^q7&);vop%<8oRt9>LJ1St$`yP2O!PWX4 zx*RmyF>m3X%wzKUF=cUJs&Je9+yQb;y8~u*7sTWKY3-}J2Nhk!tf0KX5Y`|jFb@tRXZujUW z?tn_`svtxsJG`BRUy7gyUm(vThknCIspK)sCKVk z`&SHf;76>Pw7EtH-Xpt+XNcwmUW7yFB}5Y1$Fin$A14)p8hg)Ud=e5i&^D_azw|vj{|7z7;?v&4HQGI_;Xv=tCPT3$I|aFwL91?8G9-A zm#|k*4^A zkCg15B$P*o;Cssah%86Cxs3)gLE_I4npmSUc(J+ccw%%8hI$RF5w(cu z3h{=oGQ3wxZnswkI^(vsZWwDKKITv>iReI#{99m23J^FN@@+3BjGkW5TeJM#+3WKe zB3u)-O+D>x2v4)1Aep29HO*VZrp0PXZl+T}wRF;sRekI#VRRN6&2xOF?Y7is?o)8- z026M8x=%^aHcq8y!T3-RWZ);K=}kr8yecEF{Qa zxee|1TGIi&j-T~B*rmL{GzicmZZLy@Q8@OAmP0I70x9WD*eV2ZGYJX^GpCYt!a1Tg z2=k0pPu*k9Q)jyW;Bydh>I`xRXZm;tfrsOM+)*V$+3I*ILaOqp-@qZJZHdZZjrw{7 zU_ko2XTS;6f50RFn)>`I7?DMF&^ElHq<0#QpzBQRlX0h{yBEZ6t(taLjPsW$7iSZO zpkNG>s)Bd!0>UA}_6vSk3ZpMcVQXG>i&mpV4S*u^k}VL9a=|vyl|baoe8MWhX+@#5 zH_;Z;NqLpjv#6^-BmP=5on?h7*R6`9RbQ}xBwd241&e?}%&&sak2E$qa9 zC=XTvf1h38VgL!cwKUwQigQH;`pXpLQ^*rlJs&|KCa_v;z!$`jE!-!YYt4P_#br@E zn5c0Q83fpl7nkKve?lgdu$@X^zhR$}Nhhb5L~k$2zx^ekEYjP|bhvt{&P&-P@#*Je zGLE;y15FeTacb4W5@@^d6yM-6EI%fvV){8O@%TI+&*9hz`QrwNURVw5{#1p!q|$9B zG+D8llU0C4D{Te{K|$?BSZQ!GM}BSI68Age59;q`;!GKS68&llx9Kye4Ku@(4qFau zWVg?5LrC_R6$m@^gj6)0lIa&@2JG%;Ch3|8kIT;pHpBy*Z4Ng0RItm!cm>brsxJNl z5@UC@(OuyXo(vA2cwHDzKx3;nAm6gyfR+n9(I|rGZv_0p8}`pe)1g*d=VV?JlAXT| z*{E#Bj+F)6k3SC=YQKH8?pP>hEq}^KP<|>3e^K8vx(*A7f`klYv_5pZb5f`4gsSPP6CX0Ec!SG82bL2<8wFwxeiJ$z_Q_9j zh+L6=c1`Lm?}GQPsu?fIlG8HI_2Na%=D3n*RY{cYynw#gqMUa9B_79)qwVmPrN5}m zd`j|Z+EbB=mgFy?ODznx6EeO&enFPP%;>CKe+hOxCtm%5PM6(0&dZCyCO9X{F3S!0 z-;6Fz@Q87FwR!B*wI@-c*JCa^z-Bfh|Lv#}aBaAckk>V3z8yV^7O1PLTARPjC|;3r zo~Egh|B6iF@L$d`2K{U*R{QeF+Lr->P@iA>aw`8))igBTij#;V3iC`_vRn3bPP8lh8uMZ5efuM47aJl!V%Y6 zA2k)E+7}h1Dh1A{(0kXXqA#Ds4^hIcRn*iCUI40*_?oko+3g%GL9}39fU4n{BM@v9 zF3QP_qp<918<8X{i5(^O1mGvtvQt4jS~J#B5g6tT80N{1daR$7O|&K3%yr2uVcwud zy;`A8rm_<*T|%(y|%P<2!sCsdYsJrPCZ3}&M{K#l1J0F0Ii zFbO5%)EGwq;IEhg9>;v(PHZz&iLu5`l*V(i^+lPECN6wY5_-vrm_GajcHHRM045LW zk9`+^LG9=4ja$C`I5rjWw*_x=k&eSLhti_IpxToNiPL3G0c;?!d8ky@CU971bN^5& z9X~fv>A5D(T|_o_5hZ1Fg4^bJyEQ>-h5@(5UNwKVG#8MzDI{UTxUh$)RCe3M;J8Wc zA&L{YBc=8bVT%vQ<)OC`C8_({*t~mx!^V~kyBc@w-o6VAM}Xh(*a%Xez*WNDs`lQ_ zBbwnzba(=Oh^fNA%dj6HT#F6_#a43y-{c~9Jw4p!9C`DlF^mX(1`dQ3>;oI9ZH)>$ zdVE6ioP;le`J~b#G8`*RcXw<*p!vt`*p(V>Ka)k|hqh*-hr(?;Rfn{+jkZ@;Vk($a*jq@aqD0Rl5 z!g(CR%!3IWCU4wj4EeaL36?_<8qIlzd<$TysspaZl1$=h0ao~^W))!GZi7{bCkwC{ z36Be5t&S@grGrKv_kvo2$r_L&jB@Chs64vZEZkAERf_rHJ0{~=C=nuIQTBIctG|WK zOWc9P?}~A@n9eB~ucDPQWn)pTNXk`#Xyp-9GKH;H*W2f5?7rJ#)Ru%#dDa@jkXXQnxu}0MLaC#VF?e{ z@vxMK>v>ql12$#X$a3z4T4c)#TUKEvbFC=1k5WIFBg>#mJPKpiXe}vo#qA?D#==A= z%iN|rOC=sUH;vldCQ~L&v7n;-CMCu|+tW*7XE|_ouc@JlpHLZ@K~1=E#2}V5ep`X7 zw>)^w?4lkYJiyX;?6j2OL@-b($FvlvD4GGIBrq^W<>HD=aT50aP<`Plmw|B< zB6V(-V;BIf;2$}2So>oKnqJMKAWx=vv1sO=u%Q;kJ!T6)l#PeQEF=~qfS~A!3*U4c z(Z(jetP~BdQIs7ZJT_aebN<-SPr}2-v%^~KPT?sRxMd}|<g+eKc3zX;VT0%?md;0_9{XWfV}m@Bk6T zUSf;xCAR2PVvFvT*Tsn~x|jYb_R4-fzMWTXJlw%UJD5722`kDofJOHbPINEfMEA;_ zK>Dzy3&0*>V>Z!|zPqzMt&JIH1;hgZ1uO$#UW!sV411bU&UGQvCRa_Lm+oKH3E3lo z^s;VtfXoO=T>Ls(rO*yFhK75Pu`x(~t*M>FYhq2y9sNd_qxVqfFj5!`gV|gXA%$gl z6uN%+TfwB3C5s}s2)i{h>WYX)MvaBp<__D`eY8frkf;SWA$Ss#0Tc?BXOwNAG3_Aq z;w0j=YZxzWzM*HF*}(xcAcPu4V@qqgk~t%c%j}C7D;rmX(lpi-7o+WQuolmzr5&&^ z-r!)Zo5vlqIP~(+$HOdv8Q}Hs+-sy~$_Vmdp(m#bvj+1C=?(EdV{g`5P8qYy@zS=7AARxQ^;$<^d>MKJX52w zB%FubsWB$I5t0picCFjpxV?G*p62!2_cS+bL|;k<$OkhEhV1ni{dR#t_I<$8MdL-# zrCfxg0K{C9!v&NdrGXKM*i)b?0ilK`^YMhTLz398=|OoL-Eu11RZdMRJ+!+;@xVX zBkB+XrKVBfiLNzoGw`X<7?V}=kemow8k)ugmwUl<8Xh9)mUAP}L3JEtzE~+VIfzb_ ziDzWeWmixdh3kkdCS0J%Fo*GErNB}&L42~*)2^~Ns?5D~QtVx1r6OimcsXa~@LpP~ z`+cSz%Q<<6hnBX-|?v*Ig|Q~sLp_G%e1EtJdR zz#v~OlyV+s^8nD0LaE?kE)Vl~0Mt~WRPwOEmMUASZK?5zKz9ZymXI|tv+M-7OXQF~ z?nV1-03tZlzsEYex^|`8I@Z$#ysH2;bV`Ugv6g^GdOMz<*37M$HIy@;EU?ii7j2tU zSvnS)*r0}2>z9cL0tgU@U5EpMLq@O#=mJW&V46RRvad3k2!!3S=@?_8&m1oOluMp9 zRvLROe(bQ2$YJ0RUV%s!kRswPBPFSZX^GLOK=TW6mk!`9KhftAT#DBz0a!$RoYCWW zo9ii_;Tl$gfM_j@Wv1c}XjEzbfLa)q9Z<``5D(>GIy3%wVrt&RYXVrful2kc!!n%z zS(9D#5AU^JYxr8*7vgL5oRHUXx3K6_A+ODnmNi9P_vx=yeZv;v?`l*-eTPB>Ap<~< zHWZ+0p$jUeE~t*WpgQV;>Zl8v zL_ZXoZ*aPvaO5gTEz!_7oZoI43HQaG1qI84pU(0C-p>&M@%PFpjtiRg#;-fRra3pld8S z;&85h)WV3+QlQE-XcSdR1dW0hZ2X9?h@}!&xm8IT2Z~|*ESO)Fq%oj$ELrLmPnAU8 zH=3ogwYICHfhch%BCq`)pei@8AZ0x zFqV1X;we}l?lG&k4#ykuBacI32Y*2x=R3Fk{7)VPjmF>AD4Rn2U>2)$l&YmBn;`oU zTF0h{w4Wlh2jXg;%GqAzs4k@D=)c*${!d*j6ID+d!9~`Xn+m4Q|2n?9rI{5Uduxl4~KbJ zLfx{qnqDS1IM`jdLg6w{LA2U|6cqmC;Ho9J+#=Xu1o?)jD7W4x7<{E8{j$-4_!3!Z z~nuEJ`^jXgjx=GObT!7~E5*Gli><|L4DrOW)EuJ_3RZ&3%YC5gY1${;OMBB7h) zu)(3_3g|5QZg^VR%1volyc&PeB1%C61a1Wmr!N zr!B;x1fumg2`P+l97E!>T{YE0FU2hVjz6h7FPf}CQK*@6=NYlyxs2LpDYVqOU>UWK=idyomwD-@;HmcUG(&Jm6<#r(Vn}=5V+MR`A49uq zuX#HC0cs!5pdJ%ucp64A6yOSwAZL~hCPbFnCkcmbm$ADV`D2&Rp5>U^K#{?; z7!&%a@h-<8*=ikl>dDnIlXXAww+!ay@IGo(K$);nPT}DNoZ{-WW*|Q~)jB^}JN0+2 zL`C>(Lcq~V@7*aiRILMvD8v*65P?I516c(RP~pHpf(LjE!9FG);4uVCCJzg>+Yp;* z#vwTlifw4cV$tsHW*pIMtms2obdU?3}H>=enN zj0(@F5~gZAw-9a8lK<)2B$Nr*DXvbbm=4Wg-fN7dQv#GKCFYtgGYlc+x09ZH6^bRd zZFSeY#)_rv#KNUpW2jitSjt7112k%~RxoM(5#?MN$w)xKq(xs05YSL-zfn-j(1JRm z1ZA1U!NXIh&kwGVQxFg>7ZT9eX!rwa^AD!zkI~a2q1_Q<_G=Baj$|~ApkHT{Ot!0J z(niqPUu#Gbe68t;?AHa)BQw;fRiF$5(>7bPvt&eHe9N*QufS$-{%*nNqnj|5r|OIu zSAY;5plK>Az}~8o1OOT)M=w1?GZOj;(C-iKylvQ(n|WkDgv zcNMRyqYd|Q=_)aP0qMm6=3ek8M7IGjg8-ATgk}>CZk*X!8k&dt7i3$trR-dLI zHy7b{uTgUmfHS9o8QnewvaJ~gEur%7SY3}55N-qTfh##RY7DXw#xzT9L4@_AG2DW+ zj!hvTJfTyQTyE16T>E}@zyWT986fSpHPC{pf!?FQ;Oy{{&6tc6;TOi^(D*rkr)vST z?zi~PRn<0ehxaJZ7X!&UpI(zk=~F6e*>h?9F|$Gor{6#R^9J& z!h9HjdrYikP&lndXpe}i2sjba0TJlCsnd>O!qui{#GVM_f*{1xY{P5>AUmT4dF64KyyThg!bl|^O6TXbZ+6}Ps$NeB6A-<4(s$}Y;O0jp9W;&Tuq?l7kuDJ z*>O(n8=^EnkKL3COE2`M-y4uJGd zy!u^2^WmTiu~{{*46zg{9p=Hv?C3bwo~R!LNeI35^dUh9n68cqUl_U|ZZ}$ZsDh zf>N2+;iL#De*JltU_6`V_{!Oa?;QqJ!rywNHZq!n{(JS@xC74Gv--kY;8aqU*(4Mq zvaA4_15gX)vZ4?>5?1m`(+h>%KfuE}z?abqcLQ%4D2xPp8CF3ofHdM<7AJgJG2zRK z<)*ka@eJdP)zZuuxAU-rU+rWhyLbx=jY8SYt35oxsIy!xYy9YDTUyaMhek28?>Ktk zK)M$TL$O-&H6$_7lQ~=aw%)GKdYv24pdIGw?R9r|cBFgiGF1q-8_1A?48wAvT*|L9 zo(uv*$3+z*9MY!Vv}pi<*U%YIuJ+53Bns7=?mybw9gJwC(I}ySUhaJ0T-c)H8g47V zW`z{YiX$Y|e8`o#H{cfI3IO}t?I7aTe&wYA`1K4XYEXNGZ^=2w0taEXd6ZE&yvA_}tU#mGmrydYK-PeW@rgxo4!JNUYwjc{ycY zQuR0iki={#LK6#qZ&PRHTdRv%?5HYhgZ&Gn9#9m|=*op)cHVrtJSD6+>BC|d~*m5>z znIfLQ=g08X4Y3w#Ucqm(I@3?(^{Q-sollSlJhn_ z#g@}k?6dMke(_SA&R^HbB_?$_PJglM#M3)#K$bz6Q{=^zuBKEF{&FS0!RJ`dlrjU(CXxJP z+4M2{to(HWV*Z-~`CIurUj03<{()CNH+ms~f9rMfk39U7`)C61{@J}t^6p=F_=Wo@ z#k*hH@~>DT2AItcgTKqy2u_wP%{iI+C%Kk@_ycpNeXzIfjyux5w)`9PoSXGcL%J({ z5FTnRX&6PU6X-T*BwjV0XbjdP3#VlO7&^QT%zrbP(hY3~^*=|AR1_Z80T9wT`=F`5i z!)^WThthp+DdzVfPlww&;mEI-L6`fn)5_AF{fE-MW!(VLEklVrdhj7V zdGJtwnQN3suYC`~sdcV_H3CAiVli67nmA&2dzrG=H7FXq1vI$s_Ka|nW0lZH;@hoK z%!9`|JNgf;E_19YRtha>O+}N`lpRX5P<%X%&J)MilpX23C*7qdB0h#MLx!H|ShK8X zmUhRT?X)T>TU7NX3)QQ|AZ^F`k;B93?mlckVb;p&gz$YpmCjXrezDuSy-I1RQ{&gO zZEKEWRai;Knv23%^DF?3mIOh>ys1iUn2`@LYx~TJcwW zi^-Q&ZPhqdEe^;bq+O55I~}Wz_5UbG;=6IM7FmlOYYC-NTC3?;*YVvW)>3*h#bdQS z#DQNC1iqfHAQiJ@EJ$R>T4vqgSj(*ywpH&~E1B6<)(Xd3&8s!Mx{-&qJgnnkJr5gr zXs}jXBUM07XPto>4lGOAYrHEd4SFzz>~K_#>G}KP^qO(YwiZZxR}&wX^wEml0uBOP zX_*$8`~2{YL=Klrlo{;=*k%s-8E63l8+y=TLwG41#DyShc1Lede@}Z4q{Tk*tdAJ-s<+{H`90Fr1r$fZF>iz|~h669EAqmm>~HR}4n%C&NnemOvYpykfd zJ|(`k`+JOQ$4aw*P0P#Op{v)az%wko$h@Z3U5bwVszpWU;wsezGlNA$t?60fCGmyn$ZF{ZtYF>N!Yv zoM~DL!XC%B;I0PWQNCNI^a&P>AZXi=$3v8d7%=bhJy=10Nw0kTvKC)LC@bYv)j%v# z77>Gg3ew(u`j?QVQ-ttG7Bmp>byonLK_XcQVLi-2Xwv~Vc<@kCd&)W*{+ZTNR+HW@_7z2!ho6WMq=i_l{ zXYBC&NQD3uIPi#>x6CfFOY)zQ&8b+4y`(isMZCD``eOGipE#8i9}m5{C^sz+fz}IBY-&gmoElSUw_zGzeiKVI8)yoy3W+ zIF6mzaSoisPMqY&0kHwFA&gECnhrkP z7E@Nk^3)%fi(1N09Frvt<;mU;YaQ>0$7N{?Js@7dVBs;jxC)*&hoo$IFb}Fe%idI( zU2$A4fm_6IWh6T<_@-mB{8?E6X^nP~I8*`WlAtm1(r2ZL0-%*{5kW>fMQnlighHkI zisxn3L0OCFl7q6M;-p-{Qo+OEUCaG>{#;q}@Ifizh0Cifplhy0!JdYjKLqRZ{Kupk z1ET^?KIzYHgZmoL=xAZK;R?hYROPx^Y7R;^yT?ZMYV=J5B*{TV2Z%Xz!FNn*O^C`kZeuPAjplJ z^QlYm;Z)GQAaix$5!r@OTY#u=@hk|jP>b6NeLEL_{LYMwL$CY@t)wknFc#jfofWd` zFUIp6W*26z;)8ge*%aWZnRg)zxY*rRfD9Be_+cyqx-)d^`t5pV61iuZY#){#MPkWJ!Dv2H`Hp}6 zVDJw3f^j8gvhj;An*Hu&s6GC!M51)7^O^YyNvwcTBD10(>KO`We#xODpQ#qr`17!k zxsH6si?Z(}kCR^Rop5{wa$;B)wJdIVJH?u_Ucru-pia$P1q$=;rlG;d9%G}?zwL?*-f8IqG zU8JOGA{)!J$60Kzq!?Y5)CS?L&~!NB1QEcrf%4)gZbX9>Sz(4Vc7C{PEOty9`@nVvjEfBx(CpL_}L=Wk+%=+Z=qn-p@0Vs!dx zW;59_vw0PU=+233^-;Sn@1V`>8zf=~EU(bHH}p_@4~k^<(Sbd^0Cdv$aQ68etsutH zN$lF5o@k#|`HoUiQSV$eSH)FIpU7e6nlhy1W_SkR5)Qx#o-NNflBQ#1aq-SJc5QSA z?5#AgeyUav1aW21k{jvGSD)O(D>pMZV971C&%c!?w`GH*c%3D$=gI91-oWSI z$l#8k+$nc4xH}{uphGyiHv}s6KBjvMgZr8P13Y?bHh8%YvJ4OL*|+oB!1)eH{HN358X{jhw3<^4NLp5z^f+7HVSwEFG0^XMppr!9HLlA%)qd92cdS{01I;s^_1fx@MEc#_z4n$$CQ*_T`r+Ro!JnW zk*v@%oH%hdMyJj$BgiZi)3IpO_PA&i-ez#8)&v3TFglrmop5Z)PGfv_o@pPKwmKhE zJ2j>|Y&f9bY0I_p>^ZAVU(4L!^E_caG~7#VNJpEvD{O)5u!*IgS$a5{xk|2qhL0`B zWtU^JcN*!PG|813?aP+unewB?iXf+e4_Ug-#n4T6lU$t z#e2I3`n!_!-cv6>Yj^ci`+T5jFi}5bg7#;rttrzR)VhV>9A+GYj}?|@tWK}Zs)jK< zQFba5V>UBRqZDirwB~bu~2dSG{DhF%NUsx)?%~?Il8#lqQ-} z$DU5^=6dV(|E^hV!cydtUSl*2KBF8ql`V5h?Q4I3f`PKv;@EdnTNg-Cb}`3*c$(v! z&(Nj%B1l&bqGsCZL>t=JonD0vcWQ%d^m})PNTP}ya+n+Q%5-zAmo%^G>S^olx`ozH zj;0Q5Q4+hQ>C1^Tob#ITQvYewr=IrX`v&e>jJy&}V2J!gGbKkp>zD;ObAqu&qUDfz zBw_3BN_0_EoJSgW??#ADz`E^j>%=@mef`)D0&+h>?Qwq`CVhpY3?a%LSx*2c(B~jZ z^f~AneGXDf$Dmkr40=MxpuQ02kXk}aHrKUs9roR?!BHKyn%v4?UP@%FOvpfd5YqW+ z$$eZb90s0&6I_TGLbN=}#zmXbs!7j4asYdwDKsI-6JOl$G^CFyNLB^KLm+B;Q8O>(!Gz_A2ls7Dp z`OSdTGXEKwneTt$DO^XUbm7I^Xqd#@!nFT(atoUz%q`5^!X`IF3Aq*ER?2dr@UW6H znOLwd^5M%M5_GeLu{|wC6wsZL?0kQzwh4L)6`l=R>UXI2 zPWiQte+Tl1=adSy$u6gHhzN?!wf?B76ek^%*~Twf47jl!mYAj`z5Eu~LlwI%0)pS9 zP;WuzQ^Cq=%3OtFl}wX4kR?KBcT(om=gRzb!*U_6Lp-?fpjuRLP)6c~?}O?8?qMli zZj~S&;Z5E1z=?Kb{7AA;&6^L)HSn@&$ZW9%eko zFUX5J_EbYoK)NBpGvjd@s)3wMt8{je%OFJpDsh+uDL@AlEc2+zkqI81`J&h0^$f1GAIh++N==pM~VaVg9qHg5N&5I$M>B@$Fd7Sn48iARd$>UeZq&= z?rZA=T?GPt-)&bK&Dbl~xYN4bO;Ed|1? zK<5~)K!7Yur@T-)QstIlr+=|5v*Z$6fN4B#l+kqc$rrB}x7vF`Zt>o8u3E)z^(3f( zlE-Koi`EN(9opaBcAyse{x`?AcoU?_nxycVNKT^33{a4FKdG;wfG88U3m2vW1@h_# z#xj{2mrN15s*_;Bf&FcL{ZX8z(T~OUcHemAd1)Fdk#tX|843cI{{OfP(mP)cj<}%F zEfKV|apuM0fx>-Ehl*)P>M#xEP>`=u4n^A4n~2CrCea0$O(_@?})|K`lVlD&KcX7UcU*_&!Aa zq0FVgFRJwC`+WKU%amUqSWqpi(6?xRP8BX2%1(g@mL)%;tcb;8T2KSNmBuMc9Q(am5VgB}LG4E8g)fk9u0NE{&?A?SC+ zWBqcIB{y>lH*&EYxs}4P+nDUNG~@OCZkPYV(?dbL@(GKU zr)%WafP928EKt|T#~8p2^%L@UObF@NQ?x;SN{(9cG~Z`rVq-9i^!G<^Xn+ z>$Ml!@j(Qla?{Q3-j&;33S9Y+LjoA75Llya9nG*#jP^8W^UWAMVUnsfO$|cv#7br^ zxMrPEZ%EY1UU4BPUo zk$F6KHcWUMnv*Bs-aFky;$_!3JQ`a@3{+CvvL|3vZE7a9DseBP2T z+45xyg1#bOwdHFJzAigq?w78LPB;8&!LM_Rua!eQkdaqN9h};%Z|k9%pfPkUu1*}i z#l5@s0wANrl5g19Nq*jzZ^^fzpwx_+p}1dDsW$eNsG)H($5~1E-tV#-eNVnm=@P#4 zWwyc(ZTXS>nDV2a+VV37Ka!u@@(cOp>C8O~cPF;RO)!TnHkQpL#acwf00N)i$Zstp z?)d_9{(~j|YRkXLA1Unl(*)9*f2NV_IK^MCq$dr4W_p>7OHIb<)3K2~Nmh}D*=g8_ zE{oMQ;c&V94)fFS4c$cP`LMJFG5p6w8Z*YS%tC@DB1B<+!@4sD+YuvHp?!sGaAH`U zDGWA2uR4Y%F(Z?+G^v=}cH{o8cEF}ZTXzFA6jLSTFd){k44s+Bn!tN?C}VP|y}VZ* zyYd_!Z^8^uTG>m4ALt*5?!&v|LY)LQEq4jpfMzP5Z-x<96!>KggZltgfQN9+;q9ii zqPwZB4|~RB^BYtzRuRX<&Lhqmg-R7i>eALP4kLQm*-Tt0MSI(R*0)*Zu!`xOY%PRe zC`_WYRki7|t~r&H@|tx_nb|wYU4~imU}@Qez0Clcz}aA*t!d*Kth)kdL==mOT|EUt zSK80wb)ylAT_FsY=`L~w9JyMwLsQNmtkTLj5>|xTeVyiWv8UTM&_zG?v^Q&pf{&Ax zlC>V2u~hG3M~@Q?sZyZ5kf|=2BdDBrhCI`&CLfngFkX+Gm zBUpkw2hpNq&@DO!!m*A)z33PO3}WuATHrTAX?a8?_Gh5yrBq8GRB15LHVIM(e`yBg z5je6KI3AyTT8fduJk&IB=a8$iz%C5d!;FWfL?PnU2FhU8l3o5h@xfk;yOSD#B^F%n z2fJ}H*p09VnQSaVrYr~laGHZ_7Q0k_5<51F<|*N-05)pJWZFSlkmtwN(f73E@- z009Dn>BBN(M;Wb2@*x&DE;C!gfE+6vIVAOb^GPYfzvg&WoG{V@ut5V96I9?mvxa1L zmA|w?19(A(kX7+v36>GsET6o~5*(fwk~w9t{g_)eEc1qBKDn1Lw78%weBlrnzAZQl zwZ(SIWGr(}O~3UxSbZxovIZtvffnP&dmajq z`69N~$7La8MWrwpIwUqsxXQ!e=`PYJbWh>+FdG2>sSHmjDj*?bF0+sax!z%<2d7<| z&yZZSQ+4ucRFbwNBgpuyc2M0dH7A=W9?aeXGVYxaY{3+{Rd?>%CWSi5GF-5 zy1^an?w4uAyhDg}lU-8yxGdx$TB*`p${m*FDIdhQAq5%67JdQu&CXMdhGYedk%GV< z;vf0(T~2xN3|N^WPp~7RaT`z{vrV_EdVrjQAzArACHU1au@9)KV8kEE!Y5UR%1%T= zj|14PE)se!P=}W!l%X77kKc5l%dN72F6S?M@`$WHE^AQxmxV7MlC@>%BgRaYd$&qDc{2xV*UF9mVfP{qeWy9CD4*XGts%D9tXC z4MEsN)-c!@LI4QdMZ~{_oE1p?7SV45M891m4ZPjRpozhiys?Ex&6aHC^V=-hPEqX! z?VvbJ2gR7-Lg?n#^73^dh(@s9sX34GqJrWm62hXDc*&RYx-xEUr*~_ErAxQ|x zKA!i42!v|M4FU3B7VwEh(hsF%<~axrWo*aKjIcXh*YcHv5Wf!`z$T>+P@w?XaJKq6 z{e%126wwYtU}DKihmmo19P*13h5TM1m6e8xnMCet(9Qo|4my^~j$VMW_h3T?YACjm zqpZH8ml*Z#JudIYBHQ5|8~XUP7)&5z#|<{*;TBvXm6~a9LsA6x{U!9FdWoz+zqMfv z3^vWivmS`(2WvSb4H3g^fw8-a?*oW5fq`y@>bu-#Q|}#&J-OZ8?tQ4*CS>?D%e812SXR2s2ts?ywi$0cJu^#F~=P(^EuB=bdi@Am&S4zZ)l-h4`4`L=U z2=&R>dL;}XPV8q*=3zpCv3FyiDWIY z#MVS9jbzEQKT5Y5^+)^qda-YH^aK-(B+OpKwRY;gi5gr+PY`W1R-l)3oAOr)047NU zXZ1zF-6qC#wO6#ZeotGUyOTG)*U`%JULTDTf=+jqa<{YJkClTEFv!xFX>kAPpmZdQ2SBlfG^%kuQtd zhL{>88&Fg#J!P)~6>Yabm4q9(iW8O4yaE(-#P_(&sEGKNa<_C+0#M|btRbI&mZ-at z0r6rL+z|+VYjw;cvpLGahhR-{3V0O7Bh~(T{XQtqz@VMG$j0)-w_fIXD>h)056Oj9 zun(VlT*4s4r-g}7!JQl7uyF`QHSQGib>U7LeCz=5u>&Jd@Y!iq!6zguKR8mwkDYlK zJ{SD}315uH%)vI|HK-5PNmR!IJ)0h!_dxo^nA>iw%gzVPb2er(Q1XJhvKP4xEo=!x z0cF+*2>#h-qY~s|=sd9mPjC}9KU|DwO0dH`2>l!EF~jr1^Rc&tcGky^%Yv3LkQz!y z^b38CyI?j|F<#HkLbbRIX!(?4$6ID})H0sbsRPhtbnDl%rznRS*ilz+FlkS5@21Q1 z3t;!hA2p38h?Gg(0;u^R=tm9)A!NCc0qpylY2Vi@2N>MK0Fq2VsDuavZqc}}nIg<) ziZHjy9kh97m(%RI_2ACk9+fMWo|zB}ce z3?Q+*Q{K(sAcIF3Kydk9TK3&1k21r@EQ%}V%Lf89>6=fG-1kyq`C;1g&8I!z6O>fm zM=@oyeAJ?laxsOJi)qDoAJK9b%ad7`b6UV3FTtSiJ~=|kIR7$v=78w(a3~Vg&_@t6AS>Ud!L+S@H~T0YEa$x%BL(s>YkDp8N9?hpAN`p zEJEo%p`mmqVE;0C7j^ZUqJ1tyox;j&g9z!6o+x>ysuX77WUe2PX1 z@aC7@2^dK11?Wv45cvsNY>eOHvt2#=2M3zk=-CqVC`b)TcR`ROGKXWzOSU0NYWvp> z_Io9(uP*uJ$W_N^X?JE5xfo%L?@vdJrIfRJwm6*vfzh>cjdoE&k0UsWN;{>9E!t_C zYlr1X@V??~Hr$=0r(JB>DQz~Co?oNAk61>~2k#a=vJ8$e?P&$iowBdYHMx8 zp`oR1m5s+GtFE?T!`dyDnq;fVY6=Rkax{vorKZ^`S4C`<$6z{ylp3HE@T3I*AC=!G zd?I|w^bG)%w1}U625)|r!7N4U64a=g!>l}|r3L^>J7GI&>@nw!Tkz@bK9YAkO3sIr zvOL|A+Ys&D7wzb3Ylc(EuJ))S-ykPL^K_icMhadIiAuVBl2c>mTrk$OU{2wEwVY?S z_jY3=9-EjG-`H=;xVXnD^Wucmcw<^~7gsEJMq%oiC6QwWicK+rm=UstnkRbS3ZBM- z&DX5c5=T}!H(oHOiFVY(Xc_{mJ#LX=C?t)-9jj!Y{i{tv<^EnC*XW-`KLFvneG@T zavXP2+{(JGKbgGny-%}9wX^>z1Y@@qggY37E$ zu|)&@BO8dG4d1l0GYa8+2f-40+Ce$xr6^WU^d^oOpj=inyY)~ZsNTFe?WB}q2%0Zl z-`3r|tF8U|mCPjvjl2<@sn~}YEdWrQ3G<2jDM8Yv4$9|L&tP)R{1PyGoe^729rD`h zQK{L9^H5!ew}okMcUR|NAN0|BF{&z0Gu;|ecyWs7Fb$@+kd1PVPxTbWGu*UBdwRP# zbr^jGyQ_ag`<`CtH?>DWB$uF^@$;IlZcxK!UajqM-N4cdK`a+wacNdy0WR{v)Q=#Q zp8q)1fY;IIa0t-`#;npaLdR+R>9x@$WkQ`R)BN~ae9YOo|7zAoc-fG`8Z$h|h9DZ^ zt{oJojzQw;7}TkbL4P6+lVsKByC8UFdJw=m1`VuZkim#8QIs4Z?84a<*v)f~c9|ng zhu}Pe67@_(^C*i98fzHVPS8H~8TL&!Ws<>@w35m;EFYiHsK;dNHAS=ryX^>Ohl+6oa*aq4q{23iWyILJ>cp=oywOYR|=RpmP_c`Ypc^kXuE20&T_ zza!sIBe3jKlEbKia@48AGILl8mix-4%I&c6!6h4(d6c8uaNkAQ`YfJIMM+uQ*<}=} z`>yuwMD5)Lqq?#@yrx8RZOW>$$hFBD0dizZRp67RUco=f55RILyDEqnJe|YVQ{ZL! zptDX$zX(KrjAz5Dh4D7n`bBYd9`yXai}UXS@PYBKV7WjZ zi2i_@&M1P~bq;F!_b7Bm!TZ6i<3Yw_vKKL`{h+k*U|8lJg8PCaGVi#|2Z!ncqc8wV zzaasy2Zm)-lPG6BB4#xyMGK%t0yh_O6*-M#! zaE28L-jxf}kzuJqhkZgeACj&r04v5yzmn<>-qPoXoZ|C9cZ2NwY#!(D$j=_Bve{Dh zNYy0duR9}AG)I5Y;n;n!&GK5pt56Xmr4fvpX{9XX>Y_c7;2v1JLS0~SOLz?m>MP3h zW#r0bM`Z0WS%(VYpbGgavwf9zuB=}^DIcb!^H`D%Ra5e(0KYST%8=AlW;5DYX*1fi zT)!7ZvJQ$Jfsv^(H-yxk~l`vC6GWu3U^z-8B%iYU|5!kiUaQf#{u> zfXLxWd{=+$UAN&~WEJn!Hm6w!F&KxW{?IFbtoN-t^vZ8xWs0w9G~lBs%auvpbW3ts z(2-JhQ~I}~Em;mUl8WU*DNQOZ)$1L{=x44 zs1~{>sW!a#vdt&Hm?^^Fwday;T*@{No5KF6M`$|=$8!!r0>cCeoJQS+To^L~InR=O zkf<8UbBV^E%t_7&qV7c4yX|R-r!!W=Y03*CB&Ju;GG03*Pfefh6{MXUHWySX4Lujf zm`cVKw5h*iLlRtMLr)2=7q_2v^Pi?r4iKn^W-+@8ONy0Tn(mFB4{lmJuU~HsTl>gh z>>p@t-_;6jg=s0ST2i89Yr0I&rTH`ki0XBbt28R;HRq`vp^u7J%}@6o36(Q$e<+@( z1;!n7Y&Zo55AggV@?SN@WJs3aTy}kRvvI0BVohX(Oz4YGmG*P5yK03Q$Pw&)v z{#b<;r<+#NJVNP4S0_Mi-0veVK<{G5>4+)a#N+3r!%ZGQjScKRCmx#4f<=v^^b=1G z3}sE48JI}WB|xk{Eug70v9WQ4`We_}a_R}foR)HLDhCIp2ozlgM!Eh=)XUs;;g3#T z3mTKZt8qVFb)Cyka)2OEb+M0@%3M;`&mX@F*_)0hk{MJ?IO>yVUwO#Y5Xu<3kEp5oCF1^_#K zTAtzEAqK}74D%X#o(`&{LPYA#xN zjh3?{xfE;qCCbO%6`RdNu!W92N^4@n7&I~ty^E+JRqBeg9VppcN)FSney;+V{6BP| z)y@j3N_>x2Aco>EB*#F`0T=uHkVH%PiVVK-wU)}X;hxg3WOkfFa`bw^P#%cJ#P)n9 z%Q6l~gO&<80%|R0ccn`SN(Oz>Z>vdiuMOoG;7G?T&T1QDc{veax_71K8+Z3EOCn=)m(xV*pyqhpXh zB;RVQ3y~*$R+ea=m6j^ARk^|*Fuk6@8{l73f&`)754BOq!zD7l8tB-dE#a=MaSXQ}n{A-Ta)HMZKQ zfKTJ!zXw{%w%Vj>ZE&M8DbI{I8>rX;KyAiq*M_dm6}GBV^$^DFZ)-KnM{C=_Kwqnt z1)ZPXwbWJ(s?kPlN}QO&m6N{xbT3R8lk-?Iq%2m|=j=nN9IMvO`Q3M)SE?K~%rCBwZ^9BJ zv940!1ZZ>E6f(wN`eE=~WX!J(Vd!AK4sQTd0-*_J=@X3Q<9e7*UrD~Rv zec+y4%#-|tp`+bQ8?h}1NPHl8ZXkO~vUd%3#=KviwbI5p+o=0HSdg)EH?ti!@BU~M zw5nDP(f|qW^$x7$q+vG`HDMH|!mF;47Ih-E3dY#AJLbe|omj?kWh|`$=ID<_>epV? zx^`Q2ZDVWm+WMxt4Xs<&Zry+_5wtx#W6b4aorQ7?$G(A4PBJQ72<;Hhki@!0gPGA+ zIL^*NU24iGQY2vD6_{_n(~KDJt(s0~jSDDdEZFQRjLWt&wl|I=ic8q@CuU(=nbNW) z;*`(X0YTP)%@H=+qJb)>Wz;w0hGNDCZiLBKPyF z##Z~Oas<1(16&_+EUB=t7e^VS;&qJuo{p)`!0Xr%Ar3=M+po{Dk@vFNZ&Vp zZo}Nn>Fd~R0p2=?rl>flNXEEhy#r@gfxAf|N*!HQWooS$pN1uX2tSKR))oK`fFcbU zzao27Tg-%7!r6f88ySYRQ7P06v1LC z0*#+pRA?!RSWsvw;^EAQ)d2u)KF6$}8&t$#X2gdZP~X5qJ7H@Dq{5w*S%+S^-6+n? z)|k4*2A5)3<47ZioKvzHz!Z;YM)Q1re_kZ(Q4O<@Q;`_~qVENVG%j(@vvMKuwOFXEkcBdnIDk#!%_w)k70sYRKV#l4vxzrXxl8- zm=;U~Ki!kL(-6Yc!n*@@C z6{bxD8}uts*H>T@j2M3k4ukJC;{z6UV7TGh9OSRZ$1%C|39(`NR`&!jEJo_h_0q%e zBZu~dbb}(%snFqIoY=l#F_>I4t_1UcI$rcgJdNRYklIf}QU#B|br@}{9$1ZV^%?|g zDt(0+?XWn7Y2YFEK6Y#aw3dIxEh)}%l*`s zt2smvn0z3F1J%wr+959KR^%k_xK^ZSQnOQjvL{f{|wQ8RPX4+o(7qDL#;^jLZit zJ1>|aIvILT(^N)^6jV)Pf@vdFx#j}``U4K<>c@+!BD@BvR z{HnuwPhn^`K=X006ZgwTbiH2HhYr!FZql(|y<5Ep=kHPPXDmNd&#LEe{+xQAv3yW{ zU40AZ-%{Uaj6d&00#1w5eb+ilO!HZYf?;W))|+2<;M{t2;PR0M+);Woz@U~Ax*W_! z0PaWsWbDnDPM_UzaRf6IaEs(_KJKg=m(ON9UWeAcTEC&W0dJ@n(IDva(Gyw648p{_ zEi`KxX6zYy+IGjXE(<#$b;eL(+cBDV>_BkUVV|zqyef+|YmETbNWZ)EFmRQiBP97y zQ55`&b!>sbh$_YJCLMdfB!gT=GuOgbg>kuh>HJB1?;n$?? zJgv5518>*x%0>bSyQn;XAfp_^)m?m5 zDsd7){L5`3vsn_QW$aQ*I&I>RO^oUrG$XXsg~B-?V)ano1ofhPErQWpH1rBEOt$u3 zAMJrn5B9&17@_zuRlR|Qfq^O@!vR6I10bGybBnH7Jg_HPZ1&DL?CTxu+@miU_}Jn& zbGvwLQ!TO^B*>Nd{6q*6F!kcXAY<-P9c`n7w)*kSVxxO|5?IcwE8|XuhLZ^F;;@dv z^fNpJ*ilU!q)mdf`}{aS@No4^55i>UDq4W+i|I5SyY?(iaZ>Pk$Erh0DGk^=yZYMt z4z%6~n|^I>mC7N5hf`<1O7rQ0bP%jZ$XSELxQyWhA&=7s7H)?fKn|8m5Cu>k#Vm!R znRJ^1LSY^k79d2-(vK$))8d4$875Je7Gap33t=69J;RV7D8B zyQL~igQk4j3z`BN%BDx2i=q9r26}522n6mquYlh(v-ix{i$ppVk%hH<5@$oBy$i1^+kd6_HCqZ(c_Bb+}ZGY?5lUD@+eh|NLSNdT12 zJW7Q?tlY3ix(b@d*b-@qnE*mr=vn~kOjHA8Rk(lS2YtL@u&e!g%I%XZBj!J_C;Q|0 zYW_AO`|(ZT@m%9NMWgH>mIa}-T}TH*MZS^S+3lg;PX`pU85BcBo{rMz@MJE7c|4sD z&qLbdP*CH77*kZO8s@50rT4y_nz%|;R=81)SfH~5 z)p9^^OhiAxI0oUGXv?xZUB)pA+N~T=_9Us-b^sxpG|swoPmaC0VaRJ-0K{6rc?p0J zAjBkDGm4;3Dh_%KmP*JsT#8sLlwCD3eaEwu#b^!pJ(`5SZ(`na%~|eClJ+ES(UP|k zSPrRp&qXkU-Bt?3NR~4+CVCLqUPU5|dFH23y5ZlmK5gLrM{HRLO`X# zNHhqSMEUSH7pV5Fo*T{tGaRh_Ab7NgUis&W7Y@M%U8v%P{Lly{Yiq9I>ia%{5=;Tn zzZ<354GtJ%_HPUqr;Lvw1;6@^aOQ^0HKt^6hv;((8Dgoxt`= zfF+*yiPE_a1~UtrgB{8BD9-he)G%gqrX)RH&Keg-#$!2bZoZmk2a>vudHS;Pk0NNg}m4unwPTP(SiS8fZ$!NJI? zcmtn(Bk$Zn3@>7s(l!!VM&zCV@xdZ;ZwN|q_gQpqRKPn0^l(&5n6LuEgx$%YfLLL* z#0smGhj{vS9zD!5!pqS{qK3Uo-fa<|Q{4#nu zIzoN;JE;%9QI5eW4e`L9wdC(p&9h@*txRrrd=CJ~L{rz*bz=oy@~kFXolRS_$%QMb zQNPA!_+0V>TLU-<$nL!3Bu~Ve@G7&1T=(?Y@E8{lV?|B2Ish>Y00*`bj;N_(kUf&2 zsAm8SBoX`7XoaIe$`_=(kuEv4s7zx5e`&!4bP2A$%+wS}$z@5rIH#Zq%eiwcagC3C z5g{=gZrcAY>}cV13p>DaiZ^$>bZ!Sx|L$6xjvy4xzmmPOn zpCyzZvLD6fa@=ffm7m%2bNPiOzjS)80EF z`=NxDBDN3J9njeyYL=qwtH}&`h#}5xEo<+EM+gv2(GK0oO|F=HgRxnK@KR}aYO$WU zI5yUuEa(s_9V7Rw@WyAPL8-$!y!ISs61O+{IAiH;H41(X>YfRFS`RC@=A6r@VGmKM z9hxT9XS6VLKj8iep=!>pH<4J@1w#)Cpa(fczGPe-$Yj9&iH5}4(t_&i<0D@6AvQEh93C2)Y&A8Rh*`BBwX$S(9}KH3DB~(9$+kj z`$K`JxnvfL)roM14k?!~lAUX=Q!gz!+m6Mzw-0q>775QaR9hGLOq8g4zC$Odb*|$v zW6hs%72m(7t-nDlm-;AmfMP8x#P#l?E7g<*0;2@;1n0}sQrfG$1J6lpctnYAO^qzt z!OZV&>+fHwEh9tPJ4Zi0IsRg|dY#HiLl95)uFzbYGts3m0KDaKB_Zf7K4bQ4WJuOP zuY&TzI-pH)ltDUI z$DkY$he&xLriX8k=?Liz&MRt)IU@i8@7yLL0rjb}=xV@W#`z$mXmRdGz{aDDCU_h? zIB@Nza+yQE9f$z3}QN_~|0$*##A<3_Tm}gRWGSTCv&=Fid z6n3VLR6L1%rb4_%P9nb##4w74vMU=e=e2L(#nf+`HYB;L4oPnPafv`BFi(T1O$Uft zfmY^=w1j6IlYFAmO#={JJyehjkPI%?sI3=-?4}6CnBL$#O-3S=j;HU)_l-byl|dHc zkidN%`HR<#<}7ZCaTZT$om&9VfqNJGyt!3D^Lb!4;`4L?$=W0H5$_0%XrALS!*k3A z&oLVSUw(YA4PK)Se*v4(sx(o29H{doL_ZIuBEVRIWU3C z8+AlIXVg3OoAJ`wRAA$mquPpHAtR`EQ@NUz$p?vAfz%~QV>{Gz<|xRkf>coEcr6%_I=GF}Cj zkP-YWRVoh3^*p**$w^s8&MOjK!uF{GlHG|)8>*KPV8A^No^p0%($cEQ`IDcQ@`F;I z53O``oeBdlS5%ho=etz?lnfQFJSNMHkGc%mapxrPYEK+`IU&3KyWRNQ1XUD=1}CjaTdRw4l7=n5;2b(p#Q8%2y&wCSA-?ei?fCuU9?>qg|J*RmZkSx8io=*7y|3cFQ zs@$87$|O@K@Jh_9xJ!vH{t{)WyT9~G^#i!WAE(Q+WpH1a$Z8lR`kYJPrm0k~3kNZx zr-cw09Jm+=9L$Jn(-Qe-5^W{DA4^G0d#x@#i2^wL-`T%-llGqc{ zZFt{2r)@~e-Qv9JC|#osfUpU~4<|}8tmIYQUK_FMtF*~>Ih>TSjzj9t?{nt!jSB`V7-OUadK8`x{>EQPOa%!XI0lo+G1j6v;+Y~uZ;1mne zEqRJ{cl55VD$H3YPJ{p|Li0h=>>p7r?tG%PG$wTE#UL_jX&gkx-h+dPWHMfhqqy^E ztwaGD4F+BOV&iDGx`cXt)oFWVbV(^3GtUmFKz$9z4Dv6qJP|G zPS9GJs1=|fO23(s@0*DQcR-%9nOnOy5`* zLE&zef3WBtYbxDiS#r`MD%>Xt2=^)Z$86}6oMP%1H6Yy0@@YQs83ura^U3Ez(2@Ws zoKLezpf3XPrRwIASJg{u(MZEHB0Kn13@+%0~X)L8!AXHku%3zQg z!pnXiQa*ejahiDa_aT*~ES?7N<%(cTJjrHyn@5u{E#H1Sk0vvi5>h#8Dhi^)s0#&J zH>7ec72)MPOHC&d9W)uDY6gm=@&jsSKo#Jau}>AVfF%s(u#~4PHJ5oo zE%1}{AJ?xgV3rqJYJsH|rkV*#+6D)D_rXI0E&2}-S*f2ME8;{e*kQB{(H_hU+1k`g zA7g9MF5jt1=5_Eg5q}=k_p3y`Olvoq8;0R;Sa~Y7lQoY34dwH7v<ZIXa!j3V64My%L-_JQJD@|x+{6XQ zKCRY8oa`RD@0{vh@H`wI=xgig2UsDWF{TJ$(RyBMuA%s`ZPBYr(mIRfMG4JS-Q@_4 z-hh8O45}b7=nI`?(OJdWqqn%ol=XIIxF$&bGrx_wBsjY*Kcp?x;g5Y zTRBi1NlbE#8^U9Z@^WN`zTRtkJe9-J8!7t+dun^Ors$q|&^1ZXszB+-lIyA~3l1~u9 z5Ny_Y+*7zcJSJ&RQn9wwGFx4uDlLNWtx%WR^vY_>A$bD2UgNKygaK~Lqw<*cbx)7> zciBKqTxqLSYPGG_sLKo@qTFYzbq*$?4U>b7mfB>)*mScE%j^3H^LP(I7jbkqj?@)s zJfa_3s=-!`s>!CFs0}-IqUBeM$>ulM$E}jM={ZwgMwr!86*~rX#ZM9$BU;{w_tem~tJkX6+3NLbqpfad@CNlpOWk3s zJJnr;YJAXEcPli`o8;YR^h9Z^dzos(_`6m^bN%1|-LhAAwbLIMY}IV_W`zoV3k#ch zVDLtSeVu@nyk9+FDZqoiO+BDwPJCx56mo&k>%*h2~*@sN7EtsYkIn7{!E z;LLZbciDhxsATOQwB;~Af8w}?Xx_8Kv2?YSz;1w6YifPB)4ASspC>igtYMrCrr4+n zXOwDBiMKPy<|S`3BcwGw7xNev@wI2(WDu4f`;2U)cGYj<0)=&>g*I(0Q4u#I~J%N|+AAnW~T;S|)YwsEW zN+q!ih^WT`VmGRxvT@0aKIs5bdbJrHtkO|flwNn3Q`|k#rna7rZmQ0dC+ybt_w^3+ zwgctc)UHdSI;pW$D)o+q)29Y$>b}kF+8pf`cfiG-ZW?sQrWxD1fySUVRGzM)|7YN+ z{ts~r$)2uvLq-Y9e^XZn&GEDLM7uiopzHgAddPi50zj)fm7U2|=6{ zUSzEpNs9-anFB7Gm-yNpY<7Krdg6^ux*zB}Go5KTfs|ZXWBSLUls8i-m(fuwJJdzv zdB8l9zYpjt`v&*Lcki{pUhKQE4eU2C44`JkX;FWQS#nL`lRB@vGI-5ED$~ss-f6t1 z3w~p|ZXwO)5Vg<(F<;?MTF$OMVbU~>ncgXc_Z6OHDDBEJCUzogm~*6=S`%05*m9{= z#~f!FXLgL8wJ*A_ohZqH1$6qXow~9P8yznj9z5jK_{N^q$mO?9Y9H+D1L^9XCl)l$ zfiuc@Ng@>IJ4hutzGS@~VOa)r54YQ69y29IrC^NJ?8Dp!AYlmpqjBBRbQ*r1k{fXr zw!~x94@5i6KuJ7&qS)}q+P(g4C^+xf){9{wUQnNYXb|8O#W*7fuSO0g=5N%{cjsLm zcs{inqy+5$0}wY&f>;+^2^@vVCPAD-rUv2+?qYQe(@z~^PmVaOfe?8g8+Cmh`*9s( z*RNyj;&qHIy^gVGL_7t*hX4(xil<9)cd%G|3&32tZ0t zN-m$suXt9b1EkY8-Ix82MKZ zV%jZL77dPb9?|Y-3r6q&(6`& z$p1nlSm5SQZPAov#|IviT$817+)4n^Nq`Z>H5*=PQ81cE10C`OKto0VMM^ZoQfdIg z`Eb5f`mB^?2oX*4zy_gP;5$_zV>MgN)8`bRf|KKPg<^Ci3Q%*=cIC(^sL+6jscLB2 z$45qwle!1;Sqf5jA;qE>fyV+3M8cqC zw-fM=rrAQG#nc`+tHY(EKm=(O*8s7*H1 zV-Nyeb}2{jR5sWnQqDGeMCQjE5~`Gq_%$Uqk#;N3tf3*d^rBI;X}F^nQo=K?x`$_o_6T4yBYeQXt`-+6-dsZmj$5FLvlS* zZ`Y`n7^XWaF+87_s}6ENo|LQbuYnVYm;lBo##0u;d_P=)N3xy^RQaL9IwURme!vPd zSB&3bxmu$VZ(-rC;cIww5Y+>=yJ-PMhn-X{`f27Wz*-{HokP-gP`(N0#%(x* zcJL_)m77t{R~oE{bn_I{!S#GK{~2-SpKMNF7Z4vAWiK=e+CC^~LoM9fDi<=@nVv=x zG+>3sguu7&0-{8f&$kAc4Zw|U9g+?vIORB?hAz9`x5`wHAJyX@IrIuNwf$16fmZ=f z1O)HB`0|g*Q5k~TG!zivi(2sezK+>b!OVB+sT|#zD@Ac^#$jgxB&ajjP+J;Zw$jIF z1t-xd?822k_TWlD^J)O>(un_2nV+BaqS(hJiq&p6pNl|uAG1j(j{JH)=`7Q|t{m^G z9uhqq(cn(uO-}bOnOK1voKOo=|O6T?=LNXM%KG3GmtVkW4sV` z&N)%9+EeD<-#a8XV2t&d*+7wNY6dJodFZItAT6Vd7l9(^Zz)CEfgu?@CO1AKgtA5l zy~(^K-lLU#B$mqo)7M?fK3E1-7`k7tw@q~ZN$9`@SJC`5y&f0U-kmshi71U zps5E?!r)Dkv1f=uGy9|HScdw^Mc3gX23>QikQ=Qcr1-de!b#z^BT;S*-ik*!I*BLG zzo{m|x@4)P$=Z14o(WeXO1Fngy&gkzm0>n*9Keo$3_7^~3DVE~NPplo6? z0IklG&3yC|HWs8b2ZX;v3?z`5Z9`BUwWy>7-qwG@y03x8>ax!+ZG0HG|V5 zu28)hvn9fEoYDAzR9gspa#fn~Ok8am^Qe=Cy49osu}3HWC!WYfW;GcZ3xyEbL$s0e zn@u^9S!s#MG%sLrr`77a@UkrYthzGT8U|Kp6uw_(9hV?Bs+x%u#{OUuHffW9lzL32 zjQG}ojLgv>a&T3kw`U$)yZo5-=}GZ{u@lzjq(60_;ev#Q3yx&2(ar~ER)y$%AT&~y zjg3dB5P+sTGFBhXF2(Kzq@52asdVhX{Y9^imta=C1?RV5!elH^KsGxuS~g%-cIxOj zK5-K6+@wpYL1%Nh`>II7o256LrQ9~4tb|pK1I_->3pA?>TTvBcVS^)8Y@LX{HoYpF z*Rn^dXq}qD@*lPjhn~XL@dBXaE(JAZ$tt-FMY&AY>zLU3bvUmB(ZqN=>}7W%-igJB zF*}I?o@E=A;*5?1N4(WI=#qf%gq{v>OGI~MnT z_a~sc`K!m<&taAIQY1;#_lH7&TYg;#z3*rTiCoAAZ(kqG;VF(vSBSU3F+e-O5}4UMhq*EVh4 zwgq?1q>0nk=B;?RzP4dwCVPat8{nO!N2cfuYic*tRkKLQBu8JV-%#JUrKPnVpX1K& z&ZTY58@4oUg_c_4{LY72dc16`b9ZtUW-&?3c6-aV^RvL%sEFFe^{v%cqBgP0Ij0-V zCMnxFH8-cYXWKSxY0=3OuAo{WnR3!>*}!L-<2g2)949&Vn_HXKZmDNAoA;ZRYOEnF zaN?zgbh|T`0C9FFKI3H1aY^d$>TMr@bTtcF0Gqjai3tJWAPBH0J!dySumD&_~E?hW8eTF0J%32;d{8&_&8kN>OVZ z^F@*_yN+4&lCIag@=Ioi7bawRWbQtlSr*V_l7=rlLm)&Yp^TVXuH zk1(mJy0fdR8_GNGb?lGvs@eJ(&s}^U2zisXi@H72Q>LIR#|TR6F;;M>Sm=xCCw5bV z4ez%Wtj8Z4&Q$Skt(NAN!j#UrhId0KicKl7baWp3yKZic-*ZLjvr^o{L(y)N)NQcD zhaHi;`CiX0)SqroI54C)#uN{eSni5;t( z#y@BSjsG?VNOu{JF5}VVJi44mYk9PmN9%aBjz{Zxw4O)RJgVl=1|DtTQ4No3cm%Lr z26*|z?F~I*cq98y&`ft7I%jwHwgDATdw)o`*TW)P0tx{18jSPig6M|}Uz}xt8q9}# zh4}dboG@SOAhBG36^oL}TQ=lvx~=S!2$FZP@>|7D)@OK^@} zfU@VaBj^}?LC5G0I!2GsF*=2g(Jyq2uAyVJzmC!RI!4>;7%i`3w7ZVc>N-Z7>liJr zW3;!9(b|X?p)S!w5pKrWXfCe`f~N|C8ZkUW>9`S4l{^QZQpaFb>UbN7ZeHI3{2<0H zU^+9t29Q3CuXEzpIB~1&)Ypj_!~5+{+~GV2u93dp>7<9(9TYLdvE&rD0wl2y*Ggti zl~-O@z#u1Z^X-NDAm`@Wi}b;an{U^|I9}21WWCRMb&r#EuM_Wg;v1Zz^f__A6Kj{L z$md2UpPQWYH#_$aIPopc{af{Uhyxd&65_DcF$S%UF=Ta&0jpySR~=)p>KH>+#~7$O z#xTX_0v0>gVkaE3|47c3oQ*l_axNa040y4?(MDV`XTF?mIW0Ncb6WI0KaY4tpJnOe zB{@s=nPu+eY}aRjocf&2IZZi$TS1;deZ0Xr3x(k((S`@tqcV9|rW|$rXoRs>J1V)u z5;-b)!!rFSJuc=Sm6^j*a8$4pEjlW*hGq6q7m_GxKk z8WK;TA@NJ{1?KrrJc2dxgR~}okk-Tx$(JqpN(iR%Ukw2-_3M^=gLl5p6POdfB;N|i zw}Xhk!;|k?^1T2JiRZ}YdGQAUc{wCMq#^N3@?+);YvPyWr@Z$w20stUFXWdD{)NG> z7{CztHv#!AZHZB`U(l-f7qlw=n*0HPrXfr}|Hj~tyz=j?0azCU)sz{-wD`~RmyrCI z{FS-?Eg-Lex`+L*d<|O?1n9{xsf>Wi#BJr{iJw7MNLjQXen|xxge+PR*DKqxY%Wlf zPZj2 zRS|<(3}!P;ae$V@FR3|9J2yZh;+JSd{1S|a5nSkh#rX@U1*m+rkU=SfG6v-gDu4#B z76sH|=6X>;EeWZm>f(@ErY;GoO0^u5pjyG;Qf67j0P>&*)hZrABJ`44!?#}+P?rbP z+JIUYQ0oJ#I-np6dPvm-)JERk6i|=@J;ay)LTzSng{A5&g`L5~+bP>If>o2Kl>2A_ zP|OlHjfHPEHwuOd2UVj5M}A(?C!mI>B~n}tIhC7u)uo~gnQI6)V+cIeI3v>}VT~qp zX*@v$%G#bS+5(ei+mrU~g+!*6G9`_+Xtmv_eZ+WnN3S;T+>w&G`!FLq8>8hbfY{Bq zB^iJ^dZ=V-Cy25LrCHPAR!?l7me&*Q>>cQWoqLS||E!M=?CAy3oy4pTlP2w052N_4 zz17j(ZG+vAmC-^ao@Y`)%&WAP;!Nxq&5k8efmmw;Cm5u{UJt&a&($#UkbKmpqfW=x z@?A8ze3Zds3?66jLHQ7k7eNjGANhc#0P_7g+TcN*2F@Sjd~TS^H|{n)PosLfyD8KC z3<1wFUunbM4nWl(!JE}q1rY0Z3rwV*l8@UEjDP&hDAj7a+F_}yY}LZlXJKBau9jh2 zz75B^DL16B`@?6$?(aI>*WZ^22#zhO-tboyJELxOaS|87RK0fJ$}?8nfRHs&kftWcw}E+~JVWzBWSGe|8NCU&)f-tUcc?pUb(d}Yd+)L3h`QfaQ&n3!j)ScpU}4j>?v-Rk zf$?OkxAKh(8hU#w%uW>YvSPCEiVdi#uKj)&opzC}rt`DXZ>DLph{k=8!9y%TdLi$E zG!^Nvz{-pFX->=PVq3jkJa**h9Wq=Fp3R3L>Kn`>3T`4<_}s5 zz3XxHK}&teRv%U{T|H#0C)5sG9cI_~2!oHRkJ;+uC_i5OtgSx5FZnwLPx5opjYfxA zh`mj)y!a+sc&skQf>2((M;mqUWJ-B4_%SZ`hF6xxh3)No+Il*p+S8}=Ila5}nYTy4 zdx0%~FCT?rW11G^P$)0%B3q8F_Y{jx%R?)nMp@f%#b1Iek3~_ zn#^lrK6V*SEm|FP`5u*a_0v zb{{r+6KFTh6rbi^HhDTUZma<2-L0A_NG|baGV?*mpV4F}3-#GVd(<=A3;nm6%Z`>) zc+F$a+T6>*a`~TZ^_3`WN^g|q4lGATl};AmNJU0*-`Nl13&+H%L#0)lGvgMEl}9My z$Q4c}uW;>GPiwsB%BkG>$fbwIBBD7HzyA#4f>DybvsQ2_#7sX*BD8L>s~eLH^o~6G zPl;A`U}b^ILyD9oMLWAYaV^-0FBQ(Tnowt0>66wJJby;Xn^$(o_BUE==w8}N&&WS2 zyb584`|kiQ8E*jQE8?H~zt-Q;-hI)IuC~R7a$jsJ6&kL)yE+HqszQ71JCpVIxMXUh z<_IiU33J4#AxzGJk?x&YH0aJ(4pEyz;yuY-^Bn&p;O(?hnk`Vt0K?Rn0)iocBV!N8 z7;FK3j-9%Wv7OQ}je2+=90MJLX`o}8+VDE~2Ra4|LC4@C=opLy!~~!<)&Pfb)&-V2 zwHdC{rhp16{uwZXptI6a1b(W9W%0;j5MU5w5GoBm1MM*ccBv1H@n>W*(f21mteq1~ zX$j}h-2t!QZrEtk&?w-ecsXBt0bWZbwV6N)z6PZ# zAndA-Q2(jE{CR;}1^Vqa21kWd^a_+AuOhrGbWrN_N8?*&tqYdKK61A6kyJ1$8J3ca z_tS)IPD^<1F_|}_wY#QO`KjIIAF0Yhirm9ABtmi;vEftWPh7w!hULO_FikS|7F06r z!bsNQ<(9cpTB&_I9FeleWD+hxjjH_p@xwjPpY9 z67XIYZb?gc=`p!@1c{ch@o*DAJI{*1X6KTO$7B~Oq>{b@o|ok?w8{^i)Uf|dgeD4? z9hc=TJb}U2kW|4&1t-1;4Dwb|i|-U1uKS;sRVKgHS3!}Fwt8jd`TQyr=Q3R@WmPt7 z#U82Rcc4BlN0d+>Ygr$MCzXX^&bPj-1c3e2<%8}&g<1F+MYp$s8FC|9@kU@LA;uqd z#n`pxpq;_oa=Ok3VN+$}&ONFwgD-qcUWc-5SX<0`L#?30*2LR#BkaFQP!-jPH!b(& zA!%)8Rs^PIn=7r1i1nD1^4b-Z0Y-JS$SZ)NV||M;ziS9L(mn4nX{vL&Kukjs8Rj0& zhH+yCe4_V3&0FxhMaLYt*uy&oz6l>eGcekoEj%SvP{HF7bnw`o3kw#r=m({cmaJD6 zEE<+AJM{HnlfIDIc&DN>UHyI-(z3FBBj{PMp;^e_%ENw|%m`|<8eug=Y>Zh5Fbxo5 zjATrK@GXqmePLLdFAvU+Rn^vbRc(XCRlE~#XQP$k(hf`=Pl$a;rZzkw{)&+*A1>w| zrunTueAVm1SD^#zfr7ba-Uur3YVWYRM(6Ltd_zl0bn0tMpj3Jtj?q(I;|#PCK7U+V zk;Be#8?4Wm6n0}UJJY2=vM8plw1d#{J?@lYw^N2m%l*MTf9xyu43_6d;lebAvz~(` z^g?qKLIwI97stHyxa`aGM^MmCQ^q}cC~v%4y7&TK+FOYi49oS)L%~Qei?xx(k=ec6 z&P5Kkc{QewUi}3e{DC}Mwc`g?P$ za(F9eq-rYPmwR~XQ)tRuSpnq>!S6C156B659_P=)nIU>lYt}>KanN34KOmYW?f4tQN!NfD)!GJSMk0-8?p{B7N>*_zcN_Lc>oX3x(A! zkdPUBTamT(tka6`gR!55yAPJ&!{1PnIjk2J47fX-A->H!;O<0S(SkM*zUz=&=nliX z^;LWi#$os#=j63!P~t57CIk_fCc1-^UlqY*JlmV~y-A6ZyPhIP&nfgfoN4j^y33nU z?n&NhN)O=KxEjt}!(|-9bj9qV*dV>!`7Wrb$NRv2czIF0fOlqM7Cq%uZfq9SbD6&s z6BM+x>3n=A)HwvdJv#Q*up&#=DJ*fOE#AD)J0#gOMzGz>PVdF2KnDGxYFpcoXrD%M4xqQ$qPUeZ) z4>Fek>9d3I}6swdOKe3MPr2W&KKu^9KS z?EoY(w%!T3xOKOZPAVqb@K7oqkMN-^D)0ub!j@IO%T3aK|m zNsvIqMseF<2L!c=InFsWciXB05&p((q@0{%Zy%s2k+<94i9=f57J?hGCkdqgR1il; z7{H@Khdj;T83sckQUf8nQLyAVuRO8tWJi&{=4)OYHTZ)VH4 zsOQun-{BGToKWQN$@eWfOjt-IrxSFUu#lQgC*;Qre!|nAGJx}hh4S;Pk>8n?;n^=3 z{E}Hg@2Nw6Wy!BuaHIG10{uGw9!?ZO(5iik!M_Hm^R!z2$P)Z}K>ozX|D1I>TNr=5 z3jL=O@}GWlK{9y;MX1U0Ujg|mPyWV4ul!&3z68Fi>e_qneQt72ZVnJK!36?g#t;ag zf|!eF#DhU5Z~ki-n4wzjs`&a<7c)~U4=Yg}>7azRvUOWaszV z*Vga<-}{_<&$;&|Br3k|ec$6p&N=s-Jr8TIz1DxPg()wkEndUB;spUaWyB#2sz7EV z4818hgh4$*R|>iCqJXCfQ8|&wr$;pMi9z#iAfIF*Jtq{(Vt$!o6Y=zfjM;Kp_WG0S zbxE?YKKB_44gWGUNd;-Ts>548guh6ZrrpeUhi4lG(oA$NCsSC6*{K{p@De{=HF zh)XFA&qDL(eKw^;e(Y*rcsa1Kc_V(^Fog!DQ4uDK?z^+8jBRW zjnX5o3ALm*PS@$=yz?y~s1=}DjoLT0jnlv#@YRj+8P3TJpYyfeO`Fuya4j$}p1WGi zop6NE=+S-Tc^2}__$ST?NU<|8A8FF9qQ@5pXI^1adAo3BcWK>igzh=S;*c2W07Ss(m2SS2dbft|4L#=rm(yo@NOUeZ8#0TBmKzXNHvp z`pT8nvWCX!k>h6H9KF0q*157?+~xvmhp&yiGy%ef9GhL)BDWG02ixHWC+54x>fPTC z^Or7A85aP=k!)0r$V${aQE>p;%0M)dP&#AMu{z#PBeRS6-X9Fj@d0gids`1)c6BqG zWGBiU@)B@t9#u6cq_}RKR$95g48`n9ZY&btfpn{(s{(+kUW$r~e`-Vb;x;TDP3>)* zo=_VB$4$7}c`l6lz1AjtY$uK5cd$V^8ULU-1Uj0mt2duZ&HP3G$2kRV6gWV=3kLH& zYx%a^3tRaTX?MvU+W^wGy7DRxuE1#2GdO)T0*l7R*Ovbcsnw=V`-iZl=uEVWEeBjV zD2H4KW`Ty<&$P#8m*RAcpthTzk&$=BtHi6ZD%I6C)Kp=lTnDl6^WU%h4^Y<`he_Le zyJ2iUvAmYUpm36xAAm91u8w$;*oH!5j-UTLNE#Rq4BCyPUS`yq6OaV)BufzBy|9GG z`}^sU-dh?&OSV}R!_!)?WmB5kP4Y>uL~GHIOfsABlHzF?HOcW&ITNwShhBKgY>0&m zw%zHHMC;K$M^ktEwL9B8_8N62rc#Q(cbuQ3;J|#Y?b+3fcqKtPlNLaVaaycTtN;~B zU>7hH`vHL^ycPdoL#-_PYu?Z-PG=DISjV@BUbAo6qm$WaQx)88M*}ED$)%u7R3;eKaNy?K*f&d$3opIiSgl3_l(k zES`Cj&^yB+^3Y}&PT=Y0L6K2#<5!oa#cO*ubPb~1Mw_pDvfX?&3^yRwd(^6q!0)JvxK;bYH*6Rwbg<7WI~fav)Vh6atM3pLl@BKFh5)! z2a2nvhl?EoW_9u>iUnJ~I0%eW&agIOSU^(_te$284nZH1Z&UK}O30FoN$#du{lo~< z{WpZ|-2j#x`oQbyzot zYcN50ftb5&gSIEVWTb}hIqJ|7fWB?->+8OjoGlZT1_WF?a+x56@GB zWGuKBz*zSUWV56#+&!8`2L;&Q-i7^apfwB&hWR!&+uK2#+T@yA27CMb#C6+y5`a*H zdQ%`UN&*WLCerAR10db$gv^PSnx~O{$I~>jz50GV3~@E$dvGPVEAnCb zjxCA4gQ?SZaDn;`E?(cUThVuHSo9rx7JbLIMc=`)0;778L{@+5=Ap?E!5WG$l@b83c*6j2i_MBIi*7 z#b+)-70@8(nxtVbB$4$skcCE&^j63#p^1X}w+nmA%o1;`f5HvO~Wj+VQ;tL zu$Yve2fMDcT8R+1h^csp_+Sv~ZglAm!IBRPZ9~$^Q?V2EopzAU!ZWmgo{eHQz*Llh z4d6x|76q*q(#vh3?vSCd3-X$w0(X{mF1{BMMKV3V=$I%b?qf3QIz?NYMZu=};1LPX z&23)fNw_l$D?jF^d^=9&m=1UnvSAk=hmrEMC&g`OjOnzxGhy*DF{5=YF(PF!So09g z?z{@xyqTVoG4ZlHvN8*rv02dEmafbm7PDIs{E?$#P9<#Gl)&_}^T^5^Yh|=3T9k8_ zD2X{m(G``sWwG2DGy)v6kBYev)*XEI$7M15I8V959xD(h2La7M0`rfH1xh?B7NP(w z;Ul+rUx~z+c0??~CsQfKy&Xmq8}$&Hc{1*Afu8d$YA%n6vXyobRGW)eIs8?=I$E;Q zErKcK4~i>i6uHF?G@VOUO(>qg&TP&po-h@f?xhFBvRKxzIIER$DyBvOlyLdDjF;uA zP^{p?IY-60$Hht|c6jP+sI{|WlTKFV6;HsBIFyI84+o!pHCJG?=^5rcl!LD-JQxH}?N9}qD5Gbz6kvh(wyB3^RcOEsz>#&%^-M^h=aAQ`Rk90 zs*@ZJYY|`rT9meH&8Ln0gmG8BGEx-5SjmpSWGxz-4V{ID^3`_PRJ%~r>@A8+wtl(i zb-izWNNg^fQ52!3|3b7mCo^$Ek*S0YZN8~c)JiC#G2uQUN)C!Om4K_PZH)nzQ^&lL z=Cl05jxYs@6VjD21+8b~GG^KU!_>@a&qJb-({vB0)VnZV_CU1oLA1}iV0xDKU~Bmh zG>)yO(VDaieSMiR3Jsg)#3kvxY^(fW z=gdKY=D_d*?+ekr8&RQ!V!b}6y%9D6cwW0jT%zwgVY&D!{Ju(Dt?wLv*qD1`@B0`k z+4%Yu)M>{l4H2}JZhiB)*c1^MA^@eEM)OYxMgbJ=`T z5lHN1MMR=B?pc|Y%&X)!F%K_yU|16J(s%+M0d|;@SxDlNGSDy2*|t9gsPQrYKXz&b zYOiqD^c6S(P}n@0_%1|uz2pGA+!LTz$c1E@zmVLUSV-2PD;SwsXTjV!ZWs-KJMn=? zAPk5sEFYZ4`IjR_;9I~)h#BZOE(fzItnV zp#NhfUREGFfkk>iOtKypyB-kp^XwCLt5qm=H@8L#MOSlcR-xG2+?ovxP;)D$c5id5 zQz))#hT*b8G0^;g7&eT)^YWAxA^AKk_Jeq~ zX!zH+P0LCELOCQq5mwS&^Y@Poehe+czXk*tiCN4nl=WnqL)`;$y_NRGYV($d^>ku> z4uB<-sd~?kqP1}Ly-*a{qS&VHeLC2~!986A^OnIdM}Q*>Z@9--03*Br1@2`H`#TAHI0!$m=Q5|0ZBgQ4Fyzo}bc}3-Pqgs`uR3J_McoikH1`oi^f->Wph)7*5Q2o+EWiOwD5Y@-5zIY?G8+V6=L__Un30_mCJc`qU-X_j5C#6dfP`U1 z3SpQ_!T_3(O_~6hUld3rP=zT5k@G*1Fj#Po?T_emiZFwS8o+8ivVfd zuJiUNdxH-CQE76+p!(?|H@ zP?TJtE$(%QcgYbSf@1}~|9BK!06l~jxqp%I-TM;pFYVXhNI#H zp*knTBfOmCyGMC>%odN^;t4FQv{ck7KFyb>qT)$nb~+Qlolj_6MGOGA&X>efw&>+& zSSsoiPuoQ9loPpAPUKFx_<9a31AQ}qxA_)L6#>7)#J|fpv{Pi$PSJVdZeD)q&`9ff zY=#r!M~?WhO(4$&;v@VGG*2hdJST|eIYBhfJ>r)RAv`B&y6A-XbuPBkFkRFse#^vv z7ZuOYXwfq?TGUAt&k33>x`z;+XT)D@8ZCN;5FTx`=md=xJwvR{GvXhFD4|(T5VCVZ z{ELyE#S`WlF0fs60-zmWV=P-kc5>h`AsZEzHjEe9GA9$Ucn;{62`!DAw(fu}*tX48 zwGG6EVC^7#GBWICBy5e-k&yCgw+$UQRZIc2-Ep;6Zy6ZM*nuQ@yOX$*y7<*`nDT(S zS&R_{lcUe6HTQN?7OdCpkm6|hb6_wMn3)OtDYo@x&$f(?#B7c1pE1NqWa8g~%rKM| zV6{AxJ|V$BWTsRX@UsuCiLl)htju_#ylS)l_E%ph%^6Qm{+tYw5n zXDlF>DW2jy!;&=~(90wQMh&61H==dDL)fI-H4KL-9Dt}gLuTzAgyYOxwhSAh|6V>g z0N4p4l3o<>4tydKv;f==B<6IIfl2#N(sNu7Ma5te zvNErre~%CFX#h_$ zCf)$>qbsM&8LljmGhO)U!&4~&$k`HnVP;!MOOplekMHV+W0;CLa)Opt$TC}=?b5KE9e@@=Oo*I;FVYTCPGezd9C(~H9vlfgZeM%Cax*+F zw`t|<3pJ1cnF7+ug=z-1*g#lLHG8gxtBVJRT#89Q2t-mC*+gB1cI^Tqctkig65Leg zLe37H%*7l6&1~fsS+233G}ndp+vd^&mkX?sffdnI)@8&FUGB;@d4&rDOIrvJLi7%U z^}&YY_2LaF3QJ$3oxsTKkzE`eSH6JE|MNZ}@OlF*tKZ8onA-ux+r50HdP% zs!Q6cw!y7ITL3H%#=bfYC0A1~T#DbfvjFG`plHlwG^eMG z2*rCt{K)e_$V}R)t-ZIkCl)IQ8RH+*jd^1dEM}WtSK5+t=&6f5^OYJO;>&XkX3mS| zjpMdHZ>(Xx4Mp;5u%*@*Y4Xk&n4%cJ3;Bd=VEsTyFu0mQ(j#1>xq_wB`j zb?fPOFr1IM{w&oiIL0a3gT3l)=~Hf&tnT1m%DYXIGQD9Az#3eJh=M1B3d^)2W6YQ1-+XM$;qL+<%te_1k4_e1pJ`|~FV1Jw0K!eit z?rWn@gLdFA>3|(zyhH;d3KkitHT0O{zK?iPZI3q3Yb?BL(-!l9BgClUM{WNL>W{tn zfHRa{PJkI>`V8$1K*JGMOfjy(eI`LGaiwf+rtvv?x?G2# zlc8j60=lLI_dIWJjQboZ$6It!_tk9T*5BQi<^WsE$~0S4M%0n=qbjX0&2L- zTBuP%XZc~?feuu9gsnpeleyP{M@5rkyFZ(WP)(sj60!0kIAGx>+bvO=-^y%+#^ zdh6N}yvvHL({LI)FK=ZeXBGTE6C5LFl%SdDF&aNGYR|=h0;l^(3cSy@L! z4Xr<9X$vaI6n1OYpcJS8z*w7c%RdEcMSucfVnkMQI_4h-0!W-U0brde6OM{4Wm90T z=^|?-AbOY%r2#V{uCc)cUj|e4#5yzyaWJ=Zz?n&-B1jY+0pJ)XSZv231Gbr7na_!p zf3mW`6djdD(GL~q=p~g%COcMmva-mJuIJ~pLq+$agBw7|x-t8C9}=q|D`=71(dpZ9 zfChK*jC{F#C4RqBzJ_=4MVP+51HbQpSz6r1-Evqyg5QtGCwRv{TGcXx$%jYYgg2cS zRGhaLV!YHH5CHz*p&m2Bx);ULR0l2*8`kP!TNs?bBovVuk=w;Y#<)$`GqP@2JL6uY z7t=@~0kqIr+EoiF1vc{-$jtF+)Qa$?Pn&APiDarz-aO*+sM%(Lo z4)u$s*zblpr?M$F`ko+{!YKd>ZsCKDBXeN!V;doTw+bhMLQJvNEiTF~vO9s6S`1*J zeZ>*6qvT#x1g#7-DIM0cdP(nsAX6YWKG3HWMZUxb`oPgU|0xfq$#^wT{Mxv$oC#K^g!Z@$g!?7@0G;+rS7in0`sF4`Vmkc=t{weN9XOju_oO#W z3o)_E2p1w0cOj7 zs5Z2DEy|zlMP|EPsY?!edyaf5jhiKT(RsgMWMR^$gT<9t`S-r$<=hFZM@) zUt697b^D4ay~^_GTt2O|#VTsRS33gEVa^w8_;M{T>!=7{&r4MfT(fQDrJ9!-UN$iZ ze8bG-hnf5^Q(S0^T5@??_~Rlz)iHWK8G}atY+|H~ZP9ECSY4lB1SRp#+I{+%&P*em z;RxyCn+kI-$NP@imXnwQ*pVg!Ck8zyB=pXm)brBJLAEhNj~`&2tp43QDT>EqmNr$7 z?`wDtY8?)~1SV24H7!K+W}giqVjm7hn&CuE5){(V0WB64G^;b$7Ta9`H)1Yal+AbP zNNgOZkFiN{;g$%gsh;b=I)QvmVqd`dqA`SJ|T9g%>tdoXRim zYNd$3D1#b;*0ctIpyxE`NhzAfdMb9Ts{yDoyCh+8p@Pkq966M1mEdSz1AN}>y0)%s z_nyK1+9N_D2qb~N;4U0h54tl$2t&B7SV)% zL@s7s(nm?42`L2JKvVUQCKvlMVW!axRVqA7bjL|Fx(2p)4Rk>+sOK)`WiqWqIFJY& zsD%p_QR-m`GIg3>R3WpZV9lJKquW}2bZ%k?M395=&He3td%8MM9@wr*QYioRifR<7 zI6!Rt4|=7ZoS2CIYmg{Z5$@zM$h8dlGG<2-mV`qbl@AC-tUB3P z@n8fDPm@Woa95;N`VIo2@5U3o!gheaX#;C9SY`;^@T(r{Cb`Mg;KL;`tcn{D?27@d zC)b}m@5R@!k(zZ-Osd2#z|MDK5ga@tx<5zr;#__uDTtT!a*uE35doddOg=D~V`iUa z9<`-n4-YFrh`i`>5ms>|DY;E%bjf`*oVdGn<~{+|VHcy66M31$K#L!Q8OaC5Wc*FS z9}YR?^A@=ihb!vzwOmd#M?fnOO2$ z;H>*1E5gHgLVWb1@2&58&mWIZz;=#*v}$`MXnF=teq(#j)$Idm{Cs5&aMRPH;IC#x zAz7mtI{%L9A4(~GLK>A^J#%C7Gk?+i!#g{b0onQi$QBg%r$NG=sgoVg?S_9 zPnN~!Li*3h9%7Wd1G|ff9sbUtsqScwtA@V?^ty@Wed6dYDd0eSJm);dv^5>Ms6LCVjbdoVD5YTjGD@}79(a#P zS-g{LSQ2W!oKU*gzS#34)4Iwz<1{12zicC$lVi^t(z<2eq zB7|YA8IWySbQ%!3Mdag#Gm1PNE6b0GY+o!HOT@a^i&djzF&sFX@(&xRKc1Z(CZ!^i z5_txulmoSmemp`41W^;uJ9V$1GNb?@4_68hsM@1+Vlq}}iWcxMygoO5=c(bgA|d!U zfUhrV7pDjm0Fz%WuHvOX2bTdp4MyP{e#jPA^E}XgzP`p5*Yfs`QYAX|CP%!M_t!DR>-q5wQ7YG>)Rpn_R$kr~g?{TD z4DwDs-5kYX<##jOd!iI^^XCCxZpo$TfLxjY;N^CBsm}qcdsh^f5AxfG5&`b!yASh% zGZB?M4zQYMA}Yl_ynK|2-^&7jj6Xkai%;0%zHzY`7>ju@=G4{Ry&YB=;VNZYZM6|v zgl$gxO@{CZ(MHj}URZ8vfw8yqsW=I+1I8- zS#w56Oxphb{B`7!`T&XT0jMD)_VE@ve4k>zZv>D*vna{6Z%&d3r7S~!m>>(bZBg9| zEh^AkJ5P#~laLAci=;!)0g8++(I%C+J*B9LmW=D!&E8@;Gq7ni^+Fx1adAgBRRCRZ!4MTL0 z82SShpgZcru4raaAk%imrQ$MMJmAvThzkoG zFzY$yV*sNbCt#LGAifR?%I8ulyC^{i&tjOPE}V%RcVWZ4&K94fd)*VZc-VzVh=y5e)<^KjWMzG#atx#B7DWfwqzuegw+eAO0T zbA>S$?uu{m<+sI4ZSkEKOB4<#+#C{(;=8W+9t-w;Huw*CX*U;W1GbADR0(uaAArjb z#R*sZNc`A^nz-e~-xj{$+kQ8$Pdsbl4f^cCzW+Of{k{SzgSpGl#>T_vaudlV78Woy zR}&ImCl~9Ws5;wuN6nh&M!<)p{R18pwU!lbwgn)MqcG1{{+tJ%|b-dqCU`wDDiFusHwj@{h zWSGFd*w1*fmv*ppWf~s0IMiLBG}gLryDED>P8T z3q}g>lo2I=+WmC8I;0@bARbdlelobi41k|>aLg4jU7CAM3|GAX)q3y2M;pyb=q*$g zd)fyYH1;^sqi<(MyA@Op`_nPZ)@s$7v6z`{SUD6fq1T;aUZu?$aG{Kl%rzm$;D3q>f5lG7Q3Lfpb0$su$#8{ zZYnrD>vMRK3zY>ySB2VqQz5LLtV8XMXFA@g@YyQ1c_pKjDT-i}b+7)WxKerF-i0zl z{~%ruL5ud_cmp0v*2&7qWcinpJ5XNUuY7R~daKz0=SJ>L zln{J@SHgOfkSeSyBsdoyT_W20*ZakaB}I`HaL-5oVe@W*O+Vb{9}q>cEP75vzDLA@ z13*t^-S?Wvvj?Aj%0qrd$RT-2Peyl3Bux!g!N+vlM94*XpV@BwtjY{%Opzt@zI_~J zB0{krRn9Xu*qqje$B~e8Tr9+X5LG=c7SWL4Ts}eb|EMTq+W>}(n#=>zcF7avPuzd- zSz>gZVNuq)m;>UdC_gTiz>MD#425WA_L3)J*(YhpEm{eCZh&ClkDMpMy4vN)eSHFN zy;J|TG5QIZUk{dp_bUOC=bf_yjICGpz4*lzr7bnbEBkSQ^QjF>ydp2ggI8kIBT?eX zcwGU(3-pW24#F7avtKa<%R<4jP%z??t1;mO{w~sY4n!a&yo|3$2sYZqp^VX5iHwUw z8NO1z6FCA_jAmwj*x#FE!?>#oZ^nb3wJ3}qx6V+Mu#(B4+OMnJ-Sm5 zgK2m$ZQ6h*G$Sk%E<5<_PdMeHz^pz2ZD?#IUXA^>f^zwO=H(%TIyhJY3 z0J7!{f4T5Ns@27qveWdqG!)4Ay_{7F8nnu5K%nkD@0K_RP;e;A6e1gi$UccA&SQhF zKmpbw`?bIy@xCx&!fywPgMR>7nll0Fp^dKVZUj4N{zjlvj&80JfrN)ch;M@7h#- z?Bknm{^L?ehxylvaA!c?n%WXAVaz?X1N4a~Gd> zGw7Zu+T==J_VQgfpY{>%g?GhbF9Y}RLoc8DqBtDWZ&P4gOo8!LVu;}(GG0oM+BK9H zUngG1CrF6P#q~Kj4)aQ0Zr}wH;#Y`QGscaK`x-vo#JG?XFQuHgT)aMt^Bs6vD&EM; zn{4ssD7}W*;%(y)(c0qenbAh*-Em89Pw&JiyF)9%v2i~mQq>H)Mo(fh4%w>5$|iRl z8Dy&|VZakQ*y3ncfl@TT@WNGy;r6%p3=T9Aj)%n&oNGd#{-O(Wz4NA~Wdm$-m<>gd zcj4rnAL^a}D}i>ttApBX?0ya&2C1@W-A zP4(pwTbkP8@Z!Z1+evW-PYTRUG6;GPZUinKSjN+gLElncv#DxZ-PX1ZRU0qb+}yaW zp}K8jV_jo&LMv$KRd;VcNW}zBLYPV2-A|w;&)x^+Aq+ESVb&QC%#Beim9EZuKIq&e zel#I0@P%?I%U@=pTuPvE3VmXlI%a~W0dED5%y6Ek|T?fBO2f4X>0ff$EnyT z{1)IaEcTr6sqRaXur7HiJcXSkJ>z~5d$=giBjfNcj*aX1*yh0sy=!*uc$z>@2nWP= z1ei$a!jr^O5Pb8wI4oGi{}d^*6+ zk7eC0AeF)C)qEsZVD{Zn?Cql`@ww0!LJ{@KKO~A{s1Yovtq__B{I%%f!*e4T8eEm??f75-S)DlWRhdzTyBo1(HQ@9h}#Z` zg?K9Ys17blabuWH{P9eEoOkwvFKhr`;w5)E3d`bdKR2N~5B^&YwpS1fO-zTI9h2X`~J3 z;ysSrp2eFUg^|Z8f0!SO=)sqTJ48lIfyNE=r;rSSa|M-OzyVf;ic@M^hZg01Hg?9l zaNh;-0`Dv^I2*5VX5!9v^2FKvaE>j`wZ+QuZ{+_!+RLW1 zOk?D=PP?B>+3#f!^>xy|9!4CD>`$dbfmJRKB)XXUuqs$Arg&cLu@iy~er;*n#Q~PJ zE>5o?$^tQuKj)nRT)8nRrI&qAJoDejVxIx-c|7bQXxt>s9|CTt0ijC&_JrRmXnYFU zNBSAPhdXTGBg}MMxoQw@OX|m!Ly}`qhXwRDOy8Ig(?!tvKxj216Mowv@?0*pEULW+Y*WM#nT zykrCU5O0OeMF~=usfieWi*yak^_^57BhpJbSp$|H)o}eW zcPi;}xj0XNN`^Tn-R3~mXQ7d2A{l|^n62;gAPwhl{7cg3dvK^{?&8b3`_KXWBViwj zK5Nr#EyllSEeyJ)oyUP!c3_ohB78E5Xg*HZYY!kWnVN9_Q5N8B!{k3Td2sp(K^?pv zjdFrCE=IWzIeT15pdex7k70r$?Q)&Em!YqrRtI)QA*x@|R0V4oYV|W@FY;R!t3{!+SIu_=a1gGk`8&cS!kRhF}oCx?A9=-P9 z&6C~-zJq_`8ojBGD!?>kiz&QJc&cl zixOf`jNn{`hvi5EiQc4yq%k&ydxJca1abfx_Sotd%L^i z{oC}yEK|KmvS~~Jf2^dR`tlv+a3H`(2F8qwA>;Be7#8dKV!?Q(7|yd`#GU?>xAtZ2 zd;3n7@;S{fnlsm&C}8$icg6Q7dL0|fVRtbU151A98Cm--3QWQ>U;- z5jPtGmR<+b(jyJT(K;6Mm?nClhY=QRUvTyc+|e2OPTwq@GOsf z{runDh(!1|u33I|%Kl*9SY~-4XKkO~uSvP+NX_fbb1z2983a$z1Y!`?$-*!vkKCDa z3Vuh@G;EyG)Wnjv(eG&^qur7iUje9F%Da@r0&{kBmo>9#pdv3g3H6-R$1>-Nyz$J$ zv&T3Sjf6C0#uTXEv9E5q1ABV+dowQyw8wEfjE*xqnrC1%qmm+z>(w|0v=biC|G4a) zBbzap`A6u-SgStooXl)jKH07Uu33e!+5@&L!E?daQl?HRA2UZa@0{SctOydf(K$Fo z42;1E0C#rw?%!w}sKFS2Ku-|YwuyG=03)v%dh_R^fAv~14QIc_G`Oc8PtygBnFKRU zSQr{RUw00q1ADrFcFZ9DCD+W+3G?G5D5ag7M6qYcMT~rQF7!;ZS zL%V{fk=dw;ST0SNLfje4Gj^HaqVn*L(y+-O>;~~d$rxQ2X5^-}ee&}k`Z*{t|HegU z&q<-P9XTNCOL?i_1>%-sS{Eu3D|msB1@h}C#Mdw_R4&fr={aLui0#0CiXUNRs7S2K zr3^btb*L>iMzOK1X6zbUY_i2>TU?lFbZ48vhULmEtlXiS;f1k0(R@rU`?HdPf`h^j zfGC=edm-ri_?MQ{6(I%W8(P}EWn`pvDli-U!RK=s&vhuL@0Fmgh3H(nJ@d>0!I%iG z9xZaQ-7nGmCtK9%qae0ubOF)2Sf2*5#a60&x7$3EpbuF zkv4(T3;BlFz@U1fcv39PTPy2Q#rM+fz@o)PZUjVP=niWA4_ z@z24t{ugHDiaIw(_n}z)8`qk7ZpxZDkNStnIasapbMORi4i-wm&GColG7|%WxGkRj zZSR{0&S&10U4sK%^SoW=yqo=u92IGs?m%;7 zV;45Wb46z@I_t6k6FhPpOv5bgh5~b8tP$+q{?0DAi`C5yTte3N+UlCdyi#;7P!>*cIOO1wMi^heNdL^n&n*3udfXgrqB*mtq7N2m zMlvWo^L_RU2(EH`R&`{$omN3PTE#C;HPrlifFv*Z3-^w3vv*p`i#KL@ehb>{4VUqcAGe5tJ7no?smhZ9U zd-(%a8j2*WG!)5OczJ&g9D2c2!&3QysJu9E9FCTziO8FoIJjBZp z=5&-nkL4h{rb=hrx^Z8 zTYe@gYD~>P%TT(hKF6S+x8)b2;vzQU7o(!yeEE_spK|1vqd4RHG!yuWBflCI-;`gA z%CF0BMCCW-w^-h9+wwcPz{&kvj<{LEvE|M3d$#<36c!|Zz*s-D<&UD`3i(Dy{y2O6 z$@QA5MdeTAPowf@^5?no7xI^m{P*njfBBpD=~wdCj{Hro{H^?*EuV>s9{GD-{=o2m zwB?^{`DZ5l7hA%Ij}nU znio~`)dE{BKs0vYpa#ET9qq~sq><0wW_q$`B5>f*6_z#7ImGiE{KYgYJF5ysSSLyk(X*-Y8Y=5 zFPnL}&{4Iv+5(55sHG@U7one3U5=_(4UwuFAVX7)s>xOt+p0NolE1~%s>N1YbHta` zwy5};+HR{I7&7XT9M!5W<>fL*y#yVlUTUk$9o6QjD^NkU?ggry7tHS-)xmr^S@Sr5 z?ux42Y7a)U>f+@}UiL;+x7z2Z9!K>$s*k0+%2xeR@q0aZ)qt%4=>L-%;^k^b?Poh* z6IIu$>!Rvq>gA5QKB``!Ug@YCcz+f1d9|Z%bku8XbyHMI^;$>0&QY)DBM6LC=!`cx z>dkz73loF6mm>8xTfN;@@37T7Gc7XNr^nh)udZ#W+E7>HJ0IHC)YRC#wXLb4s=fxi zpkdSWw!k~Ci#<5R$zTV22Dfu{an#LHBvR3&zpW*hilg3z(=^qsNU?TfTT@kQU1L>s z+t${mnzp9qnoTv$H4PhUT1<}mP3Sz&{Vs+b`KesE>fHmSX0Bxj#sE^EhP`dLeb93 zkXTrwm)z>iHBFI8o#h8Yif;Q*XIHPu4gA4|QQ9wKIRhg7TIff$U7DhJPe(5}f!(3v zOL6Xql}7M*M@3DhXei?Z*!bPoKDep90|#w^bzB)pC#_RWSfgmd1|%5|3DM|J3l3gr zN4KWVU@k{X&9t{k%|r+!qg5e(GOpH;nO|tglFn;;+V^#JG__ybjR8Wg6r$T*ah&^r z8&v3q0u2qe7O6Ic-;6qP(<|vo$n^x>aP44RcSJ$&&>(yk8HcUt3~H#ru#Q&YP*~Pg zdp!!hg@CC)4p(qEzv2%h5V`k&sq=s0q;H@yd^>7w0Cd%<&GX|M>qfo>NFzD)c=yT1 zq^urxAVlzRB}HpcJexKkI`vEnbzu-}nif8gH0poTsA-!Lpk?Vt4;szUTK4&s<6~#C z9HSMxrGK!`8#*D7?rGXB*XyUQYpD2vd4VLGofdPvEt4TU76#}htK+-chq`g2hEa+e zM$I*`JsP#wbf|3u@MS#^AHDt=OI55(#p0yU!j+>OaPm?z)d`*Qa*d`YI^%L7#i~(ScJy_ILnyRlz_m~)v9yt!PKUik3PmhJ zYA~3Uw%#lsJ;@9e4y6@ZbUbQ!X>yK&ypNuKAS?>$CD2kGAMhsmX%h&9MFJe)FND)m zwpJ}2?4>LlS3_Jn2+YvccV61`moQ) ze!K{9k!c+X+>HU|VE!glM#JzlXNqW@nr5m-)IR>TG) zpat;k>Wra;Dbr~V5^n78+TGQIgi~v7T1JYhaTnRp4XRCjQ%METEBKSkXHMadWYm=X z@JVi#nweswyzxIK6DverQr}`_Pn-nPv@KvwXj5pW`X5G}u72{#5^)KgZKzC$zX-FuY##)~2ofz?gO$;9vRZgfbKw#hKbQuw{h3H8ubkP2_)VHaAOA;${ z1`wgi#5GpU*YRm1*!~Z#@JlEoTuHz5a+log%1#+~aflhIXjO zTscS1#hN`*OtYH_0+^ZCD_l8G&WCU!xl&g3_qW3-%fO&37s%;SoIO&Cqwr9!TqMtO zWrdvX%9XgN_p0}eLpSWo*|L-u6mPA(fS2{II-qWG)%(@0w)%jpZd139q6pXfdQ)S) zHKarW)m3+l5=Zk>DRCg58L9SW(o~q7xVZ^X<53zd6fNG_)o!}dFW{Y0tUgVSx}3@R z70Pz$Y2pR~`#Ij_${M-JRUcFza@F1H!>-&cFSOM`SA9fYZL34Bx<_8`s*kFBG4qni zr*Xhu#R56F>SIjv0Ka)JH9ICP5R%iRG;Kug8!J+=R*Kj?%dfBrN^YVzRPBOPj^{6Y$BwSmZn=Em7 zBJI)=p$yU?(=O$5i7S`#QmKwWWj#_d0VbLeA(9#?`bFCQYj1N=DFM zY~XNlt9A|`fsRzBcrDB^FXhx-I?&a(w4-<5zM-BjjkjLvbZ)3KpuKH- zW8Jp;nzp){?KO3*++(ghmpQK)Yf2ldnzn9hu1QJg67{&Po^aKt)TeEA%2iLIJLM%3 zwh976a-=a6T-06l8TDCLeNKJeRbNn_mm;9p3^$3tn3?9QR9|%EG6~mu#!rx5EiY^z zpsE-`w!wIJyl)RYBQDVxCtH2VRZpoe+v;goeMNoMR$p_~*VQ**CG)}+E6=gjH(m8D z^=+V;M{X9DW~r}oUOK9j&sN`Y)xW9lhCnr7s=%JP>U$jO-&a3y)eqH=u+nNuti^Y= zuncnz_Ee3#%(3vAYdYe6w8sqmU@}z0(7v7Ve(*n#a3(^ya16>*y^@#q83ASKAS9HqOX7OWXA56j}=itE~U#=BkhpXzU}`n&oYT0c2`^$0TIG|9zkYpkbp z+WeQ7lE$M|ckPS!&`LeO{KHoNbk)Dqvo4OHO50MdWmyr|%CfR;%XTdXM9s>vqT^Yr zS0G_4*R@=0f@@7AK{V^N9wl4%^!M&JaGj!LcjIlmy|Wr#xAws1chYa3;m}I2?&^&9 zvX_b8cdbe4mr~4O>;#eZ)D#d`VVuVY;~F?*TY0WE*}}-uS^0s%Ekc$(03?J}U=@zC z#u}DEXAVoJEgkJRM*-DC*S_5#ZxG>fLRdxWXWlIK)89y~0F)ld&Iyx(V6qo(>h9{Z ztzy@jVoe2RAy}zxJp)61eZBpI@y@31q20ATiGhTbBH2dZ^-KNIRp`EFnl-z2LAF~u z*o(P<;*@smfl(#bidoapz`Vv?zw0Bo& zpcSXHk2TuPZ-VByRwadcBQcuw$geP)M%S8QmDtuy*P11-AI~5=8-on2s8wpscC9%q zz}R`ob2vcf+SWYRnr|(@Dr_xutwkK^XYo?T%VJ*2nQqM6R+eHRV*1)ZEbO_i#VkwbOaeEAR~=x)?d(#W);CYgTiyys{#SaR)<= z35_~9)YD!=JyhSdn?a+X4(n(28eFT9!`5x@?(W@B(;u27G|B62>tZa`Rwviy(u|+WIa+m#E(bZeAsjC}1yh`gbH1I&Y1N`e! zsN$=;K>jQ|@Y73N>!s|cg{P_4E+hq&VjL;yy7zl(XxF-&L!r&O!i5WY%(KPGk*XIn z1Md!R?X}}cfb>H=ZW^PeM`nxJJdTGh0O&Sm7S-3UYp|IQ7qwqHL5b5VxH%SRHRWM-Pi`bxM+0INg^aVJHRKWRWcC{=Ppv9 zc_FW1X%WFRVpYa!_1x5&qY3mv>O?fyc|loPczO2-YjRWXZT-NQXj$mlr;Vx`ASD(R z4LZrteiGs^Pp;;#1)RsG#ldvnXYHG zFZs)0N_+$_G?X-^We8Y#{Hme$ZipO1Hu(+nt}S8}AYO~lK$(RRq3y1LntgqPfMXb# z=Qwbp0Rok=$4!s5TnkTq(C$y6J8FZd34TBk&N_Xwb3W<8GK<~r>ygs?AE|{xr1vsH zoPYZK!rfex$aXb8~AflfOB6D?tEy~jL? zrc1byC!0IC#nf#T8VF_s=}oxN!NZ*fX%XavP;Ucp*7;}|BN{TheSnQZLvWWFp}XGF z_+u_bf5(ZZ*VB};BB7i(hoDKz<}lSwoRFQ9pG@r1kc@96jYiWFZqQc;do|;D%qZ;B zEixxL?ZYw6oCkM;LedG9{%z(CHsM~|>q>j=TRp0RZUDSRG;s8~uAN&5)5iox z{r#O$I|o^d&rxL7u6G2Xauu0kqVfR&t)KPj;~Ct5zsNU$nHtz|En!(*u%zc7;|cc4 zrK!4PAxTC91^7KOJYFtj+O(-l6`Eczt_M`|dczLxYL2zB(gM2X}=!!T_v2jt~`9 z35c`(!9IqFruk}@pV#1bTQP(X7ef4Z9c5bGRoz{?dss%a6^1WXnL>Pr=fy$Dl7n9} zI}W*&F?>tIBOY3VRq#R1uy}ueywi~9;PJI2b!KYBHYGN~Gg25bP5ivCXcH|8^VdVu z-Wb?g(?v?Ct37u1H2lMw130M1}~SqBBzg ztQZ`HqeV+tw@6)rv;=pQn4sdIW8}M$v#AW|l@YTg+!u}#9|Jd7wnSW1)7kP1%;T;Gf}~OI!qNRg5eM~7g5okdWfWm=`zK@^uyTKGR%#X84}hJ&PRXKRp-QG zfkMJTn1&CxTVi~s1x@MoQ37IoVQ)uxIwWbR(DtqYaQ}g0njz*X@gCJ5^~7fpb_29$ z08G60(rM(-XtS=Kt9$px>mcz*Z~8M|FB{E6J=#&3>3ai@fR9NjJWS2=JoBCL5HFpC zCC^og&X=!I?? zN#bbtd@0donAZOInh!EiW)soavdwUl*|jZg^;H`~>|ebW_h)&=s3VIu(f`;qGkC(P zit{%ad+|9t!7*xf95Q#a^yyC7*xf!bfX-f;F>-BMNF?Vah@w9aE5_JH&d9_GY0XXx4{%D)w<% zH&ewwp9AI+8D;LC^hy$96yOzo>4Qh~bwd*Tmu%LQol|=2d2c-O5F8xH$p~GvHdbTH zPg_hsHMG39oci+R^8=L$gyKkV(u9G70Z4-0?xDfBdGj2NacA7|`MPl0E7!+3#B3aj zbcK`?a7cF=HPSdw8IuLF5bt=ZT*+emo)Y*y72#sZ-*7lIjern@r?E^WOYnPU;QQZ2 zl==pIi%MXIaL*?WO5Xu&(s!Vk67d(}JD^E;uLuy)cVIpA9dHjF9;l^2_$W~YiQlmE zD}mHNxF~TGIy?YQiSMgnc2`PZxNu#AuW!LwdKweB3J2~-^iVep`{1x-`4G$+4~t27 z%zH>o#-sN(KlxaIGyF6bkb6WF7QhKz-Q$NvF)U$59uUQ_);vYKqpM&1M7j1%bqU-( z?M3E$;Z=-xoV*5-YMocKqz5Mnivm;cO9X&}K3(=guk0{;UJjE4v1Ew#UI>~8r6ry9 zhXuW5O_u^zvX_2Tr?ebbnk&F5M9<`c5DSJyN$cYBB}c`~`-a6V^H_SHXa8HuD!IW+ zxdE-l*c*`Y;*^xn&XDrLVKKXP@uOnSQ85=u&*Sran4?any-`+sY5x*w(+<#gnRc?k zBABioZ3shy)C*ygy5S&t1drt~OO59&0GcWzOHPT+XqzLV?6?5di00gni*mYJYwV{~*ETN2Agp^k_O_z^oGqOt7Ch<3{M1-jxpFI*TsB9VWv_2yv=EoU4T z4=eZpXMCsNKreD!oGrz1aSpT2M!{kczpnu8@@gHlsP0>OCDaQO0RvV3038XNck+qD z;#@S!N|1{Zd^lVVmD0OUAwmTrggQ z#OwSJEplsmhMOjI_#`zTE-QaOqbMIYb`qY1T73xnhgm`gSo{q0Pclz=#-d0BW6D+F1u5>C46|v zU7|q0SgU`n)8yybPbNvlOXcNW&a+W^j`^a+kBQj_*gP*KJ)M12T%M$-ZSo3_bUchs zgt2RR;IL?WQoeIoT!BV!e?YY5?<^D@$3&bhkdKdx^Ww+EuH$02C3fWRDHL7!R$p$u zmFFR(_wAV2+py%6yfD8TG&U9iVc2JR)RmRj)#U7#3s_-I8G0&hYo#MGjct0n?2TM; zMD!gKSFLmof&gJcR^}WOIp!gjb4tuPECz?g5DI#A{{AE4ni$-BTysQR8-quL>kdA9 z#}bl_mnqm~<6It&MUmzK@xZWnd21|sR9s(~8_Ugq#S!t!N*50|91*Wt39qoa;*}He z=G8~UjR!=Pd3sIdq}Ze*;-<>HSe{3>7V-%tKO$aRIXN~dHknD~$0o)m$MQ`B9enod zF}G;K>tYj+iPtd!*bqV+#wHaxiH15TW>@B>)&xb>H35%s-NAo-199#{f4)Y%Tf9&7 z>-(KzK>S!5adDf1;o{>0!0>~jgmnHfaVK4kIFE`uPokOf z?_yRTjM?{r=(NDs)+fassAQDrd#~cZ1xJ&McTbl+CO&jPd>nJ{?nlLk>F@L)h8~*Y z6b4BIvw0vE;e!9j%4}<;U1S$!-z6@NWfj>gDme^?#YZr<4pm0;?*V`C(IevC17dRI zVezq6D;90xV4Rwze+`R|Bj6`mTCrN-eawmF92fT~E?=PYm02wIVfur)ZizfD9^h)? zzkZ0XKZueYVTEU-#77T+lIjv4V~LNm#BkQTQAo{5I<`MC&$_XX0 z2@i^Icdjdn@Zme~gFGxQX!XcW40epJ$^SQ8iZD~Z3)(X*zUP0;|Gxh|{|9&~K>+ zXO4)U91u1bw20@)SrTyP#jNyVE=Av7q8A=I$0g+zGw`4ZZ)?L6tVusrc$c;0zJt&H zD8bD4$*a6{=(C!JJzpOv!ISJ5l;J&RWPS$w>x?3B2uKngsPqgX#IB`DNUsp<=)#UJGbGICUA z9g*;w^|u`b(ry6dLz=})yswV_iZ$e)reJxFyg|OoD;Q1Pk?RRLM3%2kEDhW*vvJ|^ z7(~w4m_-6NCJ1Oafba5Hz9vBhlk9eaNILSSM9Yv!@?QaV_Qxd5pACXTd_YtllevC} z<>B)RaQzc$ln>5~PU;Ab820YB>N~v<=znsRdbd0;J11$f@1t;eF=0aInw_W#|0)nJ zsT$4zU4R@32(Vf}t

{!?rD~UPUpri=!C0QysbufPKX%q&+hnQNsI7?K@zOEpRj~ zVdFojQXMr*OzVUJ*z%F3j9TEEET|SOdR9VSFeezW%MWY)F6_b2x5WZ&m=$`H#%)`h zwry>zuG(7F*3!7Gd1H+&&T>VWSnR@t;v}g3TUweow$;IckPC~7OGg3Hrc~ku^_(%{ z@uieZAt=?xnKhh!d{X5Ra0fv_s)vv`EzHb6EvXM_`akrc%DSQ811%B1$oQ zqnLBK+V(VkF_^8su`A7~HnQz$hmKYwORCwqs?w&i(Z&-n^(Df zh3%hXCbQBGf+CnB0&-GNQxQ8_Wep zMNG`((=0xf(%CxR<%n7EPGQqu)bpFKqd0O+8FizYT`|)dssj&!N_2oXw~Lc1ejJhl zgvo@JVqFMf5vDN7V|Y;Nnge;;s+)rGL3E;tb0GsZY!Qm0WKP;Ng`d&dac2~Wj(pA; zB|d=liCU)=@9Z%~3ul&Y?9`Ak&-KUzny7{aR+o#c0#b&;cep zNIrc0OhRjsX{5zE{9{l=f&{w(Se#&L;XyWH-*NO#4W$|ABaVjvdUNC?196gc3~lc_ zE&+!Hha=j}DfUrVnhk}5zbx&r1a3|Z34*^Wn8sJ!Y{5~M;eHCRx3kDz8FB?%tBVaU zNZk#Ebp^O$aAb&<6^xdh8ZECHxsjkUw~zw(x?$Da!cP4%Dhza*5p)#S`gkkG9gUnCNWjDn;8|1}Z{HO})Up=hH2C7}j- z{J$hLh1NcI68ieRzpuOr94P0qveKW6eWix+UC zv&9^Snwx_s*oL1i;9zmK-h5$;1s-o~mf%ws^?AU(c(6Tf82+5GrJ@-NoYgZ&BLKiz z)6vbtD9|g0Y*MDPSY@`^3NCSBJ|Dal9PqlZlMgcm8bvpfJ^2+3b~Z2Phzj`P^ND5#f9%vYRBhZ^ zyS)Zy83UZrX>vrw)KhLwbIr!>jSY3JNVBD;p*rx$FE(}10XsKo8H_xPoaBhYA%;;+ z>W`EN%4>n|1xGnr9Y>1|k{>#idAjoFm11U*4^yzjPaaU)%sX?U;Sv- zz}LUCPYC`kL4+~xD#F(PBY%p@gD?k<%WhuwMCBpXWveUUkxcE)!JBSd?Tf<1dl!H7 z*s3=wa?OuEzPXB*ep?N|--R0FkD;t*y?^|5H81;lxyDx4f?Arm*YVBEczHQ5*YolU z7T}dpbpvdNt5>TV`R+A*cayE)pJ1LT&+GW+^-=W(^~R`rlX{~K1LC4gy@jFQYOA+J z#S)k@$D6k^Anl05!@1gdvUxqVCF}c_Dtin@#ayJ{`OzbCLbJR1o`n{w65EZXie`H>N;z)UqqyFru zzcAKcqp)o9pEmp-h$HH6{P_2%`Y-j5sQRb+7cbA+7Pdwovm`HYGVor@LbF*B$I5c7 zY!uS6qn2akI9AlLa#3;1MYC9NE%0-7mu*eV6?a>cqE?=|pWh}kZhkHeeehBgwTi7N zwl$SMV!TX?TGOp5d_99tGx!dIr92D5raWtwZDDagV$F_PbF8^2zctUc<~tId^GR!g zZ7pQhi%?Gs{stbl;B4Sw3(f`}w&244VQUGjK(MS8{IQI&m-A@_FK3eq2u>Xq^BfF0 z>s%(bGK#@>KYy-bg!3?htkt$v$sgxO#aFF0wgs-_8`c`WS!Y`pIM({8__nnmM}FL@ zimDQ8gKfe0+V{1Mg{b%;@0+6H$JPSI*z8yr+Ey(ew=n06c&W3kdfpq*h*l$?ns~XG zmu6mC7=A0Cw&hye)gjy3!5^16a@et29qUrZx(o%kUcy4WlusKN<8s!cjZg4qP>CK9 zmDUyPpey*)?pQk=tHZH686wX2yBuq`W9@OQt|*4W{dlkLVrp0Nou(8O&Ia!^K1EpFt2kgP@~UVmowNK9P5pUs~&Q!H}UtI z9qTQeBMwPGU`h{bG zN)1@IFv0h;vH#A?+imMs7Wf0q{5IRVJ!;)y-Dz8QMP;M)!CdP@7HCzT^&> zhyLMMsM-<7I?BS3=2*u$W8dyrpJX|Pqt*%QVO&6=(YTK|)=9^D)Uh7RwH~*gaI8=9 z{%OZLnpj|SFNu(*4KIehGTsb z6y5rkV||H8y)^h8+j`cl$|Gs1WfcGCd){l7qF)zsEC%pgEv3|z;&mHR*y#La% z{+;(BDnA9=&tC-u=+}Kpp4BrqmxdDF-8*9KZwr$w937#Zi=&WJ$)(fGkNykP5?2nCd zz;A{1cf2xZms?=YNE_NZJHV5Lx0Bu>XT$C41J7P0@N;uRsf5Ay$JYOhg-Jc8$GjU%& zd%r$*5lkhmf&m$`36E5wNF{ObFz8evTn1Bll)wv%m=h3F3(-7Nslmu;StDjLEFu>T z;IOdQqE-FzjZoCWuoch(fB@S1ObdVIc~6Ob6}q2itOn!eTx4xEy2G0tx;wUGm#clU z&kJ;jd1<=D428Php53|+Ch+i5x1SiY-vWD$`WQmJ{&`U zKpAEYF*H!Snrm?GjnfV#+7ied$8du=pLP%ilhQ?ub`11))bzlX5b_IJ$PIT;Qn1PJ z6&rC$NH|Sww0iD<88gO(Mo?g%)?q;tCuox%ZK$siZe#Q??xaEZcz<)82FXz4>HFHR z!I>g-3{M30<4jf;j*a2yygo5E9k$U%{>n}s#5C&a81SpPdc?VqtY-gUM_)xtN>tRb za32rRn4!hb1GUiq<1E;SNd{&`B0SPbDDN*FwVl!_>F6rKWCsLQ{r}fkviYB&G?D^V z?96d2&ODDIZ5V=$JGkoPku3CgQ?S>p(K=6Rojn?nj}{{sCGemd(@0X-Q|jWfF%9%`geQD-3aK7>qr;xpH;|>k=OR z=@iT7{Q_fQtWh`~=7ox26wOKF1BoKd2nB0F%W*wTeD==+js|a2Bb|8qL zORHZ7l4Dw%#x4Sk8s-SNFwSMeSa@{5s%Sn0_J5`N@=2?*ncm3H>;w{O9u$(k zCrtf(78LAm+B;M?qZ65Vej6lqDnU*(!2|PPErw2_08%Uq^--7<`12tc10^Lf#H++k zBJ4LIoJ89Ci#-;i2RKeB1VTkfZ?ga!1y-$VpkA}%7!}w*DVNN^!+5)AR@>St*1BM8wAEHo z0+gy)TkUH1ec$(e`L_MG<@fo_%)Rg4wK2`b**nxg zq+Q;S9QpaleJA&2eVhyt{sa2SY^@`+!ZAiYlDwryFX6{X?6Fa62HKJ%yjuYmoSHqv zbW4~glFCo-bZf%PN048{W0Z@mv)e`A&ZT~_8NOiQpRQy!mr6Qk{JF?~orea#tXW6R3B{3C| zmao#5UT5Yxgw)a81w?o;U=sj(Q>$kh_XI%a;FKB5_GB&=I;mb|GvgV16`e5hMbn(X z>aYY;wi7d{e{}Ej>L&Y`vmSg?2ufB9SK;9P;@nZS00x#yMBOd&P|ALnz z#~{2h7YSmUJ#`Qc*Rwdc@YFNvS3+juW`m*|pM?dNw{HPl8$46mnAZQzze3-%{T`Dp})PTSw1vow%p|sQv_6GqnOotJ?2NjMrsloViY+=Omn> zqjCbHClHrGv-Jhd17`w`7X$5;(}aDh{It}bQ|yd_EM!>xBv;kbk}d`WI8amxxoL@} z%v`GV2sx$BXxB-4PMI^tQ=e4u*;3||drpNj){7OxCA~Awb1KzGJ!iZFCs03iCVI{! zXR_-|@ti7Ws_RVioD*U-o-^HnfPDzoz?_&)n?OKX`TFiTGZ-Z#^_>kN1-xU=ISC`_ z%w(E0!>FEfvQzEFR$wAR+wF+w)No4vhnJ75Pqn!rEHZ z*&XWX^ekgd&bgk`RoXP8)7Ff1g-va}oRp#h|aGDyBzF|8Pgi2Ls9|i+6%5~Oz z&Iad14@l#D&)Mk2UFQPN+2jDdU*tKji2+qy9D}o#h#M95r)BY2)`I6;;#}%Emtnwx zP+C1_vjeX%<*7adAyWlH9mEKFWK>J)4HfsCcBjL2ws_7~=Ugyg(*~dQg=-ftRv1fo z>X7;2`WNXQ$KSI#+m3uLAkAmFHaT^m)#%7%=8F#FW>jp)_(IJmN7|byV!HyKpc1jao~-_fj2n| zVK6@odTrTQ|DJO*XVx2?H+kx}>UW;=X6G%Qa|@?eHCuKo)(Q1_E*5XaCAJ($I5y9@ z?WpEmc*cdbhdlLr^#{*+n{)dyXA_p7_hN1=?%UbZD86~1t4mt~?C1@;6uU+=+^{b^ z=MLxXp7Rbayz+rL28MiLTyq&EW++$HsWhov~4#^DgJz!w@$%4{aYel!2YYo^x01OwYNSi`Z`G z9?yA?^KLJ8T5ORQI|Bi+SS-(rEsZU7oqK_(!yrXO5ZT&!&U>Bv5J@wNz#6CuBqWHT z`n1L}5I{lImfoHn^=4+*d(QpN1D^9B#wNBRhNXKC;q4*ych7mB^L|XrAUBH!!&$i| zD`c7vEKv_MQ6F3EIS;G9qZlwBwCV5ohHji_>&FVe7Qv#`W)`hMg8L)RqptG-F#L=s zsk$w_9ak{VOJbM0&IfUVj#ct8BB{KpRo8gV4u zBuPN*W7VcWJ+jm zgX=uwInO%J!IH5JgvY*)tEwU~P4D#K=tviF*o$o-eG+m0mST~thiki@fqtDmNqJD# z&vWk0%vr6}NZUGn%yV9FJ`MstdlJU?r66oEpKxAuotHf4lTM50e9HNB7JQ&LU@JR1 z+Bd_3v*&y!R)GySstq{l$BeHC+TV)N=6un_6#Ll15cTpAv83vvoyY-{0vsH6_XF%d ztFx-DqFvlRynl}G6}2FCAcxUvgfgn2UW7NMuf>4%^}{0~GhzIf8Gll3RX=*Js;{%V zO*>P(va@HP&sGJIKF>(89iRqcRTqPzdqjlacYcuB4;X|Vx)wxjlXjqd8~`VluJc3B`4Mw1 zH67Gz<#U+nkNJI+pNK=vuRr0ajL+RGp7T=^BWG85&d(U5luaXC7>OX}{d1O>+}zrZ zjS8CW0~SJlp<8Z3A_2eDmEY0Y#gz-gwRF>pK4$eRelJOVU$;(w{8`l2o(dA3j-!ViRtJkf)&Xv>ww;R7DSjrXsJk= z#E!0Snme3|k+GFA%-U3hqb3cZyfusuHTKnPUx$5m4&m41Q*H8HI@G52LD7+E?&txy zK~T)NaoJ$(lBamVDQDvp3<>jsqxooJ(Pq*}*6c8wlk~X21!m_Q^27|J6e%qOKtgd* z)|_1J17ZwLbfdce#{9F-T(?d$ayo_#=M&Oi27L$qf7+41Z&w?WWk#xA87+t$^zt}6 zjjhKMq}&~@u_uv5U0O2qhV@S6_V-w;@H4ZzW(r$1w{_+z{qb-hc@px!?y<=CZs1Si zm74c~_7`GI%nQ&}^f1WA(H>Gl(>G&qG>nE0bwg^5fwQlO;~am`L#J^;pC(Nm>NF!> zJETE(!ILsLq+oCW{4vf%Z6*Rfp$#GbPC8D!le7z{N>DP9==#jhNc+Abk8<=^aDHpo zKnJ!%z85)q{5iJ+Y+UVPz=q-+3c@TdU7vLi!23Z?+~VW#@Z3SeNSR#Ov0n3dKt1Jh zYgF9XM^Al$DftN|T@I9=<$y42OnuZf&SaHsRmgI7m>ErHQtoGxwrWg|0$hj%<}VyN z`53=BBn$lz>|ioeuhW#HA4Mm2E!P=)S?gQHw%=?~EZ~JeG2m(IrcUKC&3_3k=Cr?7;oTpgLpF1q?q3(GG@W>kqv+Rs3QBU@1u;I zmb3Lll!62$OQHjnt>M;-nBPtV3BDX78V7F)z};;f0f-;B^RO&>;BlYLu10dkk;Cj) zK314EAcKfBn~&v)?m4K~&R}@^02)_yo0o{+Ge3F=5-|XJ`>cJ~qZ250Wp>>@#@0em zVR_G>f*OAYx(y>*IOFj-HrWH4YaQPJ0Qi{5I7J;rsmU#RB{zbi1}rR1NvACVJx9+r;XE>i#f(T0AN3Bo zLmw%&X_7&9WDG#N!|w`qJ_EMG1Gy2XMAnprwc~5P`G;efv9W|Bvcc;SflTa3!(~Lm zY!NIMn@YckV0c)H`G|-_*0wI8xMt8&5iz$B&x*B##6q!M$M=-rX39Hk5j+a@ujtaw z@IVxF;q=1Ju3Sz%O9#4l00y>nYB%24p<#DsL0HdbE^F4|m7#w0hcv8XKt@9*rTDWh z>_~#36o&TKOKimT_q0_yCAO1_$XRCH38nfEG`y{E2zvb*>rVlhmqvK|Cy2Rn!muI+?E=`{j!4!)CpW#m#l&A~I1FKp| zWK=S6Vssk>uup;FNO2*{a-5cVXwJo0chUa6+plZ|2ev&d-8#NC<0G^uSJ3x$F!NHo zEwePHHecA66JX53vbGgSyaRhHPyogB;&xRZk%(Tk{>MGJhn#0;?@lvZ0Bvd)Qp(<6 zQUQQ%+t+DXN~aUsB%nEjnkA)iZG$iWujSG8{$Z^qA9A_2Eio-Om{qsk$lQmNb=f~C z!YqjNi)v4)eIUz10fQ4^eAAkZsm7MRh$?rGzHdxO{H5p#AK7PoGDj|0-6mvrE=RpL zgdU6E(MZ9=5UV!p9497`^+=z87-}H$op2f5D{(&%iGs>cj1sA)FH(N08}w&A&) zg)Q2l&zDkbp{h8?;5)aw-+vFbHhONDujs__sP)-hJ)2v*G;?o9r(Rzy8mP%K z5;-CxtBfPN98s}&p-}c5@gHi>o&&{VUI;pxQdx#$AMTYHsPT&ZK#Gxv9VR+^!`9qx z?u?R>DVyNCQ~M4#cx`6R21R3{HPh2i0J7)E>KWMRLl#)&g0`7gQhEj?sK&Lrvpbu* zwhn5&I$Mz6T9X?~TiOa;&}D1aZYQGFrSXG#IpacrZSdU$|iCMXVXbQ4+126JMwe%DUwfN;(v)P%!f?t&^^}4IY_$*1F?b<}QN$6?NlG^BZ;-mu?+|E4JleL8 zsly0|5OeVU0=_|5Q-?uLQ{N$ds_zg}(s#%^>pMiA^&OH$xF;#)9OUyQ9YWCh4moIjhww7)bh7nR^)p<5j<=LE zJw>M~#(jW}@e3Q{5tuQ9aYeZo7I+=F7|Y*;hk||ZH*iSe@X1iP4?Z9cNf92seK0Vd zM}L91l;C6OCI^mCM(>kk^%yDJC*{@X<_d<6Md&yrsoV$GFvwy8FB46yNsKkQ8s^ET zRL^=zyaQ4-BvauFWY#{JR`Vh}4Z^1R3CLhNt8(H#nPKe)t6!>L*;>;OFuf)e*3jz% zJmvXOeyx6!Bg)Bs6o`V^D86ZZY|!=S6b8XvQ}rgeSgC1(9rao`;X=J; zv0k(HNo@_k!LtcH(afPssY1Ht!|T&B*+iYosPoWVMxD$sK1|b|^Z0g1=5MM&b5DIn z77WS4!*bewS!65|I}{7IwHYNiOGj;Dft!;*tH0Q=3sKJkgq>M?SnBEdF0rZJ`55mL z4#;9SOgSBXukd;X9Mtdz?j<(7&>r?YowJRHt4V?(AK|{N=7lG;mq`r03(%%7&vKaUW$gdRLA9h8-HEprN=&Zh6gRrCULP{2PsEazZs&fN_c zX86#=537fyx%P#}29JD-PFWK51+_0!7CaYw3{`ezja-15td$M=egRAc@*T#T)W6if zZIx0sr~x}>q!oq1Z7}Aj2JD9bQfmM^Yf)u@%X#1fA-)+x^!z%`p;~-uc~QG)X&I9B z{Img|Fwk&jcm9xUr0*4e*e@6GhAi2WykBVV7uox3cps9Bna3IMq}WvRyj;3l;x&im zQuwesKY1BCg1xxel(%_E+MWbR_Qs1-ku<7PeimcZ$W-J96s%lztzkthwG~= z>I-!5_U@*e(DM&TAMjj%a$rcVq;n;@bxZET3!K1QgIn@iT$t|aBg9O;1!)-f7G&TjyD47{9x1GLfbRX~o`uTan(DDQ9f7@d z0ei!*#cin;Cf~-2AXD2`dM0nE_M;Ka`d*xzoDb&Tpupgj?FF2c&)+GqF3oboum zMYZpd8MVx@5IMr-4|BW+16NQUuP9u5Q`}_y`AT@NLu8Ko+UiOyw-tVaA@^%r^hID4 zBKBuc^8+cGFQ@5nWl`jrCLoZ@cMfYrotB|8)+g z_q6)_yfZ?>cCQ&WJ@yz=fK0w~#>CySf~Na7_`?sMtieFP7b#Hr`-bFxJS876uNw9r zOl1ZTCz6-|#JCQ_jtNgWciTJ~d*yh>k8kawgjF`dL*f<+}p6%Hc2*v_K zuQC9@M+s7NwonJRWRN3%QA+XfL3)#X?65rk1YSPmfBi7OKEba(#S*JLuIy1xmh4eZ zdiLXwD|=o0C$rXmZ>07Ujw^dz`;6>$?W5UGj7_n9Uu*lmDqG)c_jTy!r;zzFXmREaJ)Ib2!%Gas4Em(a?Nejq)2}y+ z=ox-5&5Y4OI?2m0{WZ-GhB}B1o@%?l+(#q{F3 zX(EVepz^;IBW=2<_Idd-9FAfm@@3TiD?{>C_^HOnukDsm`1m#R@#{#mfu3G?-!I=V zjZ{?Fwb{Sf0@7;@@O*Pq5*`%4{T$-A=#j^uKU(v!I8W}C@0i&zB;U0T;1{D>Tot&q zOt8;20K4zeX`g(5pR~YBE8c&g-+!pz0iZw9W&HTLYE4uR$xr-RLBZJ6N}Y-(lW46B zYV}jr3MBH+R-K^M56FwCA6$Ca(m(7Dx1P9Dm&5#c5{tZ6Ck7g00V8Q>b%>a4*j?o|D`-?J>E5FBQ z(gMG?k;V?mAF5~ZWk~*LBCgSK026=0LoxlN^L|kNjJ=U|iLO_!33N-Wm#)9mbD7;t zhqix(*G=nGypT@C3-#XayQ)}~qLWHhIq&#Wu?4Y(c3^*jE+n(zJ3$xz%?|8Cc093d z0bxBqL~8t3h_?7UpRvr7(EUe*&fs*_^qyJw(NlY{?!!yyko*%r%q}y?C=Y`SvgV<^ z^4}(_f6e{?>v;z2iXZDY8NV6$&B3p}8q;#W{QF7VKZiRUxZ>$Q`pLzT_#|>Eu{*7Y z_RA3;aG+ykTYZOZ^-a2xsu@#d1}gXn9imP`4Y~a+pEYYpshWc-hNVsA?bg7Z(HZbG znd*%)g>lnFf0+WE&8-C~I1pXcHGW3$8i_|}k_{=h77?ruPKSy_7X25ajhxGd31ad7 z=@>TXN7)9nA_AjucR6;#{q$CDsx~JzP7|=)l&L~Ehc8nJ)TT@orK)PHHGzyFJy3vP zPBcQK-(P3Nme}ILNOgmcq8kFbnCl#8_+$VP=fQ@Tr1Z%eJ`5?39mk0tU=`>Q*=)xn z6$f}!b@h-c#z=8;{)XEla~oG`1TTZ>WG97sa`|EpC42u9G_C%Y4FGm!dfK{sxs0z=*BU@ zmvZ~10$jSG@hW@I!T-b@vEKsFb&48;D~k(N!oM;27?SCdT3{-aywuT(i& z_8+v&?@j1~*6QNK_7}~-QSkD~eH~(Bc~jH%1}D`uW$HvUm59)8aMX;!Bm23?v|LFIx|$Qep@YdvZ+?Jsn(E! zGwg$^78c)FJHO>v`u*)xnF1=;HRKM;OqPsB%+74YTb=|!&zAwY+U~AkW58Cv(gM4N zLEtLQvh_y?iikGazYVO*AEU627K4D}`uYWnJOQ|T+ASBSh!jn+q<~^sHMW@TWHn+1 zD&~z-Le-@b7{DQ%fG$8F;+UBd=h}s7kt*#!rnHMviFIkI$<=`2m=h`MKUvD+Y|~|> z5}LC7u7FCP?TXK#E6Cp@K0gCs+5|9N?GKg((^`Tlw?JHvt#Gj zOg?3&!{Y!Ihz5@;BfGUPgf18Gr;dxXA%R9t|?Pz=@3B1l8wM_4gPx799v^^{wMmLE>>Tz zd0s8uEw4kYWlVep&60tbvMa#_=KXGY0bBvW@6-B@u8uXw*4locn{Yy56{@j% zw@g4anl=Bk0X4tA3f#|lbrtq)W@<9!c{U|U6iw5og4UTJbq3~a9OcZ_y}0onAT4CS zX1AJFz3FNA`D(@4Q_W$uW=O4Ft(vhPUg)5^z)lD2@;+H^p7Vy(y2Gjk>x)_sb}X#P zpl2rC`5sNsPeP(Q?;&Rvm}y(QvJFSV1 zs%s}FdK2^p9Yk0GVKx>M^@e&U+A}vI;)p$?wrAA%CZr>dzd1|cZ?s`=$`bZw zmd7Jh^_Gl0ZwbO~%?NvI5O!Ne7^a7=%k5dpyTgXPJxdsP`a0b^vxIR(*uFcnguTm# zy*o?TT{i6QEMdEC*gaXo-ebdHy&_{U$)smppg5lqM(|+R{aL~uuwf5o2_t|o-JUFA z*p}lunCUGT4S3tf_=ZlrSVu>tlb9FjTA?$*P-e@6NI%}4B%2y0Xt+Nh;!Rbwq_MU{i;bECfEL@&m8d6AW zX5?Jq*yET6C!@PcGQI?kD;uJo9Y?Or^t8MneO9nxZPS_tkeO$O2+r}~4_x3m(YSM*d6e!Pi6hcIF_Hirg}fZ?K(Z1~ zoT4t@;AycG_eo2}M<>xOCyjbtJqQ~9mLkC`8K<-DxK2?;b7?qWST zF)r|6=g17kI4RC~=g3U$J2vPr=pv;JR0deS;?WAm-JO1ZL(_&8ElSSHttEXlGn>G4 zC6#UaXsS8lbM(02$zp_*3ii6JBGs>C)L7-yt;gJoEV*ly>aY(gKsIny2zgnjR9e(^ z1?n6?WI^sJ)CisLKrh8pU#>? zD-f20=!qyQz#FIn9V6Pa_LPnGu942n5Py&89I+CMm(0O*@Gu$ku=Js>BDkZvn8oAS zGkS(|?w131RNyUGX!i<*HxEmmUdw?W#zOMT#2E`rz~#883=)h7B>%8DCQ^(YgFt3f z1|-D&JvibMA>e41YjZ#}5!h;yOtiVxqlWyOeMp>5Nf$h=_)}7-UlI^!!b?&9GYHDt zD}^naz?>;+dCDgdV)n>svc^)7bUV4Z)pXnGY!rwd;bu2I*#YCz+fnE45 zg|bp^<>jrs+{Vk>c)6XIJ9v3}Lf#?oV4zJAD+ z4=2zM@US{f;5%}q>`lm1@-(0J@iN4y`wN!bzJwi*736@xKjBLG2%iq|@=?A%Q?O){ zjvxg~s_esAH(m3?vp+QET9)%{p)|^K2{|m!7sFt`GPN152WWJk(#RU>F7Skyb3 z<(5%_qda3`oJOx!1G&se3E)8#w9oX5`)7tKd@oKs-JpyVylo{YS$NL&v$DT|G-X``32#wsgRP65C!iK>l%=_q&W;ML8ms17bR4#*Lb^mzREI?udP3}Q zKdR9%GW5(*DI-NygmY*&@$&{fT-qq1uOvP#O=rMr42R;NYSgk_4hu#c>`;hN6$xe9 z(s>O=IxwrzdKJ`rF^bxc9kO8+BH7sZq0az=6p)|`041r4M*=5?Qc-^^4UVY!VQQ8o zkXmbgMT{~GL7d7KCQ0fWyEgUK@CreK&6#9i&SaVe%-d%+QM0&jOWl?om)Gej4AmcK zI6*7IpJ-v1aK}OBkenzt)qq+*HBJ1CwUX}0#WRD-AOomP&=qBX1_IpCOdNoYUG@sQ z?HoOok}zDh6K+`|P>??pf#}t7HZaRz7ulc{8&@{~i_AP{`EsV9YCaIw@(pP|K8~k9 zfeOR0t+O@g4%{=VhZ@;K?RlE|d#g`G$w% zfj4^)t3#}2S>wsKp4=!mx$-?v zzAry;<%gd9NPg_fPdxdlw0ZI~CjGhm!j)fo@+i>v zr}9VH?#Z8cxm>op@@G%}BHf;J@yk_mwI_d-D_r@TC;!E2?~-dg`8%Kf!OQh*z(3`` zJ^7dX+m-)#as*0eN_i@VimN>3xC(~u3;5znhpS+&zECAxRpcp;AB)wfEQS&-pqg!t zhXd|XSB>^mk}1k~86!Yn$4GK!*{dI$HfqRv+fl$CEZDvx+B~97*Rl(i-av$p_O8X8RPcJlrsa$-tChm-iu~wO*#%!RF>+4+B5nE+*$Tf^cbfSFpEzlAYyPZ zlcF&StcLg?)fH46TDK!EenuV8EZ;_x`+|PhBI>vT+OZbX`)aaUY5e$|n7zu}&zZS4 zbOs-S6bZbo{hz4KM)YLqi7&fK>i>e0Yg8-sc#M2yQ~J;9Q!m2^g*7=iyb?Ei$5__l zk``70PABJm-S|`-O!CO|$c$m27?e?$R`yO)`3+u4H_BA(fX@a;VHJ2EF;Xem0mn$P z=sTz!eFveV@1S+`9psL_gW}P55Iy=1x(D~k$nPSksVN9ah`bhpT0HdF36VBc4Got~ zd4+2?IfZNYNsRiNdC_l9^fe!^?xws^>oz%~*6qW|N#xayzQ)0)(VC?=+bJ@<7=;rd zobBkE%mCkn%$o6twFE+Q-jw}Xnr@W7<1{*9(!@xk*);D37l+*Dw?lHMgt}Y%rF3CF zZ=)Bw6%@LSl{3vr%bLIL|k#~4ZOSXfwtA|A%!{(h~@=;(Mw)io7G6@?W= zt^1|C!bNOofz@@GWCx^T5oHhEa%lOO``mFw2W0Fzyr7(l{Iw=Qg}c^o-ezgDRh@=A zJGugKiiTtyh2$wxGbEKmGT!j66r@%@mcjU`5hpOOQE)^>yZzCi28o z=98lNZw>NKtB*;d^GA}P2+*sxK9#tW;YJ}Z)PM3pnGz@@Narxos{Cj%(yBH$s1N80 zPcXSnrS9Q0h>F!5mT6D~rq+qi&I3(*REZ!0=qFN;?CZ9P2<`-{q-w%YpGYB`I1VLe z_!0!vXUrb=q%3iF$`v->ai~B0gA&(Jhw}h{b3crC9)$GfiZv=6t1oLTH!ZLJT(Kf~ z4Fs{q*m}h|h4#x#zfMVeO!XrwYRME=fbr>HfE}qV?;O?3adE@_sc9l%IktCOM#atK($~m zj*_dX$4;^C*-LS$L-r6&k`hep{Hb`!>wq?8ZAE^Ci&Fksjyr!Xp&Qe^`O8NRQt^hRgWV9lVdk* zi-o|T7NI;N?{rh_R4ALQ&O37w1R>8-;1f@;opex^#K4zrsCSSvG{&hVw@k@pr$gy- z@W?kN-0WwIowm*PVw>%GX{~|eT%{0%fpopBP66T*>C;_I@W#M>=O+F?Ac zW{|@RRl?ArmEpLKaN<5mCfgJDDN^Nux|lY?iTeps1!E>h(`xiT7*ivjvrij2uSkK} zcWI^zf|JRUqbHNO(||b3Z`iQBaSa%8AzuBk3DS?i^UrTwzG6-3|IPU~PnYcZcl6x* z@%R7W_Sq-k01LmFM+K;9XG&jA$fNRgp5}bRm2W11pubfpACPY+zzq8?I9&;p`+Zk_ zkN_6_p({U%%a0Q{?*D!Qr)WPZ0^93njPdh=C4c<~ipRMeKK-H)+5M7Fzv9!c6Y?AR zEuVhJZ@({+Kgb{X`X|2r*_FRAv%i9ERq)&&bS5|z`Y-uAEAkwF=C^Zc0$Lek;;KBZD&lHvT#bvX%7P`&EzvbBSn_%E5Le^lYC>F1jH^j; zH94-P#8p*XO^vH*t~wzB3jOPG1zd2RIx(SUsFV0KGpflRVTy2S~t#P$2t~%rD^0?ZLjKDEfT{zWKJ9u$;zK7v#9Ci!TeJu)+t-DdhPm6m#$v1ys_cZm21|mZdl&}%llzLh>QuJm06Qq-EhIB z8eLqvY*j;Z^NJ?qqkwkHQvodvtJgNIxO82^daN##?4Fbn*3x+4ic1@tFJ0QmdQ@D# zV~cMbZ#}Gr8_Tm`2$rOo{{thWrE_a{YyUtm(EX{=(4+KOjlC%LpKDup@nnfev#X=8 zFT{~Tv8ADmX$}l1vLWqLSpMN?dhSf*F(q0qcp&S0q6N2vN`bBUEG;_L5o5W*DQ0v% zY;A9kmcDl8Qd7Q`@-Q5=@Uc%uJ9Tn)VHW4$7cJ+BP4}yrWwdi_nSp6YQ{YGb=L*a+ z8kya7W?Hq5GLfmgHZ8^jbi*4}vLb4T*0M~)N9q}4l6BTD&m!}){MfT;$(Bvps2qE) zyGG9SD0}hP%jT(UXcA~gr8I9n93hmYhiPM6TZ&5!9?*#OCJ=T#<_iKDn{5WQY{=4n zYwbLUc0B0jD6GTkxf_vSJ34qeW#-c3NL8K{&5vxP**f5irT4-@?Y`gVKYIg(uI*vmW+tAHzwJ7B17{l=6u!&!_=U zU8$~e)zzNbrLIZie_9A?7-;Y8F>@MOQh6b#>uZ}LFn9~0hpv)f+r@gSydEHz}NoLh8taVge3$56M1P!E5N7)muDyTt4KfThy(t zdaI{yQ*ZO+Y1!wg+tnSzNFZm<77F`#>h0FMIMC`Mjsz zrQYqSyVTvDd|Y1Qx6gWNx4Oqw@A1^V>b)L>{O>>3GbK+wz_vfA_ITDe8;q`c+=C4KhuKe0fRLtVYb1+rXlmF+q?xfr}*VN zJGQ32&NYt}Dfvj#0%NQf;!}Mv)LM1X)n{BZXO^e-s;6A_w5Rs5tM;lPY`QM4-DSe| zs~fTVz8KnC1v*VNw!L&pcBM^?xaPH*poD=RotiduZja7Iv(_$Ky}?rl)IrXz=Uw#? z?FiUY&(IriK`Z>bUfqgfx_gk_=1v$ur;JzLg4w4a?b+xqyqw*#8ZXPwZ=7%PgY<>d z*|ZdVm3U{@<~Gyd{JxzX9am!}=)3vG4A7@eOJmcyh|HS_DCq}*xN{o>MrUc$yf_!! zsV&!bUIXW8J>9clA|KKK&wA=Pb=XzUd+KBA1?1gHyweK2bo6R1W-PgHuHe^M140LyDx0ADZ9G~(h212-_ZT6L&?HxU{F^uzPw|8u59q6Kc z|1EGCjr#6@{|lG?(qV)Xzz9Rm44Bo0x^~U#Y)8M%U%q0_+%0^VXC9nY$cavc52B&W zl@0aOXXpg@v+4=o^?_Y`y0>?<2SZe_Y(vZXHR$48uERZ;@O*;c@iJOm%Lh!^F9_XWM$wwG#SJGkf^NoX>6>9PFw4`aTVcIL& zL)ljV>`O8ZB8T_KrcGc&HnXdP5?25rEvjb^FAK1nY3PEGN2Toy4ZbvR+|kBqy7=S^ z{Q~vw#t4YU`+E$^V<#@ny6PX7BeswOFpb*sAVdad?%{E=;^w9ob(QRwa4iCv^x@BD zxoYk(UgGsqtY%&cSe z^M-M-K2I>bYYg#lq zhDbqU%cV_?%^NN_1q+S>D0%p>v9TFaW-a`b(_y5Q3Tgpj?C3VqM2)~ZRw&sl!QsGk zhe#Pik|jg*Sx5@+Xi{L_p_@jKcRnH28GfE!otrO*G<#=VQ|D&L5cPFp+9D(P7~0ag zbpTWp&|{176-peH4YuIzAr-eSTS_!%erC}lrvs(LMrnccGz@8hE`%X-f+0#bM-XPv z8=9A|Thj=}W8m&F|0)B96SKRY@Ew{(9H8YaE#=dpV4DS6ito@zO?L+^>}!`cdZprM zHFiVSpbrO2PznL7*@Z3+c2an%BypnepilH2Bns~1xvv5bcL>ih*^hT@$b$Ee;2qnt z;Qgae2UOgV;!2zCDWd^_!tO1kr)}^!R3IPGyzw=)vlJ|&9*~$h8D^}Hp+ID!wjxd` z?iay2>jL+Xvtbx^Jhm$f2GS#yK3yh;xhhBQLyq67@dgo=e> z$kF^3F1v7C!Y>;MP1&9)yE1-I%9PwED`MjxkkNZ(48N44R)aEruT(%xXKZDBuZ%k= zl`)Ljcvu|Yi<9Gc-a(nj(_V;?OonkBem9+N#`pysAblK~H)aHB+K|WcUDeNv3yXo( zhiM|ObQSFP;LDWVl0dET=8lo7Rj@rU?W6;8!kMv2_sil*2V^==xSw5+pSJ*q_~rR9 z!&`}i`+2lthw@>zjyCH~gs=zf`&PP7+*E+>{H7HwVJ%*?wSW#8>OnoRli(-dBmyRc z6S(U(FoMHjN1v@Pfe6#ggL1NOMI4(yW4}gfXeeA;8a^nqAb)$;Ju@&#M8>4;CFgik>!$#g^oO5z!I0v%m_Q0ii0qvT!x*8tuVo9u(|H z4$2~9*-B^Dh$K3*diHX<4dt1%p**iXUKzI|t&8z$2_zbHX-oO*gGZi5l>kQ09$Ac* z>8@klbO|T>CDgKnw0s~ZzBILBFi@ z`=!2lRyxR>6oAY@0d7TioxWSV8d^Wp?I6s21GdBb+6S4Q=x18X1_eorYVc-i{tZaC znCSs4{XS5Evtuhi8a8i`amJMKnW3~_kT2S_fvGP50>DKlobML_ z4w8-bJqy@hs)n#x?6KVyMEAgqIlqpt)GHSHXh4_9>==ogzoX_Z?vYKp+5`125pObiQw$Ib>yv9C{$MahI zJmoPM-{)T;84k9sZ^9JjB);~LoCnZex4Ifui))iDu#&&A7Q?y$ra#W#Set~k7W3f( z`vInU)&r>}YLl?=vVJ3t9oHsd<^{1JHxo^U51Gkezz1<*N#6`WT)yV7P9>)9DvBWP5EQw3Y}45vX2qYi6-jjw*fbt=t`XkNejlv z)l3>oUc*?|gj4z*k-WCaKCV6>uWg?75)O+8r4Ta^HgI71J$ap8^#bSHq z)_XAhu*kg?m?}NgR;<3@klcnbe;ZaM=S7)YS&+Q_klcYUZ?ANo*0$o4cfzZ0mSF zpX@q2s&dp}d4L4dkUY4cl(#*LM)UTNrXb$8psc*GymSwQbxRk3${9EM?t8@@2LhLHnMGr@}D&4 zEEF5PY(>H%2ji}c);0;0RT4Wqr4t&x!v1H)>7EAGs#Q>F?aKt1g=O(6S%=xf&)-_@nLN5fbZDvu0-0N&W5K zD?8gd2n1=+^Hf4+$*Ket;m=7xuCb|5YGrkT>H>UPTLj^wb-c8=vOWQg$n%S+4C%@y z8ZWufm5UOH2Faghd5tR&a*qLr&$d95q2bLBdh z-cb^*JTF|<)w#28B*~bOvL z3*f6qZnCPtb7Zb7Z}K4hj6>pE|wFiy$rnVA#lajRvXEacgmfRX&V6|&cU%8^q9J#I%q(fxxWiA*Nr1S zSKjT(U2?Z8yFC~ceGeFWBV?z+$mq0&GlUg7BN?C>uka1oa}}LvgVUTE8sjl?ISvW8 zdGcPl&y)M*Ru5**PW9vgdC-+To;)P)bLIV>JS+_!Y{5R_frYfl!xD^FSQgP|^5`wo zt!8e)#)tGHLM@WQBv=&{YMON)|=Xpiisx+5~-Yr<)@w z)`wG5v+x)aS`}VSb|4BIW3I(i!x3;+{1`?!C^2#(7z$k?f07-1iomuw=hwsNfR7nCU(NDePcI+u+SM11+9>q73*qB z!pJlF=&2cQ){l0;oNqN)hf2&8w?4&rBdb00b45H-*aN&vI+iyy$d%Z&+L@~INih*EC!c+ z>8edQ&BR>m`xbv}76m0mAh}IjnLkd?`I76%4N|*e_%8K9ON*BD$}I_u8j?i+5=|*e_mj&i(%YK=McU%!OLRI4er_ zWhl9gr^U-sGB2PwGfI-$KxPG|QUA8izUerp$h}$0T?!VEV6(I^ymyIW$YC-drnLNz zyxxIsjU(_W(;)3w576m(

$YYm0ZaScnz!MYF@x=a4fH(OfFAA%lLH( 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 K5w8W%U;hXE_)c*E literal 0 HcmV?d00001 diff --git a/lib/native/linux-64/libjnpulseaudio.so b/lib/native/linux-64/libjnpulseaudio.so index f8a3a2893b2760b08e8f158f5133883f3f394c6c..3845ff51efd87acfd8f70ba687608ed5acd064c3 100755 GIT binary patch literal 33480 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 literal 35592 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 diff --git a/lib/native/linux-64/libjnvideo4linux2.so b/lib/native/linux-64/libjnvideo4linux2.so index 05aa25bfb18a9bf61b66e3518a02d1322dd7ae3f..ddbb292f51450f705762d1f74b832402f347dc2a 100755 GIT binary patch literal 19632 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 WOsY*~-(}v}v;HT8dt=a>d;bf!EYS=A literal 40908 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

6yc6+Vh=1Y&@#Tmw!My3I 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 iyt)R3?kMAR9&43ycNue?E<>3ngq^1lHMA)t%^ diff --git a/lib/native/linux/libjnpulseaudio.so b/lib/native/linux/libjnpulseaudio.so index 1cbecacfb0d82580f1654952ca4bdcdb37542ce5..e36eff9e09d7f56633b5f7f2491064728b7bc289 100755 GIT binary patch literal 28044 zcmd6P4|r9@+2?_T7&St~h@l1z5D+VdMDX9IpS=PXQG=o}hyvbRk_(B3B<9{AD(og+ z!g_len*zG6Yg-iS+OGBCtNo}}>juLk@?qPQQl;NQzqm$vkyL3#iq)F^{pQa(b5CxR zlXUml$@6B;@60>z%)IlyGjryiGygeQHgCj;5ta@aR)$3s_^M^iLcDptOqpdBTBEFK zR)IBMq-%c02ZEAD5#(ATUEHg{eb7z_JO;{A=_3&zMV_NbBXt9ln4YOUnsSynybF`yV|8i=Z0 z3Su}_M&f^&y8fDq??zkzIsyA8|GasutmT6)#47 z59k`uP3qqHD!vZ!Sam%I@j`XYr~z~{C`zEhGQ=r8zEaV2OR=qwQXWDN-2Z&BwA z3qYemUm^H^5N<#jv;`f;>kChOr^2VH_+G?wK`TI)fi48C1~I^Ft=q(vWnHb}b5(o} zV%lGh!h=P3Az?D;KF}SC=~5LlS`NxLu)Ykbi(q~F1+4^`f&Ox(x-rsB!1XPl zDeB(oh>Jj{D6Av;bBzXwCxRlND$v=W^FR!jgUZE~{C7K|S_AX42{Z>pA7fo)<2z9bmk=!4p}85b8@Z1ALLp!6Z4AZ z23kh48%E5XI%z6p(SI4V-dGp0{-(dsHyLO<+8>E& zyYva_kAY(Y+s=MqyXjlHFL5dSoBhl_s|2x6sYBY74%G483eYd>)HTN$+F(>+jvLzk z)Ggs#ygv7*U;ETP{iVJapMG@Nr@g0dd@?Y1!@)aG4Sv`LwHVZalcO zvHOER?EYTfXU86VW8%jmxss88ovU9#Z`8OY*@zv2sc0Pamo(&nlEqVT(J$XdE)2qZe08R(mlUB`|`;TbsSsx>7OpWYQvwJW*sa1 z<)w4&$M>!Y9QsXbhW+bP_usp?Abi#3G~1N$DhEXsIM(IT7*!xH;ozhK@k|c9DiBwk zsgWEjzfNaYf$4=FJVGZj4K&4r=hFdIVE&05G*uuT%}GNA;v=5&&l#mtrEmS64yFS6 zr+V6VC7o9VroZ8l|3^>#|L0knTei2~7$}&((xcCbdH_Wl)8Fy5=ThEOftNds`V;T= z)OWrykTU%PkG`Jv=p*2%-*-KDtVcf^JoWvdC;e}p`i4FAZSl0P%A>EP9(mvN$a~z= zzHfWlx7TBTEgpQxlYfmzfA4$R_pryl$Em(xGzl~h_3IAEacV4Pu}$DF#DH0bG~&}x zUL^)o&RxWl(7uHjL^YlO{cM@(;(vhy^jswEp8W4&G73zWYc1j&@RyWgeS!PLt01q% zkoO4f6N7ajw&QS}LdZyUIGuY=*ls8S`zoUK~z`DL4!@iGBMWRSQ&AJ2poksm;WI!IuN3}%x&!hZK zqx?MN??L+mD*eak-@vtUZOZm^K%XUsKD*J-M)bFCUq9M+6!K>){fjvj`lwX${(}3t zNJp`v{J-a+{5h8OGliq5UklQ;{+@@t9$;PHbD@t8)aS>F{{_^yG9c$_)~^zbJ<#`a zD*XuTKNpLxe^dBD^jEiGZ&yKoC5C=pK?iR$?CDw5uLJd)tnx2GeY%bMEQGyu8|{B= zB;*qsumuZ}W~Hwn@)sKUt1Zyn?p2IQKP_yNdU2zk1^b5Or6M*Z%Cylz9@@6n%?=uhnrzk%Ei^q1E6$2sUv z!#)ZiztE5$fPT1G)Ao4{{HxoL_unC?14ghz)i;5-67p%HtnZEJ=pOV>K;e5l?foY7 zRSA7 z`eDhbt*?%(8I}a7vNqPxq+9uqlocwi4-ZpM!xj(?qnpup(Z)zssI;mkTwfol^JNPI z`Yu)EiiW0D;n=X$mMX9*9P?*e$~yl6)-_O)fBPCJ!?Cc273c?ef-hwal;_(f28u}4 z_>ipP%Y+WWF1}2pw2Ygs58Yf}QD4^(uC{Ivpp2K*bQhbb{js!z`GfJttC%t@?Hp~*Dv4+O<@dGAU* zMDgL}V)EpY$}NWyMM9MKhakDRzA3W85Ge5w1c~LDXdveHa9!QGDT zYC@%rO%088SiKuY!c>vyqz$16F^q`bG9>e+yf;*da+&1X1SR@kIw`lVM%#_r2{?p` zRo6!G7*ijqGL>lD9D>NIh9B@p{5G$lF@gm;9_T}*&iv-y^F776 zS>=v_GibR9LmIcl2v}FUyeZstKh`LbrYQFyph70-`}($zE^&+seMxZ|6And;axpCi zdp!Q+=p7uVFZ7;{@1D>Z)n?GZg@9&2Q-`q<&{9+}YRAajaH3XKvqVv3sjVl6{~akU zhz^u)($(oq9`dZKg?KDj-yV|v>dZ=J$}_WGF=!r9faDOnBO=|8F=`_cPGfEar7cPJ z2ln`eT#hk48=Y<39ZKb)4ZRA`iqW^=?_%S#INDHLVgXh0>M|=7sSd}&*i>B}jnbs? zY#WNyS6kPWT|awH=#t{n;+fXMin8)xs06#RBUAox!@=%VDvw{pw~YRO`@0kS)ch@| z5EMPX7Q5&f)>_8v$Y+e-eF_-k_m)D&*yk@|j5bVTJPz+YF+K;scQDS! z&tQzl ze#od~T!eS87~_YJ8pikmp^otd&@ba@cvp(?g?NXE@mDQtEo1!F(83tMnXG4gv1L8X zxY)A3!FUFKpI{7A-pshvvcAn2{ZNs3uRPwDnS=(dC9PfEV6`_L>+kPx+Z!8|d<1us zKSZ}AtI?*#OLlklzktrM`nRGBMCjiNrOUTs4)-8i|5jQ|4U-Rd3(Ox+YIyT-r@&C6 zRl|RWw+RfTSv7^kTLk814O(g)?hqJCv1(9r>u`&}Osc`JU)JG9fzfEICO}*%Fj;Hn z6E75a7V$#jfWXXJvzWLig;!1(H5zi-HDDY2-7ZL{qevx=Faf!gM5LXfx3fxItL!2w{PU1#lOJJ(DW)1Pt z&)EJqiCc(!fZI+0j}FO<>UW_Z|(SeWc-5>S00TPwr^+dc;|?OVC&x;Cx^^)<dla7`iqEq*(XQdnXWQ`;yy}dd-Y)JX@{0Pq<2&<~EbFohin=-&DoQ&O z@5TGBNGv;6x;ObA_*=Vvj`1bYe8O(dO|1LOURPk-7Mk0(J2u4*=I@$Yl*zIz4gNghpe~x8- zmp^wfUKEsC{+R87ye_l+Ku&6X0=W)$<^QAG_kXLti_zQYkK}O}cx%@lOfTqY_V}g) zP?`O55C6w|`Tqru3~hVIJQ{qvtsnpQB!b<$;$&mk74MT5xax7PjyhKq!LTcSOkUuM z0vUG2IjAt~ihm|Atme@z>)y7Sv)hi3S^st1gQ4UUB`S8p*s?QWgo)sr_JTLtgT1u4 z{#)|xik)qp&5M``R<)qlHLQh;Th{I2&0w#c3meUZ^Y!1l*ba8XAI9?Tf^H;~>4di9 znm49zrPy&>=a{y7c*l{$?b5JZdx`he*cEwDY4REPdu!K&)0F#Ux9t@Ul#>YVgYSq| zqV#j^-1Y^%Y!X}TRG|P#XQq@%`?D)h(>!~mV1xfItZwT}1b4>XViU6A8i`m@p52^} zCgwva1$J;B?qmx`1kM2)d@UD>f&%Du{oi6&P;79geVXuGh`nX$k@ec&%9DTil@I_>ws8>Zd&Uh>%yM<*@=M zCGY!b<;DA^C6=8?UMYl*hEQmv`Lo39UKJlptK!l2GK_3uY!dnn9)lU^KBsbDj~%pe z)23w$3(3~W8-?alGAuQuiE&$uH`LAU!?(a(_}{47#Tc7l8Zf$(GK;Y( zW+D1X+I4EZe=p2BM^riw{>|JDdmFrZ{oS~o5F=XRWzpv>@oFtHrNjlg#K}4t zC4P1A5+|fDF-w%#gNh|yrf-Qx#I(qi5)bR-lPvKi$?t9BQ!Gmi=!uu55u=UIr7f`> zy(}s;Qzw6M8z)PCZ;3g$oe*Pv;$<4%;nQ#f)4VNa434IonNhSK6HD6(q8C^ z!1h|Zx>ESJel$4$tAc-13jgH6>w`*+*&fVK{uhyLDYDVgA5VcL~OsLVjlQ z4#APRWSJP$y9UfZSpNzBjFkG!bmR`y&*!LXYu9fln))f%?Uki;sA7cveGrz9WTnV`DRSG**_b-*;Iu@=o4bNy zF_Bo;lL)@i9_-;1q!t2p#Xc-;llP(o%xhR+-f9PXFzDQP<*wBu6T9pz&VU&9a_ou% zTxQ!9`B<%r$*`jk54&K%;XbMk>jXdg z@-oCCNfj_fXy3`7vfeFEet^D&{bSq0^_O@5GFX3=Ctnr(n^O3rgY>U_zL;h&$S>W? zHPS;O@9oGdC&jkiVvUp?8*iT?7CBd=D;`F3(SeiOH*Nks#u0QDdYc`VeDf$YWjW=^WS+x|VZyd3t7pYoo9-delvJK6HQ?OXe0<#9Z`MwD?D z$}sv1!*%-cE#9}7{sP@+iG2SHTRW!rU_9l+Ubg6meC21mf<3TA@yPles(e8&rtMSg zik`N;&1aQ%rl>@$qq1P=;vul(IoL25FA5f1*$w~e=DK_w{1|2Cpoj4!SfF_2G9*A3 z4DLJfKPX46H?T~{U{GK$C_=62U%~09TxowY2<^0XeT5B>RSxdQBWa?dC$ZoF?4`iY zf_G|1b$tA3dMSqi?d7n<9i^S?cQ*&^1^ZD|J9t3UNK{Vvo~Ub1QSuj@1joU6>Bbbu zrA=^O|Hfz8NVI9d1Mk4~6V|`bU~5-Zf!SZ>gZ5W>@-D$YGlf6n!@>F&jfPN4_vYn8-BL&t6cH+<^wRc0Go@V7Ko36AShYweB~-j9`YS zFy;js7?dKSLlT-N5`U3v*1pi0*rhUJAcrf|g{SrORn!q@F z(6H97e?@M$gNJOH)zF0+OEExA-~d(Nc#U3!NYm~yMkvR$W0%P#O#w%tUYM<6#Jb;8 zEm-!uy#OZLYgf=2!00A36C8XB5*u=66i%$@xP51lx(Bp00nyZoARA z&EJY*ItoqRbTVz4+94hjq7s%0Y=#OaqX7sUHVjNkj$z3uVM`}_MRc1xpVi@5)j ze6E*9?%kD7*>9)5U1cZVLHk>~w&OR_Vb*7Ey87gNd3~_{5mlIpD!BUGgpBF*2^Zq; z7i@u^u9N49{2$@xUeSa?cO37*V}|o2r-o8xEU#hs#c-+Dh#We1$o0kUbo;VcQFFu) zD~c7xg;b%&izMQ$At_va%cfo&V%?y9f8O6v2Y^=+to5ViIUc=PmW5XktPbSkD+nCp z;Fs2$i})r4euIZlE{*WIfrYurs=>x6ujeC1|5$|}*tB?00^3~;*|?7?^0QwHEBJ=I zBFn<|a0BZ$l)$rObhr%r;`2a@Kr2A2K^s7ift~?v2fYq@3v>u{9F&D0F2;eTf-VEi z11$or0IddX06hkJ2DBaYI_NFXA<%J97Jf(?2bv1H3^Wh42($vU8nglQ80Z<$cF^mf zw?KzL$3a9l+7hTH9Idg6tM9Mpr$r);HOUnHf}mhiAcVB0 zNFDj)MPpseDi$y974vIKt5|%gS=`hhUM?z*)ZhaMejr#}g%1#;C_qMcS3wYjgjdy8 zp|l2M#J^%8P3FW~NyyZ&YE`6OxRvh4FO2c{WSs({{p?c&6LJD=nc)%;?U;PDZBh(| ztJ4{i_%kwg5`{g|_DO4yiD?XsNmqbq|CC3cAZodTa;ja{0bl z=R7%%o_S1Rv$;p!s&@r?nf=Bz66XfW(%}{G?biS?c^DY8&vZCehWE>0xb%O@Wx2T^+OjEcF4{bw z6Ojs9p2lX(@q(2QV8Db`vJ|NR&#c1ymj}bBLT4HKW+ONdy71*eg z&Y4@s?^;ypLI#ypPX-&GS?OaM3LRSKb4_ z=6N75N*AVhA^&X;{utOiuj5J#n&x>q_i+$af%W??uzCK*JHUbI?s*y)$ss}HApcDs z9P{As03StueO}8mp7c%+eh;`X;GQ=!0Yi>?K20sKdH&76$|1?A&##D${u(QXC?|b} z2j2!<3I2<~!Tx)k>6g3uJ^*ZZRd+^P`=J`Q)G9AJz5mEk+Jp8`|HqR?L z8xKF`c{R82VMqm*cee+3c<^%`{1&izzRqL}!Fv4Tc`q~6T)`qJ|5jl0{Fg_8OQyT$ zwe$j;=cQaAhj3;W`ELX^&zo8AN&gXWC*)BL)JMN3eLS4hJin=2P6>|u2Y}7@ zo(FXd*gS7(o}5CQ{8b+OAaJ*u52%k8VDr4BSIIxeJ%5G|_vZOT*HURJ@Uja3%=3Jn z@}&P9*gU^xBpyP$1Mc}aHv*gIL#^jSstOeKga`iu*gRinR37y6HS{@nsbB78H5&cL z^Wn_?{}!+gl)oLg1^hG%=Fh?u+5`KYqVRQcN)=hizXaGkf9EM+^ZcWv!9NN7nV5nr z1MYcBR|A{pL&bp2^ORl!HqQ(C6xcj}Y6PZm^SmvqswozY;WNnMD(;7T`Dr}h^YPhB znr|e1bKnll z$*Gic)C`Ymamxma_`un{8!KVH2(}x_V-;4u(3oGPzZLgU zFQlOMgR&?pW+< z%Saxcfew0fj-UQeZkuWYj!K=OhUu7{-B$Q0!;xk3)W0$GBxD z%ehybvFP^$Z1dA@A9Cc;u0r~^Y_|#Ea@Q6f>qeS(Ga*7Q=iL)0Tq#3o zfYiNODw+pfnCA|p?F2rl45{oi1FrAmB)@oV>-+dlHC3tJG!I2`1`KEH7YnSRHCz=V zW(aXUi}HYf%&3w^uc^yebII?lw^FAvA135TkVhDK%~TxGGSJd}6p&hZ=*Z8^l)8BG znR&o4;hBomp}J_YF=vRg#$3B_6Zx3x-WO+h_|by7jPiY+nI1XRNiBxk_@16sJ>=0n zZtJwq$m7D?cKT?dQ%QGCYfSch!XA=XJwM7J&U0kYP^vdvL9WNp9$gjkbUC+$?tP9E zVq)j>uFK$~>M1Ia3sd*_L?3d*dQ5LPIR{qx5RhhUlD4c)xp5m!CG$x?%`7>*@*E!? z(h72C(Uu0^SSw$(m#?V>HVUoezEEnk~bO7YX~W-HpEuo_pSu63RL{mwn--ZM87 zY`x?2?BRKH?(d#+-}n4^-}jt*@7$NK`fKKm8a2vLDbL6=h^i|LV+QhFHCD+C!)J^! z%8gQEk| zRkrB$SQFr|q+ef*(mc=&H`g0AtDDZ*@!bplu=?QL-R}+-K2rPhwL60-`!eXWpeSfI zh-sFU8B=9miF_I8)1X`BxpQP*h5S;`T8Wv3K{tV}AwW6}bRlR7s0}m$G!s+~(o?Gh zpGSTRh#j0P&s~DN6m%x&O3+FW)6Jl(K+{0&APlKd4PshsWkvz=IA{*20dzY^rOR;8 z2>J}@VtKLz`PuTAW7rIuCowb5!79)?0;D3)r$A>B$TSZ5xu6-K^`N^!b)YhkO5<^G zK4_6T@i*ilt?r%jSgNU3l6kmVgOhMPSK<}O=Yv`#W_AXsUg8*X>UAOL3VDv%jiB2! z%)<*Lo+$Ghke>&dBC*P#^2X^B+=2Xypyd)zmpOGgAdgi>oxMu}n3HiWXpO|oE(g_0 ze6`G(T_=x6%lvaP|ANf*3}$bqh<#)j*W)-(!|HG;4lV*M1o=SOl3$*r4zhpL8TNlL zQ8{BlxJj~pxR$A&o7@} ze%k52QDZtw=gr9{FX|Zemo`P)RsH7JFtP8nDJJ%pZQ$H#?bD<;kvZOomh!?YvLe;CvZVxpcZo#x!qw?sk8-f$>% zfOf@nx0M+;{rbsSzkYJc-dpZJ@w4yVxBQvE9GRWI;K0sQ!RKCCS6uUt&tLiLO&_8xEh&jriwUiF8`_dL)aTXE0i(T8W3zc%gtmHP`Un$otxMON_uMvf-zy~t z|LJG{_a}vaez!Znv1!b0FI0Ct-E>_~&FjJ2zI^EY&;R(Xj>WrcKlAoOo5#2R{oMQR zeC4X8HC2yvz8Sds*orA%K3wp}w@zF7$f~D0yMAQ+tml?c@YzY9{r>V5<6b#3$N$^o zKY0DRU#^X8zU#4F&sR;pBzUOf#+lE|UjJyrjD}eUcD(lBhI?PR=2w$`aDUfTKfZYH z&H2}S@n^H|fA;c6etYbDW8?QOtNH%&m)9;Wl|y7_x6{C7qOa?7;Q=bBOf26zK_SaG zK1s(Y6U$eZC}fon(dcDjIc-%X9}X^406Fo}Go2Hxzv#3~{I8mGW%;smGRx1Svyh2R zzs}XZL$3Z^JxSHJ+PjxbW#ZxQT>bf~t3O{=&I@%}f5?SL(OJsG@+w-gOvL}S zjg{{!?DTBtDioQx7USCsXL~756W;~>>VV^o%kr^k|28<_$+G++$REIlh(3??A4PwA z;gnVRhroRr{%?*i_^a}I^lwNjhbXb>X+TDP@jSG*(pqPU|A_u=x!$?{u`yU{P|jgt zc_H{$e#S6bu^uV(b75KMl*Z&9XqYn$n^RoO$7>_=!y?h_=9vdc72Os&x3QUy&c>40>;CK z#jIMC7aIS9e)zQZgllzCoM+S-7_M*Md zO58LF?OO(bRAjuJHlcq5pLN>*IVfI(rr&cgZd=e^rH`9Rzz_PS`nwPVQ>o3*L$KGj zd4_Q>__IBm(XeXhml}_|AYW}TDgT-=kgxUkLbPX#)}E^{KMOHFO5V57o^5E)6_S4s z$~(03BD9YiDkc9A^sP@DpBJIOK8(*ydHtQP@h}2`JJz&D0?}BoJr)QUfmO|sW}IwX zALL=MrTNPtBd}my;MUL`&Cyt>eNIa-8VyB_1;KT}KqM3ktmZ+qxh>Gxx@Jv0(%cw~ zwYCSE*R-{uxOGjasW}*Ei?>8W!FW@1YhdB^s2GWb*2e->QCwaXZH>1#h5}Ws@mO0N zcwK8td`-v;|7dgM&OlXjWL0aR>JEx%3Pl^+o7-Z|t&yDaZH_dB*5{NXrlOg{Cr9Oz zM~n~Vhl)bOyWC3^Q7FEbMhw}*mFp{799nqV{7x3&eU?g}=?jJ9CFF0+e7iH8-% z=BP=FLu%ul+2zTy97~MGTHCVA6D2v9h824xaV*NUyyiQw9T-8NRhDCkkzY7SOLHU?Y^OAo zSv$IbD3JwTgvH=lAmXm}W-O(YV4YZr4QeFdK5O9|i3_e2n-Ok_9l4Ys3Zgup14;2n zduWv=z`{9TEVkQXK(LnzwzRAaTK-WEAd9V1yD(Qmad#2JHqPejj2?wrrFLPigmM8I zQKl%&rARW&svmYiuJofV6cWptoHhY-FlKP7FskNQI8fEr-rClJyFE<_St<(cvK)vM zZcxm=CW$AlbGedWZDSpsqXh3;Tj_?HFjiXY1b^-0i9=0HSaYrC#T z0_KFRXm+5gJp`6b+Ster1!O@kWwo^g?{>K}CCx7KA}`}URPIaGuYnJ3ZS>;uSH@SZ z3gK=)7>nVr$8AmKZHij$*Lz*u8|Ctil^y#B4}+N5S+CrbAHq#!C>Eub*=NKF4-K^$ zi5by3dz>MMv6>zGjMw34Z42Rs4iC5jRrdbDIp=u`;jprvsM${2DaeW67Arza^UC&M z``y@6hT5ZiW``+YfjX~FdzfNdsi7-muP|XQ*h&|n*y5S0H@@nLsXe#q8LH=*RgC1r z*x?&BRRKej!=0MqD#gktw)z8L&Wh}|5X~yh5!Uejgjg}AfoI$FsB#wPY}cchx-3YY z&WZgfW>QARGa$92Q+0$utA==*D9XJkzfw|R#QKBQtdgzy#54Mw$uc)#0lc^|MrZuP2^%{{nRWhF#9tZyZ~ONpyq79MUwxqH#m#sNm}hL@yE7!V zwMLc`xBcDYc#AgL*d)vM7;YFdk+;#V{Ua zemUMpGRF(yZ!^b>$ETU&o%S=#uf+RE=2H#hhs-~X_vOqh4C6)ScvsoS9ICvFd6i-8 zWsZ5MPrhE4IG&&494_nZH&Dggd?KArcOQt2Nj-qGsqbJ~QcdX7(q;Sl)6ZdYjPzDa zfk^4CeCr$L@zFtCmflK@3A6a;d0_$ zfiWmX7|k+{b_mR(@GRmsfzfFrTus~{Fsp{=6E75a2Ju4TYJquacqwtEz<4oigd2!` z0#_46Y(;tt|Lfhj7yiFiQZ#l*eDeF9T-_+jF00xu`t zLcB%b2I8lQdj)PH-bUOZFq;;Bfw)cJ7UDkQ27%es@LuAD0>_94h^qx=)5C{}D+S&_ zJV@*lxPv%FTqJN8@er{g@FwE-h==~0{r?&5n3H&f|3Gp_8 zA0_q?ZxMJ4aXE3Xz~3gWB<>LSY2sPLZ2~_-Tus~{@HXQ4#0v%fA@M@uYJp!MUP@dk z@QcI^#6E%hh{ME10`DSjBQ^x)(1zC&4}HM??P4I}6P%8o=Sp$hv$+I+uQ;^x!_kR1M_oM>_4RD$ z)rr1QNl`8RP=YnAYpxz@e`9xo>_;Vb6)n4cML+F11-pm%=|X(5xtV$mb3VsRyvL)y z*ti~XE?Hcb9!TseUbdp&EG_HrWvZ|0OTL~sJ}bH6MAd=R>!{z^|0npDWc)odUXHk76y@*Wa_w=y?%dPxvQPUSU?}_xJY1 zrqEvr+(8ZLU)2lj@avt5lOwVGA-t*J=hQD6sV)R%%Ac^ky0~ALUtO5lp6VhSJN$Fq zzfY>YOEKG+kJL#hcxV4#u)JWRIpdpO#gLgh2KhH}gnyr-XXrjK;p_h2b*J(77fJuX zo&>8g?MWQB4sbMR9}U?@WWls2al$&l5g9V=Nzkblu=<3B=;OD`%h>vwhc#h36RXjSbIN3j+z?b!GWp7b9v zi=de+j1>FaP0Tm|w2Vpy+mymveS=3W|gk55=&THx)IYNxEiE=j zi)ygng-zXkN&l|cA$Fkvrjd-56`S!Abg=}3Qfm4S;!J@sMBqYHgRK=|pfCWmy7WJA zD#+Hq%REC^F4!(weymH`TV3j3|H6K}27^o-FEbOIPgE>2{lyl`B4m(VNR}^|{sI_1 zS*PB@f|1x&2LF;g>5NZZ>H)!Tv*O1F{8jwEm6c!OczJTgd#S4h)6at`MkM}0a<_Yk zPh=h9@#YG6HsPDZ`1(&k4b+@-aCgUkZ{nm$%@!I`po$+9BbRZ(a*dnt+rmF_Z1x>p z1a-0e)qLqqp(2U*IkcPLo1hv{y1z;-&dyK^F;A9WXSVxgq1J_>(Z#TDP7iC;locj_ zWtud%o#~6ADb)LdwCoP;L-ARD?CZzQ6zhWeqxGi~v%&t{wgfxKshIZE_WxpMc3}Go zg*J<9E2UKlZ5KvY0>z$XiGKk@lEy-ENlzm6W;zWe$lsG+hISdL#*@GaE;KLD(i6L; zF1tN|h01@V$2|NWSO6Vk1;ga-30*%xT~T~Y6&LoHZ{e7|Q(bzn3(Qe}&xEc{tG?FV z#jxtG)i|9L9xb^;%sC|%qIJV1)+&kbXcFHaS>lD+C5{ym2hp(P4%(LJ#NwTYFr)RWhy3Kd^_3b9b((mZPq zBb$CNn@$OZV93SU-An^*Lz|NCS#5$HeY6a*Ns_Ypq4Gd!N`N6~rc)r-@C@wU~-c z=q@I3a?j?bm*Gb+S(t53SZe$7c%BRhBjYt*V+AB;`mb93&wt|xNaQVrdbdCDR1@) z#5|NpJKN(QgeHnx)^BpiYmZ>rKFzEj>^=~mSk;#?Bw`;m7K$!z0(+l<4x{3g{?e-l zV1EPLm!AtehRj0DFzy6PWnF6r{qn+xWL>rE~+z%AtuntNOb3#r7%`h3-m zIA3+C+eQ7xjQV+RjWoaT|Dyi%jQSH#QU61f!T)E}uRA^>f3<$?5tr@10C#NCq1i+2 ztY@a`m$ipn>uW+#Pz>K)z1Fk;4!#$ zeKD{90~AJFe_`hJ$=SI5DNWACO!$(si!@%+zUxw75&RMsKVFSlnuES&_g~omiTZUJ z^(UU9{zanxiirBr zjQU$goG+|@qW+wW`qNV*&o6BFz0~RAqVc#0PYbZzrPlrtOZ`joks$Yo*7C(ClFnT{ z`!5#R($rq`ptJw~;U$sfT=={N1|zihNhMwG(e>w<@c-h<&A8ICAKsIuo;N4g)e-&*Y2Z*4%wGTe%L zza_?}3|gLg8XfBFe-|X0WxQaIT>OPGie(?`JC^m-e8ImK z{MC}dy*}6c+Ke@ydfYqWnjbqeqdT}$;C7pP7j7|OB&*T1?lky{Wnb(J)XJ|6?p4w1 zW7}~*E9~R@7^Ker=inBFstApE2hY;8&5wB6u5~W8R$ROe7mJ-viPbqci?d*$&@k>= z9^{5N`xfT%M0(Vu1AjiylW01ePG2%$DJ6Tv=Rc`uj!?mmVCr9mX8yt)pM?70 zhEoap2W!{(>alI=@fx3R;Qi5>H#p|)ct33>ity|MFK%L!dYuK-EHT>S5u<#;f*WyY|LD40 zK)54(MLJDfhp$Md>0gmf<5#59)K{d_oUcfyExf)={J=!~aHVl&AOm=# zY>)MW;P%kkcqkeR$VO>DL=nGYvV_TRUF8p%*mjI|TF-er3dG+%Fz4?hxOL*U<@m{g z_(nY+IiGL6`(e7Z1pq%`FuKNDv7C;KwPNY?;yV0fLHxD?c5Hlr-$Y=MF*boIw^I0d zf{2q7#)}vp&qt2=G<+cFu=rgC9*?ya;5?eh&-M-M_*;wdq5+SSTiLdclNftSrI~o= zHxIM~vx?Gj!3*> zWxTni>C??khCtz9G;CBf-5uelcp{IrTP5lTkfNFd0hG0eT3F9IXlscX72=1775v)T zs1RRvSG2c^A0t(S!uTME9{^W0;)CNT1X$VXMlb@C;F{(}NNdG~_){UcSy$p$Ot=Ui zdxs*z?9?=#GRN(faTsH= zdJye~$Fv<%HI6Bl=T!YB9G@=F(e_9_t(^4=Kx;s%UKn*qv|*OBf2!U(9J8(HrtlT? z7nL|xiS?M)f>b>p>`4#@Kql5BZ2+lyj7vvakDED_#9j;F9+0ZX_!%VJpR@laXDnEkyqJCtqI|Y*0QCk?FPk3x3gwim%2-dIHl2Gr97j=o@buUM?4dKo`^Gb`|b2x)YIb)JqWDFZ+VxDWMb>j z(-;!Zbm1=n>+xs453I*8Iti@DZ(+O`mB_Eng?nB2d0;)>O)*qRkN2}2SdRzvEU+F= z=R;sUep9W~MYe(R*J;=X-0i~O1lHr%yv=efVv~_EzKkC#tH)P*0Jsmv%W-Ge>a~-_GGC`Z)Mi>4DF@BTUfQ;=u=_)_l zGFkijsla-CpSY|1As7B<;A)J=6v@931Ea?S3R^C~=Klb&9^dCMa0B{-E{gW~Gy|f( z%yHpnU_D;Z^T31EXoI{y|4ban#OtpB9zy$6JgAw#di<-exavRb!as50LoWP|3zxu! z>G7>1z`fAlOVJjN|4v{%e%G0BaRZt@wbA9xhRwl_S^vkD3lu$Ke+~c-YW1fV!Jkw+ z@xC?ztHk=>CBDIlkCYFWsmC9iV7X9n3F}|w!Z*3_T3|gsRzI*Ff31*AWa44D3*QQ? z$8-82upVD+G;X@MUNbRX)OcV$e%C7Al*vTaNnkym)&W=fN#Mb0j(y*NB|wi)^%$@Z z`Zp82INonqON5X>{)N^OVdE(-%tvB+{Iq`r_Fa$rR>?2rsy_w~163mb3yGIoXV~9M zf%`Onx6W1nVHe&8?9=q&EN#gm|0{s?cw!q}<&OdD@$pUq>+!f2lw{7wB4Cxsf1L~8 z58Qz9R{r1*z^J86}V0N zzT5fI${7_5Y?e_PvF2RrnJbto1goYZ=l9EwY?Rqi zD8M7?lz3>B8ftr7lz2yh964I+vJ9G+Rt&eg9EE~a-8t2F_O`FF!yK}A&|#(uF~2$Kmp##z2hr|etym*YoZGBs$B3U!J5a@*iHrt1c11sE?Y7j9Tb#?i=$O`U z(G%|vOyqnBr%jD=wkyLuiW)`HJL|sOiN5p6bkOx|AqOGK)l(2BoSq(r#mnSK&Kw;p z7OA$?&Z<@na-5T4v(-_>CmU`_BFaoogz0g7gc5qa1yc*67&upqP7m{8?_$7L_)7U; z;uLG1ZrQ`OI2qb6qGILNwlj7mUZcNdhSuXU={P4&ns6MBIyi;gl{n``R3Z;^VC$i_ z6HtMb<+Q7nz={Fsh<2L9M`_M^53L!dxmg!zM=(Qo=0tF|VGuLy$g*!iGoQqG>8w4uO3US0(Nv{>sbsumA6QVS+=zHrXnZ**SvDBCNa?+SBnV1y`ANWHy4hsEuuJ#P-EY(2 zg)wopbzL))V!hUm(=x@jwpAxBwzVz22BT7E>@8P%8SQjzN};YT)p$!8tjP9x&e;=A zR@&>G*^fJO5A*Ih&v)MQzURE>J?Hy!&dXiRYgd((l^H5k7!?N5=#_?1kKCFgYw8WB zG0B)`%rt66z2avcyh_p}0*4{$#j`p*2RR{d9%yo*z8v{ZwAqO|(oca&tgkH4FOVy8 zp-fVB>yKLjzz-z7eGO_WKsT*xHNLbUwEe1mQ?AWE9h^ER_2|_3*B$%#$56K%bQ$Ox z&=e5URM0;i z-1JJPx18pKpfbVJ6C<-p`(W{y=cWB9~k}p;kT#n=xn-w*TE}~we0)#t1onKdGeNDdY`y$ z&Sy?+?R;(BquIw^ToS$O(@!lr`SSCDo=^N~{jbKtH$VK!>78d=`?r3lZN?Q(g#UfP zPoA8!`qa?dAA6%ex2z@p-L}zbu{+*d)G=rE{r}p3=eqCQI_dChcWjyUjpM`}PhkTlq z_$h2iqZ*!$&CCG|6{3C_Hj^>*SMg7Q{60bdq*Ke*_)5Z!wsW9L78Oqrih2 z-T{7(Q?6C=_oIIfOJ7f&5WT{#P)c2Kbdd11Jn?`W}G%K282+2=0Ua`33#`Q0#$y?kr%=gLtV33@iJ5 z+aj^3FKPJ`md|JSLeY?A__~pys;k$}qCXtE(=>cH_xLuL+d@gpOf-i5$)uSyZua;1 zeX+zg-}aD|4EaKlc-R*;V-YhD^82<&y3Jn8CqXdk2NY7vd5i2pe|vHH+RPp5x*ryv?^kGL$NJ z?Xk*+X4++=J;FEIIGvE~U9q9XrjBpg(7dAM)>SsS`9>*zU1>Wnzwq^4z#k6Bx{Qd- zZ1`)Ucq_F{k@_sMO@aO)X`2$f-h6e|j=1Tovr~uo1J4EpvA7v6t;a@E(TG1@Vwt6v zXhyo?CH`wE6zj6Wr5$*8!YuJuZdW*#G>vemv&)@~xtAC|GvK%UIJxLdCgqt19z_Gj zO>5VzZ1gR5*SW7BFMD_tQZ7#4WzI7H@utJxe>?{*H(tPDj5v=$Ka#UUI7zB7-Y7hC zghDvUDL4L9V7LcoR5*$(;;H>OWi=4hj>{Uc2{2hTouGM~@i`-(Lw_s@8m zyAkSg#~^dd)|W=|Jh(IRd)Y^({9Yc!23dS_6wUH`IglW$-#jERPuzoi_~x*{JZTT| z=glF3aj0bkoy2m{LVje;B0yN zt+E@(lFotevvqp7EF;+RUr3Wfwz+XE@w*q(6knEp-m&#l?IW~r&W#8CBX8i$IDMif z``|qA!@QSe)2CS)wk{qJ&oVWx{Gs&oHCx+9va?(xgG^|jZFaP08>&VI2dry2UjiE= zvL6aJEG^X6y`oywj|}t___M9G8Atm>?De#dbf1&IX#U5o z5~C0kFtC3v=Ru8sqCL(#-f?-&j)M);;M9id1`Vs^Ju{=NX*hFSscC(tvhC#w_|l^K zi;A$(7VOj8SGCnlXg{e)-sMI3BW;xpdi&~$nEv$o`}utT$irA!@TY^7u9q>E+)+65 zy~CO3tVy(1d4`^Z8GWK#~+k54K&)6-|mGM?0wgAGn<&K%0NpU$Svpih|-=+x8K@G0hRV{W<- zbr5$eay&s)PFEFp#ae4Vmf!t2nq-@gWuX9?cAXIh6K+p?aT95-&Ao~a_m6zO z8qy(*lZO541VqX$WPE=Bzbo53FZa0M_e*|AU>_XWW+$>~+2&cusvuUAfZWJc3XMBB~>wm3i|DU*-m8xqr)yLme!}!A`VjomL!e3s8 zbj&|m3R8%I?;USZygzKrJtg?J{SAI4TI7(A_r)&JUCUG?e?FU! z-2+d+Yu(7KO=7Gqz=kpHgMFfe$5@#ue@7|)^7DvYTO)D7wZeHQd@ps$0z4|)-F z1jKKin;ILJIp;N*ogshJS?{iQ->`7$d|5z%LUKpM@^>P)5;6~}QZ#0n?rqVOyE7FE z2Ns3`hCo4oGHAF1JECYQb1NZhddx&J6pKy(KGY@5F!^O69<~g(xFK^}xY{z@;-1WH z27TQLf5bH0T~;iSgkYI%?}7j{_D4cp5FA4T{J4b_@tx|%XDS-SA`ufOi61uMdeFeM zi+TM8a*_+A68(e;<`X```KRBI9>9dEdgdg4hMdCOl8=5xdh9%WOHohXA|L&YGz=%B zAJR`Ki+FwjQ|Lr zvZ4+Bn&bpl@|bfAj(`*&*8z#^gY_Jr;_E?~edYQRcc$=3>Qza}y#o&vpNBl4A;pB8 ze59Qq#WxBbQcws-1(HK%#@)yjAJ;vJU&AUXz4ze(`Dm8_cu1;_ysEq#W%6-O7hVk^#kU_16d(7Hd%(v!l~nmTJfME|k1+xFf$w~F zIf#17Q*%!~eLh%6ngOCLl^z4%Aq9|=hlzQ)D9N8E<{Cx^i~@H+9G&bdeStoz%bT_k z>y1hZNy$@K&$%Zs$*4WK_9d2@xyB`y8n~7vmIba^iREl@ZAvU1mTORA$;h=Pv9uu9 zl*Akb5(kG=A>LAQjY!NDC)a|+;;koqUShueq;E@%fCeP`F;j(z;)1V^W4Vgxm$F_O zOuc_9#M@5(9WCqm)|2l^iE9L=-$=~Jlyfm76(Yh%JQ6<@c$@0;P>Gn5Vk}1_+pxY3 z#Zl+En3`|OD)C#5-yas?mw@#cmzhwY$B=xE3gM8nBx6!e0qZeJn=#iNTFl7PzxzLwCDE&+uscw2d1To{~LG=SjFgUfs5!dMc-2k3j9vc^F{boU_EANIb4c+8WUrr zRswq=c=iH2fSmoHMhfg7~`-_9+fus>D9%ALSot={NL zSV;?EN$xJAM6phgRMN{1c@E0s?}i3-*6A@KIB3>!NmWvKX$K*1hl+1(?7aN$Qo%nL zCKgDAw%Ks=p{}QGxh$O+n1>0mFG65K90@`I|KCL7=$D>$hCZlE=i<1|3l_XN@%~Uo zl9qJik>058Tj3*i1iY#BWJi3!!~xi_8At^amJ(dfwva4ktI~(BOx$=d)wYM8+81>k zvEhzZS-udhfnX3`vFfjUaf_=zDCtrZ7rJs_w&^&(Gut2V_knMNQU~sqK3L)Wrm`XC zQ~8|@advVH#UFuKmj4G4km9S_Hpec6mgunxG7ic%jUU)f?f6d#$~Wu?l(ZoxMRnKC zfH(EskC(7~fr*%ulJ3OkS^8Kr7cLz7!hFSGNcvZdTtWJBDa8NSU|KbY=z@*^%SQhz oL7H^pf5JL9Rz@<}FiiceXTzMT)ixfFEdRe*Ne41P2cwez3P_BamjD0& literal 34500 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 Y(YyNCC~oMPZUzm>Tf5aN;*R(K4P--3mH+?% diff --git a/src/net/java/sip/communicator/impl/argdelegation/ArgDelegationActivator.java b/src/net/java/sip/communicator/impl/argdelegation/ArgDelegationActivator.java index 398ca4174..0670937c1 100644 --- a/src/net/java/sip/communicator/impl/argdelegation/ArgDelegationActivator.java +++ b/src/net/java/sip/communicator/impl/argdelegation/ArgDelegationActivator.java @@ -6,16 +6,17 @@ */ package net.java.sip.communicator.impl.argdelegation; +import java.lang.reflect.*; + import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.launchutils.*; +import org.jitsi.util.*; import org.osgi.framework.*; import com.apple.eawt.*; -import java.lang.reflect.*; - /** * Activates the ArgDelegationService and registers a URI delegation * peer with the util package arg manager so that we would be notified when the diff --git a/src/net/java/sip/communicator/impl/argdelegation/argdelegation.manifest.mf b/src/net/java/sip/communicator/impl/argdelegation/argdelegation.manifest.mf index 31e3155c9..bc6ee145c 100644 --- a/src/net/java/sip/communicator/impl/argdelegation/argdelegation.manifest.mf +++ b/src/net/java/sip/communicator/impl/argdelegation/argdelegation.manifest.mf @@ -8,7 +8,8 @@ Import-Package: org.osgi.framework, com.apple.eawt, net.java.sip.communicator.util, net.java.sip.communicator.util.launchutils, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, + org.jitsi.util, net.java.sip.communicator.service.argdelegation, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, diff --git a/src/net/java/sip/communicator/impl/browserlauncher/BrowserLauncherImpl.java b/src/net/java/sip/communicator/impl/browserlauncher/BrowserLauncherImpl.java index af846af22..c4ad992a3 100644 --- a/src/net/java/sip/communicator/impl/browserlauncher/BrowserLauncherImpl.java +++ b/src/net/java/sip/communicator/impl/browserlauncher/BrowserLauncherImpl.java @@ -7,7 +7,9 @@ package net.java.sip.communicator.impl.browserlauncher; import net.java.sip.communicator.service.browserlauncher.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; + +import org.jitsi.util.*; import com.apple.eio.*; diff --git a/src/net/java/sip/communicator/impl/browserlauncher/browserlauncher.manifest.mf b/src/net/java/sip/communicator/impl/browserlauncher/browserlauncher.manifest.mf index 55a9449a2..0b225ba08 100644 --- a/src/net/java/sip/communicator/impl/browserlauncher/browserlauncher.manifest.mf +++ b/src/net/java/sip/communicator/impl/browserlauncher/browserlauncher.manifest.mf @@ -6,6 +6,7 @@ Bundle-Version: 0.0.1 System-Bundle: yes Export-Package: net.java.sip.communicator.service.browserlauncher Import-Package: org.osgi.framework, + org.jitsi.util, net.java.sip.communicator.util, net.java.sip.communicator.service.browserlauncher, com.apple.eio diff --git a/src/net/java/sip/communicator/impl/callhistory/CallHistoryActivator.java b/src/net/java/sip/communicator/impl/callhistory/CallHistoryActivator.java index 7c7cd7a35..c424df5a5 100644 --- a/src/net/java/sip/communicator/impl/callhistory/CallHistoryActivator.java +++ b/src/net/java/sip/communicator/impl/callhistory/CallHistoryActivator.java @@ -8,14 +8,14 @@ import java.util.*; -import org.osgi.framework.*; - +import net.java.sip.communicator.service.callhistory.*; +import net.java.sip.communicator.service.contactsource.*; import net.java.sip.communicator.service.history.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; -import net.java.sip.communicator.service.callhistory.*; -import net.java.sip.communicator.service.contactsource.*; + +import org.jitsi.service.resources.*; +import org.osgi.framework.*; /** * Activates the CallHistoryService. diff --git a/src/net/java/sip/communicator/impl/callhistory/callhistory.manifest.mf b/src/net/java/sip/communicator/impl/callhistory/callhistory.manifest.mf index 6aab8668d..bb33b1bdc 100644 --- a/src/net/java/sip/communicator/impl/callhistory/callhistory.manifest.mf +++ b/src/net/java/sip/communicator/impl/callhistory/callhistory.manifest.mf @@ -5,7 +5,7 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.fileaccess, + org.jitsi.service.fileaccess, net.java.sip.communicator.service.history, net.java.sip.communicator.service.history.event, net.java.sip.communicator.service.contactlist, @@ -15,7 +15,7 @@ Import-Package: org.osgi.framework, net.java.sip.communicator.service.protocol.icqconstants, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.contactsource, - net.java.sip.communicator.service.resources + org.jitsi.service.resources, net.java.sip.communicator.service.resources Export-Package: net.java.sip.communicator.service.callhistory, net.java.sip.communicator.service.callhistory.event Metadata-Location: net.java.sip.communicator.impl.msghistory, diff --git a/src/net/java/sip/communicator/impl/certificate/CertificateServiceImpl.java b/src/net/java/sip/communicator/impl/certificate/CertificateServiceImpl.java index 5068a72cd..5090f2691 100644 --- a/src/net/java/sip/communicator/impl/certificate/CertificateServiceImpl.java +++ b/src/net/java/sip/communicator/impl/certificate/CertificateServiceImpl.java @@ -11,7 +11,7 @@ import java.lang.reflect.*; import java.net.*; import java.security.*; -import java.security.KeyStore.*; +import java.security.KeyStore.Builder; import java.security.cert.*; import java.security.cert.Certificate; import java.util.*; @@ -20,18 +20,19 @@ import javax.security.auth.callback.*; import javax.swing.*; -import org.bouncycastle.asn1.*; -import org.bouncycastle.asn1.x509.*; -import org.bouncycastle.asn1.x509.X509Extension; - import net.java.sip.communicator.service.certificate.*; -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.service.credentialsstorage.*; import net.java.sip.communicator.service.httputil.*; -import net.java.sip.communicator.service.resources.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; import net.java.sip.communicator.util.swing.*; +import org.bouncycastle.asn1.*; +import org.bouncycastle.asn1.x509.*; +import org.bouncycastle.asn1.x509.X509Extension; +import org.jitsi.service.configuration.*; +import org.jitsi.service.resources.*; +import org.jitsi.util.*; + /** * Implementation of the CertificateService. It asks the user to trust a * certificate when the automatic verification fails. diff --git a/src/net/java/sip/communicator/impl/certificate/CertificateVerificationActivator.java b/src/net/java/sip/communicator/impl/certificate/CertificateVerificationActivator.java index 2c5bffaa9..e1a41bc0b 100644 --- a/src/net/java/sip/communicator/impl/certificate/CertificateVerificationActivator.java +++ b/src/net/java/sip/communicator/impl/certificate/CertificateVerificationActivator.java @@ -7,11 +7,11 @@ package net.java.sip.communicator.impl.certificate; import net.java.sip.communicator.service.certificate.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.credentialsstorage.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/certificate/VerifyCertificateDialog.java b/src/net/java/sip/communicator/impl/certificate/VerifyCertificateDialog.java index 0e55dfd13..4e855a220 100644 --- a/src/net/java/sip/communicator/impl/certificate/VerifyCertificateDialog.java +++ b/src/net/java/sip/communicator/impl/certificate/VerifyCertificateDialog.java @@ -12,9 +12,10 @@ import javax.swing.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; + /** * Dialog that is shown to the user when a certificate verification failed. */ diff --git a/src/net/java/sip/communicator/impl/certificate/certificate.manifest.mf b/src/net/java/sip/communicator/impl/certificate/certificate.manifest.mf index 8699c8d1a..0c77bbe6c 100644 --- a/src/net/java/sip/communicator/impl/certificate/certificate.manifest.mf +++ b/src/net/java/sip/communicator/impl/certificate/certificate.manifest.mf @@ -8,10 +8,11 @@ Export-Package: net.java.sip.communicator.service.certificate Import-Package: org.osgi.framework, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, + org.jitsi.util, net.java.sip.communicator.service.credentialsstorage, net.java.sip.communicator.service.httputil, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, javax.net.ssl, javax.security.auth.callback, javax.security.auth.x500, diff --git a/src/net/java/sip/communicator/impl/configuration/ChangeEventDispatcher.java b/src/net/java/sip/communicator/impl/configuration/ChangeEventDispatcher.java index f6b204f34..530f36678 100644 --- a/src/net/java/sip/communicator/impl/configuration/ChangeEventDispatcher.java +++ b/src/net/java/sip/communicator/impl/configuration/ChangeEventDispatcher.java @@ -9,7 +9,7 @@ import java.util.*; import java.beans.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; /** * This is a utility class that can be used by objects that support constrained diff --git a/src/net/java/sip/communicator/impl/configuration/ConfigurationActivator.java b/src/net/java/sip/communicator/impl/configuration/ConfigurationActivator.java index 68b28b36e..86a28d754 100644 --- a/src/net/java/sip/communicator/impl/configuration/ConfigurationActivator.java +++ b/src/net/java/sip/communicator/impl/configuration/ConfigurationActivator.java @@ -8,7 +8,7 @@ import org.osgi.framework.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.util.*; /** diff --git a/src/net/java/sip/communicator/impl/configuration/ConfigurationServiceImpl.java b/src/net/java/sip/communicator/impl/configuration/ConfigurationServiceImpl.java index 206ba7757..982ff230f 100644 --- a/src/net/java/sip/communicator/impl/configuration/ConfigurationServiceImpl.java +++ b/src/net/java/sip/communicator/impl/configuration/ConfigurationServiceImpl.java @@ -11,11 +11,11 @@ import java.util.*; import net.java.sip.communicator.impl.configuration.xml.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.fileaccess.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.xml.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.fileaccess.*; import org.osgi.framework.*; /** @@ -556,18 +556,13 @@ void start(BundleContext bc) { logger.error("Failed to load the configuration file", ex); } - catch (XMLException ex) - { - logger.error("Failed to parse the configuration file", ex); - } } /* * Implements ConfigurationService#reloadConfiguration(). */ public void reloadConfiguration() - throws IOException, - XMLException + throws IOException { this.configurationFile = null; @@ -591,7 +586,17 @@ public void reloadConfiguration() } } - store.reloadConfiguration(file); + try + { + store.reloadConfiguration(file); + } + catch (XMLException xmle) + { + IOException ioe = new IOException(); + + ioe.initCause(xmle); + throw ioe; + } } /* diff --git a/src/net/java/sip/communicator/impl/configuration/configuration.manifest.mf b/src/net/java/sip/communicator/impl/configuration/configuration.manifest.mf index 542af3d3d..0e521dc10 100644 --- a/src/net/java/sip/communicator/impl/configuration/configuration.manifest.mf +++ b/src/net/java/sip/communicator/impl/configuration/configuration.manifest.mf @@ -13,5 +13,5 @@ Import-Package: org.osgi.framework, javax.xml.parsers, net.java.sip.communicator.util, net.java.sip.communicator.util.xml, - net.java.sip.communicator.service.fileaccess -Export-Package: net.java.sip.communicator.service.configuration + org.jitsi.service.configuration, + org.jitsi.service.fileaccess diff --git a/src/net/java/sip/communicator/impl/contactlist/ContactlistActivator.java b/src/net/java/sip/communicator/impl/contactlist/ContactlistActivator.java index 4a8b23398..70fefaa5d 100644 --- a/src/net/java/sip/communicator/impl/contactlist/ContactlistActivator.java +++ b/src/net/java/sip/communicator/impl/contactlist/ContactlistActivator.java @@ -7,10 +7,10 @@ package net.java.sip.communicator.impl.contactlist; import net.java.sip.communicator.service.contactlist.*; -import net.java.sip.communicator.service.fileaccess.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.fileaccess.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/contactlist/MclStorageManager.java b/src/net/java/sip/communicator/impl/contactlist/MclStorageManager.java index 4576725e3..44190983d 100644 --- a/src/net/java/sip/communicator/impl/contactlist/MclStorageManager.java +++ b/src/net/java/sip/communicator/impl/contactlist/MclStorageManager.java @@ -11,18 +11,18 @@ import javax.xml.parsers.*; -import org.osgi.framework.*; -import org.w3c.dom.*; - -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.service.contactlist.*; import net.java.sip.communicator.service.contactlist.event.*; -import net.java.sip.communicator.service.fileaccess.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.xml.*; import net.java.sip.communicator.util.xml.XMLUtils; +import org.jitsi.service.configuration.*; +import org.jitsi.service.fileaccess.*; +import org.osgi.framework.*; +import org.w3c.dom.*; + /** * The class handles read / write operations over the file where a persistent * copy of the meta contact list is stored. diff --git a/src/net/java/sip/communicator/impl/contactlist/MetaContactImpl.java b/src/net/java/sip/communicator/impl/contactlist/MetaContactImpl.java index 6f27d9a09..1397b36e1 100644 --- a/src/net/java/sip/communicator/impl/contactlist/MetaContactImpl.java +++ b/src/net/java/sip/communicator/impl/contactlist/MetaContactImpl.java @@ -11,10 +11,11 @@ import net.java.sip.communicator.service.contactlist.*; import net.java.sip.communicator.service.contactlist.event.*; -import net.java.sip.communicator.service.fileaccess.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.fileaccess.*; + /** * A default implementation of the MetaContact interface. * diff --git a/src/net/java/sip/communicator/impl/contactlist/meta.cl.manifest.mf b/src/net/java/sip/communicator/impl/contactlist/meta.cl.manifest.mf index 5d655e4a8..fb997832f 100644 --- a/src/net/java/sip/communicator/impl/contactlist/meta.cl.manifest.mf +++ b/src/net/java/sip/communicator/impl/contactlist/meta.cl.manifest.mf @@ -5,8 +5,8 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.fileaccess, - net.java.sip.communicator.service.configuration, + org.jitsi.service.fileaccess, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, net.java.sip.communicator.service.protocol, diff --git a/src/net/java/sip/communicator/impl/credentialsstorage/CredentialsStorageServiceImpl.java b/src/net/java/sip/communicator/impl/credentialsstorage/CredentialsStorageServiceImpl.java index 83abd01f1..6329e97bf 100644 --- a/src/net/java/sip/communicator/impl/credentialsstorage/CredentialsStorageServiceImpl.java +++ b/src/net/java/sip/communicator/impl/credentialsstorage/CredentialsStorageServiceImpl.java @@ -8,7 +8,7 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.credentialsstorage.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; diff --git a/src/net/java/sip/communicator/impl/credentialsstorage/credentialsstorage.manifest.mf b/src/net/java/sip/communicator/impl/credentialsstorage/credentialsstorage.manifest.mf index 9d7cb699e..f4b5eb012 100644 --- a/src/net/java/sip/communicator/impl/credentialsstorage/credentialsstorage.manifest.mf +++ b/src/net/java/sip/communicator/impl/credentialsstorage/credentialsstorage.manifest.mf @@ -5,7 +5,7 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.crypto, diff --git a/src/net/java/sip/communicator/impl/fileaccess/FailSafeTransactionImpl.java b/src/net/java/sip/communicator/impl/fileaccess/FailSafeTransactionImpl.java index b612feb91..2b4c895e5 100644 --- a/src/net/java/sip/communicator/impl/fileaccess/FailSafeTransactionImpl.java +++ b/src/net/java/sip/communicator/impl/fileaccess/FailSafeTransactionImpl.java @@ -8,7 +8,8 @@ package net.java.sip.communicator.impl.fileaccess; import java.io.*; -import net.java.sip.communicator.service.fileaccess.*; + +import org.jitsi.service.fileaccess.*; /** * A failsafe transaction class. By failsafe we mean here that the file diff --git a/src/net/java/sip/communicator/impl/fileaccess/FileAccessActivator.java b/src/net/java/sip/communicator/impl/fileaccess/FileAccessActivator.java index 9f832ac1f..8bdaf495d 100644 --- a/src/net/java/sip/communicator/impl/fileaccess/FileAccessActivator.java +++ b/src/net/java/sip/communicator/impl/fileaccess/FileAccessActivator.java @@ -6,10 +6,9 @@ */ package net.java.sip.communicator.impl.fileaccess; +import org.jitsi.service.fileaccess.*; import org.osgi.framework.*; -import net.java.sip.communicator.service.fileaccess.*; - /** * Invoke "Service Binder" to parse the service XML and register all services. * diff --git a/src/net/java/sip/communicator/impl/fileaccess/FileAccessServiceImpl.java b/src/net/java/sip/communicator/impl/fileaccess/FileAccessServiceImpl.java index c3d644c70..677e15b00 100644 --- a/src/net/java/sip/communicator/impl/fileaccess/FileAccessServiceImpl.java +++ b/src/net/java/sip/communicator/impl/fileaccess/FileAccessServiceImpl.java @@ -10,9 +10,11 @@ import javax.swing.filechooser.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.fileaccess.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; + +import org.jitsi.service.configuration.*; +import org.jitsi.service.fileaccess.*; +import org.jitsi.util.*; /** * Default FileAccessService implementation. diff --git a/src/net/java/sip/communicator/impl/fileaccess/fileaccess.manifest.mf b/src/net/java/sip/communicator/impl/fileaccess/fileaccess.manifest.mf index df19ee546..ddcc1159e 100644 --- a/src/net/java/sip/communicator/impl/fileaccess/fileaccess.manifest.mf +++ b/src/net/java/sip/communicator/impl/fileaccess/fileaccess.manifest.mf @@ -14,6 +14,6 @@ Import-Package: org.osgi.framework, javax.swing.filechooser, net.java.sip.communicator.util, net.java.sip.communicator.util.xml, - net.java.sip.communicator.service.fileaccess -Export-Package: net.java.sip.communicator.service.fileaccess + org.jitsi.service.fileaccess, + org.jitsi.util Metadata-Location: /net/java/sip/communicator/impl/fileaccess/fileaccess.metadata.xml diff --git a/src/net/java/sip/communicator/impl/galagonotification/GalagoNotificationActivator.java b/src/net/java/sip/communicator/impl/galagonotification/GalagoNotificationActivator.java index 6904a9c3d..01f4d620b 100644 --- a/src/net/java/sip/communicator/impl/galagonotification/GalagoNotificationActivator.java +++ b/src/net/java/sip/communicator/impl/galagonotification/GalagoNotificationActivator.java @@ -10,6 +10,7 @@ import net.java.sip.communicator.service.systray.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/galagonotification/galagonotification.manifest.mf b/src/net/java/sip/communicator/impl/galagonotification/galagonotification.manifest.mf index e1fe3df35..7c68a9475 100644 --- a/src/net/java/sip/communicator/impl/galagonotification/galagonotification.manifest.mf +++ b/src/net/java/sip/communicator/impl/galagonotification/galagonotification.manifest.mf @@ -6,6 +6,6 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: javax.imageio, net.java.sip.communicator.service.systray, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, org.osgi.framework diff --git a/src/net/java/sip/communicator/impl/globalshortcut/GlobalShortcutServiceImpl.java b/src/net/java/sip/communicator/impl/globalshortcut/GlobalShortcutServiceImpl.java index bb183b8d7..b9336b3fd 100644 --- a/src/net/java/sip/communicator/impl/globalshortcut/GlobalShortcutServiceImpl.java +++ b/src/net/java/sip/communicator/impl/globalshortcut/GlobalShortcutServiceImpl.java @@ -6,14 +6,16 @@ */ package net.java.sip.communicator.impl.globalshortcut; -import java.util.*; -import java.util.List; // disambiguation - import java.awt.*; +import java.util.*; +import java.util.List; import net.java.sip.communicator.service.globalshortcut.*; import net.java.sip.communicator.service.keybindings.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; + +import org.jitsi.util.*; +// disambiguation /** * This global shortcut service permits to register listeners for global diff --git a/src/net/java/sip/communicator/impl/globalshortcut/NativeKeyboardHookDelegate.java b/src/net/java/sip/communicator/impl/globalshortcut/NativeKeyboardHookDelegate.java index 04b135c32..522759989 100644 --- a/src/net/java/sip/communicator/impl/globalshortcut/NativeKeyboardHookDelegate.java +++ b/src/net/java/sip/communicator/impl/globalshortcut/NativeKeyboardHookDelegate.java @@ -41,4 +41,4 @@ public interface NativeKeyboardHookDelegate * @param modifiers modifiers received (ALT or CTRL + letter, ...) */ public void receiveKey(int keycode, int modifiers); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/globalshortcut/globalshortcut.manifest.mf b/src/net/java/sip/communicator/impl/globalshortcut/globalshortcut.manifest.mf index 93aec4c75..16bd25ec9 100644 --- a/src/net/java/sip/communicator/impl/globalshortcut/globalshortcut.manifest.mf +++ b/src/net/java/sip/communicator/impl/globalshortcut/globalshortcut.manifest.mf @@ -5,6 +5,7 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, + org.jitsi.util, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.media, net.java.sip.communicator.service.protocol.event, diff --git a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsActivator.java b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsActivator.java index 243b9f095..0ee56758c 100644 --- a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsActivator.java +++ b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsActivator.java @@ -8,15 +8,15 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.contactsource.*; import net.java.sip.communicator.service.credentialsstorage.*; import net.java.sip.communicator.service.googlecontacts.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsServiceImpl.java b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsServiceImpl.java index 0b1c98d49..509ecd9b7 100644 --- a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsServiceImpl.java +++ b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsServiceImpl.java @@ -11,7 +11,7 @@ import java.util.*; import java.util.regex.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.credentialsstorage.*; import net.java.sip.communicator.service.googlecontacts.*; import net.java.sip.communicator.impl.googlecontacts.configform.*; diff --git a/src/net/java/sip/communicator/impl/googlecontacts/googlecontacts.manifest.mf b/src/net/java/sip/communicator/impl/googlecontacts/googlecontacts.manifest.mf index 9629bf12d..f5f779364 100644 --- a/src/net/java/sip/communicator/impl/googlecontacts/googlecontacts.manifest.mf +++ b/src/net/java/sip/communicator/impl/googlecontacts/googlecontacts.manifest.mf @@ -5,11 +5,11 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.credentialsstorage, net.java.sip.communicator.service.contactsource, net.java.sip.communicator.service.gui, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.service.protocol, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, diff --git a/src/net/java/sip/communicator/impl/growlnotification/GrowlNotificationActivator.java b/src/net/java/sip/communicator/impl/growlnotification/GrowlNotificationActivator.java index 69a1638c9..ac32c63be 100644 --- a/src/net/java/sip/communicator/impl/growlnotification/GrowlNotificationActivator.java +++ b/src/net/java/sip/communicator/impl/growlnotification/GrowlNotificationActivator.java @@ -6,14 +6,14 @@ */ package net.java.sip.communicator.impl.growlnotification; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.service.systray.*; +import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; -import net.java.sip.communicator.util.*; - /** * Activates the GrowlNotificationService * diff --git a/src/net/java/sip/communicator/impl/growlnotification/growlnotification.manifest.mf b/src/net/java/sip/communicator/impl/growlnotification/growlnotification.manifest.mf index 27444f404..08734427f 100644 --- a/src/net/java/sip/communicator/impl/growlnotification/growlnotification.manifest.mf +++ b/src/net/java/sip/communicator/impl/growlnotification/growlnotification.manifest.mf @@ -5,10 +5,10 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.protocol, net.java.sip.communicator.util, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.service.systray, net.java.sip.communicator.service.systray.event, net.java.sip.communicator.util.swing, diff --git a/src/net/java/sip/communicator/impl/gui/GuiActivator.java b/src/net/java/sip/communicator/impl/gui/GuiActivator.java index 66af4a650..302107338 100644 --- a/src/net/java/sip/communicator/impl/gui/GuiActivator.java +++ b/src/net/java/sip/communicator/impl/gui/GuiActivator.java @@ -11,26 +11,26 @@ import net.java.sip.communicator.impl.gui.main.account.*; import net.java.sip.communicator.impl.gui.main.contactlist.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.audionotifier.*; import net.java.sip.communicator.service.browserlauncher.*; import net.java.sip.communicator.service.callhistory.*; -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.service.contactlist.*; import net.java.sip.communicator.service.contactsource.*; import net.java.sip.communicator.service.desktop.*; -import net.java.sip.communicator.service.fileaccess.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.keybindings.*; import net.java.sip.communicator.service.metahistory.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.replacement.*; import net.java.sip.communicator.service.replacement.smilies.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.service.shutdown.*; import net.java.sip.communicator.service.systray.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.audionotifier.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.fileaccess.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/gui/UIServiceImpl.java b/src/net/java/sip/communicator/impl/gui/UIServiceImpl.java index c705230a6..45eb91cc3 100644 --- a/src/net/java/sip/communicator/impl/gui/UIServiceImpl.java +++ b/src/net/java/sip/communicator/impl/gui/UIServiceImpl.java @@ -35,12 +35,14 @@ import net.java.sip.communicator.service.gui.Container; import net.java.sip.communicator.service.gui.event.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.service.shutdown.*; import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; +import org.jitsi.util.*; import org.osgi.framework.*; import com.sun.jna.examples.*; @@ -1515,4 +1517,4 @@ public void startChat(String[] participants) else throw new IllegalArgumentException("participants"); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/customcontrols/SCScrollPane.java b/src/net/java/sip/communicator/impl/gui/customcontrols/SCScrollPane.java index 3a1ccf089..d56dab53d 100644 --- a/src/net/java/sip/communicator/impl/gui/customcontrols/SCScrollPane.java +++ b/src/net/java/sip/communicator/impl/gui/customcontrols/SCScrollPane.java @@ -15,10 +15,11 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.util.*; + /** * The SCScrollPane is a JScrollPane with a custom viewport that allows to * set an image as a background. Depending on the diff --git a/src/net/java/sip/communicator/impl/gui/customcontrols/wizard/Wizard.java b/src/net/java/sip/communicator/impl/gui/customcontrols/wizard/Wizard.java index 2d4c7c1b0..923015831 100644 --- a/src/net/java/sip/communicator/impl/gui/customcontrols/wizard/Wizard.java +++ b/src/net/java/sip/communicator/impl/gui/customcontrols/wizard/Wizard.java @@ -16,9 +16,10 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; + /** * This class implements a basic wizard dialog, where the programmer can insert * one or more Components to act as panels. These panels can be navigated diff --git a/src/net/java/sip/communicator/impl/gui/lookandfeel/SIPCommCheckBoxUI.java b/src/net/java/sip/communicator/impl/gui/lookandfeel/SIPCommCheckBoxUI.java index 2e208b345..757006fea 100644 --- a/src/net/java/sip/communicator/impl/gui/lookandfeel/SIPCommCheckBoxUI.java +++ b/src/net/java/sip/communicator/impl/gui/lookandfeel/SIPCommCheckBoxUI.java @@ -34,4 +34,4 @@ public void paint(Graphics g, JComponent c) AntialiasingManager.activateAntialiasing(g); super.paint(g, c); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/DialPadFieldUI.java b/src/net/java/sip/communicator/impl/gui/main/DialPadFieldUI.java index a3e2adbb9..c4cf2526b 100644 --- a/src/net/java/sip/communicator/impl/gui/main/DialPadFieldUI.java +++ b/src/net/java/sip/communicator/impl/gui/main/DialPadFieldUI.java @@ -103,4 +103,4 @@ public static ComponentUI createUI(JComponent c) { return new DialPadFieldUI(); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/GeneralDialPadDialog.java b/src/net/java/sip/communicator/impl/gui/main/GeneralDialPadDialog.java index d40260f3e..1a165282a 100644 --- a/src/net/java/sip/communicator/impl/gui/main/GeneralDialPadDialog.java +++ b/src/net/java/sip/communicator/impl/gui/main/GeneralDialPadDialog.java @@ -14,11 +14,12 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.main.call.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; import net.java.sip.communicator.util.swing.plaf.*; +import org.jitsi.util.*; + import com.explodingpixels.macwidgets.*; /** diff --git a/src/net/java/sip/communicator/impl/gui/main/GeneralDialPanel.java b/src/net/java/sip/communicator/impl/gui/main/GeneralDialPanel.java index 1f61649a2..58075ac95 100755 --- a/src/net/java/sip/communicator/impl/gui/main/GeneralDialPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/GeneralDialPanel.java @@ -16,10 +16,11 @@ import net.java.sip.communicator.impl.gui.main.call.*; import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.service.resources.*; -import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.util.*; + /** * The DialPanel is the panel that contains the buttons to dial a * phone number. diff --git a/src/net/java/sip/communicator/impl/gui/main/MainFrame.java b/src/net/java/sip/communicator/impl/gui/main/MainFrame.java index 6824c943a..e2a6ae195 100644 --- a/src/net/java/sip/communicator/impl/gui/main/MainFrame.java +++ b/src/net/java/sip/communicator/impl/gui/main/MainFrame.java @@ -8,7 +8,7 @@ import java.awt.*; import java.awt.event.*; -import java.beans.PropertyChangeEvent; +import java.beans.*; import java.util.*; import java.util.List; @@ -23,20 +23,22 @@ import net.java.sip.communicator.impl.gui.main.menus.*; import net.java.sip.communicator.impl.gui.main.presence.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.service.contacteventhandler.*; import net.java.sip.communicator.service.contactlist.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.gui.Container; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.protocol.OperationSetMessageWaiting.*; +import net.java.sip.communicator.service.protocol.OperationSetMessageWaiting.MessageType; import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; import net.java.sip.communicator.util.swing.event.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.resources.*; +import org.jitsi.util.*; import org.osgi.framework.*; import com.explodingpixels.macwidgets.*; @@ -2009,4 +2011,4 @@ public void loadSkin() GuiActivator.getResources() .getColor("service.gui.MAIN_WINDOW_BACKGROUND"))); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/account/AccountRegWizardContainerImpl.java b/src/net/java/sip/communicator/impl/gui/main/account/AccountRegWizardContainerImpl.java index 78026b4da..314ee9830 100644 --- a/src/net/java/sip/communicator/impl/gui/main/account/AccountRegWizardContainerImpl.java +++ b/src/net/java/sip/communicator/impl/gui/main/account/AccountRegWizardContainerImpl.java @@ -7,18 +7,17 @@ import java.io.*; import java.util.*; -import java.util.List; import javax.imageio.*; import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.customcontrols.wizard.*; import net.java.sip.communicator.impl.gui.main.*; -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.configuration.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/gui/main/account/AccountsConfigurationPanel.java b/src/net/java/sip/communicator/impl/gui/main/account/AccountsConfigurationPanel.java index 5b7ed35b2..90246d6fb 100644 --- a/src/net/java/sip/communicator/impl/gui/main/account/AccountsConfigurationPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/account/AccountsConfigurationPanel.java @@ -14,11 +14,12 @@ import javax.swing.event.*; import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.configuration.*; + /** * The AccountsConfigurationPanel is the panel containing the accounts * list and according buttons shown in the options form. diff --git a/src/net/java/sip/communicator/impl/gui/main/account/NewAccountDialog.java b/src/net/java/sip/communicator/impl/gui/main/account/NewAccountDialog.java index 0f62bae33..1c6514a2d 100644 --- a/src/net/java/sip/communicator/impl/gui/main/account/NewAccountDialog.java +++ b/src/net/java/sip/communicator/impl/gui/main/account/NewAccountDialog.java @@ -18,10 +18,10 @@ import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/gui/main/call/AbstractCallToggleButton.java b/src/net/java/sip/communicator/impl/gui/main/call/AbstractCallToggleButton.java index 13d217dda..7958d68db 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/AbstractCallToggleButton.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/AbstractCallToggleButton.java @@ -300,4 +300,4 @@ public void setIconImageID(ImageID iconImageID) * action has been performed and that it should execute its very logic. */ public abstract void buttonPressed(); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallButton.java b/src/net/java/sip/communicator/impl/gui/main/call/CallButton.java index b2c1b7d3c..69c86d52e 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/CallButton.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/CallButton.java @@ -149,4 +149,4 @@ private void updateTooltip() else setToolTipText(defaultTooltip); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java b/src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java index 9e0b67950..476ad524f 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java @@ -223,4 +223,4 @@ public void loadSkin() setHistoryView(); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallInfoFrame.java b/src/net/java/sip/communicator/impl/gui/main/call/CallInfoFrame.java index baea81ff6..49ef171ee 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/CallInfoFrame.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/CallInfoFrame.java @@ -12,16 +12,18 @@ import javax.swing.*; -import com.explodingpixels.macwidgets.*; - import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.media.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; + import org.ice4j.ice.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.resources.*; +import org.jitsi.util.*; + +import com.explodingpixels.macwidgets.*; /** * The frame displaying the statistical information for a call. @@ -495,8 +497,8 @@ private void appendStreamEncryptionMethod( } String rtpType; - SrtpControl srtpControl = callPeerMediaHandler - .getEncryptionMethod(mediaType); + SrtpControl srtpControl + = callPeerMediaHandler.getEncryptionMethod(mediaType); // If the stream is secured. if(srtpControl != null) { diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java b/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java index 4d7ae57df..b20dc5d51 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java @@ -19,14 +19,15 @@ import net.java.sip.communicator.impl.gui.main.contactlist.*; import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.service.contactlist.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.transparent.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.device.*; + /** * The CallManager is the one that handles calls. It contains also * the "Call" and "Hang up" buttons panel. Here are handles incoming and @@ -1170,7 +1171,7 @@ public void run() qualityControl.setPreferredRemoteSendMaxPreset( qualityPreset); } - catch(OperationFailedException e) + catch(org.jitsi.service.protocol.OperationFailedException e) { logger.info("Unable to change video quality.", e); diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java index 84ed128d5..751bba184 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java @@ -16,23 +16,25 @@ import javax.swing.border.*; import javax.swing.event.*; -import org.osgi.framework.*; - import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.event.*; import net.java.sip.communicator.impl.gui.main.call.conference.*; import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.service.contactlist.*; import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; import net.java.sip.communicator.util.swing.border.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.device.*; +import org.jitsi.util.*; +import org.osgi.framework.*; + /** * The dialog created for a given call. * diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallPeerAdapter.java b/src/net/java/sip/communicator/impl/gui/main/call/CallPeerAdapter.java index e61759da8..23c39b3ff 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/CallPeerAdapter.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/CallPeerAdapter.java @@ -11,6 +11,8 @@ import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; +import org.jitsi.service.protocol.event.*; + /** * The CallPeerAdapter is an adapter that implements all common * CallPeer related listeners in order to facilitate the task of diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallStatusPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/CallStatusPanel.java index 3099702f9..e50f7ef81 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/CallStatusPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/CallStatusPanel.java @@ -53,4 +53,4 @@ public void paintComponent(Graphics g) g.dispose(); } } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallTransferHandler.java b/src/net/java/sip/communicator/impl/gui/main/call/CallTransferHandler.java index 86dbfb777..beaf53667 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/CallTransferHandler.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/CallTransferHandler.java @@ -219,4 +219,4 @@ else if (t.isDataFlavorSupported(DataFlavor.stringFlavor)) } return false; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/call/DTMFHandler.java b/src/net/java/sip/communicator/impl/gui/main/call/DTMFHandler.java index 62594fbe3..126c6e505 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/DTMFHandler.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/DTMFHandler.java @@ -13,12 +13,13 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.utils.*; - -import net.java.sip.communicator.service.audionotifier.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.audionotifier.*; +import org.jitsi.service.protocol.*; + /** * Handles DTMF sending and playing sound notifications for that. * diff --git a/src/net/java/sip/communicator/impl/gui/main/call/DesktopSharingFrame.java b/src/net/java/sip/communicator/impl/gui/main/call/DesktopSharingFrame.java index 693c6cf2e..41de8abbd 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/DesktopSharingFrame.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/DesktopSharingFrame.java @@ -15,13 +15,15 @@ import javax.swing.*; import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; import net.java.sip.communicator.util.swing.*; import net.java.sip.communicator.util.swing.transparent.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.util.*; + /** * * @author Yana Stamcheva diff --git a/src/net/java/sip/communicator/impl/gui/main/call/InputVolumeControlButton.java b/src/net/java/sip/communicator/impl/gui/main/call/InputVolumeControlButton.java index 5dc9996ae..f318667ac 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/InputVolumeControlButton.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/InputVolumeControlButton.java @@ -16,11 +16,12 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.event.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.event.*; + /** * Represents an UI means to mute the audio stream sent in an associated * Call. diff --git a/src/net/java/sip/communicator/impl/gui/main/call/LocalVideoButton.java b/src/net/java/sip/communicator/impl/gui/main/call/LocalVideoButton.java index 54b4961b9..d945a43ed 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/LocalVideoButton.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/LocalVideoButton.java @@ -8,11 +8,12 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.device.*; + /** * The local video button is the button used to start/stop video in a * conversation. diff --git a/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPanel.java index 8a4796b0e..13bdaf4bc 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPanel.java @@ -12,13 +12,16 @@ import javax.swing.*; -import com.explodingpixels.macwidgets.*; - import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; import net.java.sip.communicator.util.swing.*; +import org.jitsi.util.*; + +import com.explodingpixels.macwidgets.*; + /** * The CallPanel is the panel containing call information. It's created * and added to the main tabbed pane when user makes or receives calls. It shows diff --git a/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPeerPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPeerPanel.java index a1bfc7ca6..86ed4494e 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPeerPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPeerPanel.java @@ -17,7 +17,6 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.main.contactlist.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.media.*; @@ -25,6 +24,11 @@ import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; +import net.java.sip.communicator.util.swing.TransparentPanel; + +import org.jitsi.service.neomedia.*; +import org.jitsi.service.protocol.event.*; +import org.jitsi.util.swing.*; /** * The OneToOneCallPeerPanel is the panel containing data for a call diff --git a/src/net/java/sip/communicator/impl/gui/main/call/OutputVolumeControlButton.java b/src/net/java/sip/communicator/impl/gui/main/call/OutputVolumeControlButton.java index 7dfdde5f1..78a157d50 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/OutputVolumeControlButton.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/OutputVolumeControlButton.java @@ -13,10 +13,11 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.neomedia.*; + /** * The VolumeControlButton is the button shown in the call window, * which allows to adjust the playback volume of your call. diff --git a/src/net/java/sip/communicator/impl/gui/main/call/ParanoiaTimerSecurityPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/ParanoiaTimerSecurityPanel.java index 13c7de2e0..f950a7fb1 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/ParanoiaTimerSecurityPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/ParanoiaTimerSecurityPanel.java @@ -6,17 +6,19 @@ */ package net.java.sip.communicator.impl.gui.main.call; +import java.awt.*; +import java.text.*; +import java.util.*; +import java.util.Timer; + +import javax.swing.*; + import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; -import javax.swing.*; -import java.awt.*; -import java.text.*; -import java.util.*; -import java.util.Timer; +import org.jitsi.service.neomedia.*; /** * @author Damian Minkov diff --git a/src/net/java/sip/communicator/impl/gui/main/call/PreCallDialog.java b/src/net/java/sip/communicator/impl/gui/main/call/PreCallDialog.java index fa31bb6e1..c3cc565d7 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/PreCallDialog.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/PreCallDialog.java @@ -12,11 +12,12 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.util.*; + import com.explodingpixels.macwidgets.*; /** diff --git a/src/net/java/sip/communicator/impl/gui/main/call/RecordButton.java b/src/net/java/sip/communicator/impl/gui/main/call/RecordButton.java index 607231719..12289ced4 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/RecordButton.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/RecordButton.java @@ -11,13 +11,15 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.resources.*; +import org.jitsi.util.*; + /** * The button that starts/stops the call recording. * diff --git a/src/net/java/sip/communicator/impl/gui/main/call/ResizeVideoButton.java b/src/net/java/sip/communicator/impl/gui/main/call/ResizeVideoButton.java index 9b581c1b0..e7cae169c 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/ResizeVideoButton.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/ResizeVideoButton.java @@ -13,9 +13,10 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; +import org.jitsi.service.neomedia.*; + /** * The button responsible to resize video for the associated participant. * diff --git a/src/net/java/sip/communicator/impl/gui/main/call/SecurityPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/SecurityPanel.java index 202c15078..22e940027 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/SecurityPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/SecurityPanel.java @@ -6,12 +6,13 @@ */ package net.java.sip.communicator.impl.gui.main.call; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.neomedia.*; + /** * Base class for security panels that show encryption specific UI controls. * diff --git a/src/net/java/sip/communicator/impl/gui/main/call/SelectScreenDialog.java b/src/net/java/sip/communicator/impl/gui/main/call/SelectScreenDialog.java index 961fdd335..e08eb0ca9 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/SelectScreenDialog.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/SelectScreenDialog.java @@ -14,11 +14,14 @@ import javax.swing.*; import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.format.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; +import net.java.sip.communicator.util.swing.TransparentPanel; + +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.device.*; +import org.jitsi.service.neomedia.format.*; +import org.jitsi.util.swing.*; /** * A dialog dedicated to desktop streaming/sharing. Shows the possible screens diff --git a/src/net/java/sip/communicator/impl/gui/main/call/UIVideoHandler.java b/src/net/java/sip/communicator/impl/gui/main/call/UIVideoHandler.java index 3bd9caac5..37863a9ef 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/UIVideoHandler.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/UIVideoHandler.java @@ -16,12 +16,15 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.main.call.conference.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; -import net.java.sip.communicator.util.event.*; import net.java.sip.communicator.util.swing.*; +import net.java.sip.communicator.util.swing.TransparentPanel; + +import org.jitsi.service.neomedia.*; +import org.jitsi.util.event.*; +import org.jitsi.util.swing.*; /** * The UIVideoHandler is meant to handle all video related events. diff --git a/src/net/java/sip/communicator/impl/gui/main/call/VolumeControlSlider.java b/src/net/java/sip/communicator/impl/gui/main/call/VolumeControlSlider.java index 08b74320a..9f8d2f271 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/VolumeControlSlider.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/VolumeControlSlider.java @@ -11,10 +11,11 @@ import javax.swing.*; import javax.swing.event.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.event.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.event.*; + /** * The volume control slider component. * diff --git a/src/net/java/sip/communicator/impl/gui/main/call/ZrtpSecurityPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/ZrtpSecurityPanel.java index 31b7ab5ff..8c56ae9c6 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/ZrtpSecurityPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/ZrtpSecurityPanel.java @@ -14,16 +14,18 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.media.*; -import net.java.sip.communicator.util.event.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.protocol.event.*; +import org.jitsi.util.event.*; + /** * The panel containing details about ZRTP call security. * diff --git a/src/net/java/sip/communicator/impl/gui/main/call/conference/BasicConferenceParticipantPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/conference/BasicConferenceParticipantPanel.java index 2f0f3d2fa..1b13b99f4 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/conference/BasicConferenceParticipantPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/conference/BasicConferenceParticipantPanel.java @@ -13,13 +13,14 @@ import net.java.sip.communicator.impl.gui.main.call.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.neomedia.*; + /** * The basic panel used to render any conference participant. Meant to be * extended for CallPeers and ConferenceMembers. diff --git a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceFocusPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceFocusPanel.java index c50b83c94..e67a97fff 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceFocusPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceFocusPanel.java @@ -18,6 +18,8 @@ import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.protocol.event.*; + /** * * diff --git a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java index 593b8766d..0dc53c4da 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java @@ -482,4 +482,4 @@ public String toString() return contact; } } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferencePeerPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferencePeerPanel.java index c091ac04e..c23021962 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferencePeerPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferencePeerPanel.java @@ -13,16 +13,19 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.main.call.*; -import net.java.sip.communicator.impl.gui.main.call.CallPeerAdapter; // disambiguation +import net.java.sip.communicator.impl.gui.main.call.CallPeerAdapter; import net.java.sip.communicator.impl.gui.main.presence.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.protocol.event.*; +// disambiguation + /** * The ConferencePeerPanel renders a single ConferencePeer, * which is not a conference focus. diff --git a/src/net/java/sip/communicator/impl/gui/main/call/conference/ProtocolProviderSelectorBox.java b/src/net/java/sip/communicator/impl/gui/main/call/conference/ProtocolProviderSelectorBox.java index 7d21f3f36..2e7c57452 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/conference/ProtocolProviderSelectorBox.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/conference/ProtocolProviderSelectorBox.java @@ -253,4 +253,4 @@ public void paintComponent(Graphics g) this); } } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/call/conference/VideoConferenceCallPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/conference/VideoConferenceCallPanel.java index f44bc8b39..03a78b75d 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/conference/VideoConferenceCallPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/conference/VideoConferenceCallPanel.java @@ -10,7 +10,8 @@ import net.java.sip.communicator.impl.gui.main.call.CallPeerAdapter; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.util.swing.*; + +import org.jitsi.util.swing.*; /** * The UI for video conference calls. This panel contains all conference peers diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationComponent.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationComponent.java index 7aa4dca00..e25a9afb1 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationComponent.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationComponent.java @@ -14,11 +14,12 @@ import javax.swing.*; import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; + /** * The ChatConversationComponent is a component that can be added to * the conversation area of the chat window in order to display any special diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java index 97c65b48a..70a8ab90f 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java @@ -9,8 +9,7 @@ import java.awt.*; import java.awt.Container; import java.awt.event.*; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; +import java.beans.*; import java.io.*; import java.util.*; import java.util.List; @@ -30,11 +29,13 @@ import net.java.sip.communicator.service.metahistory.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; import net.java.sip.communicator.util.swing.SwingWorker; +import org.jitsi.util.*; + /** * The ChatPanel is the panel, where users can write and send messages, * view received messages. A ChatPanel is created for a contact or for a group @@ -2636,4 +2637,4 @@ public void removeChatLinkClickedListener(ChatLinkClickedListener listener) { conversationPanel.removeChatLinkClickedListener(listener); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java index e06118265..75fc85147 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java @@ -23,9 +23,11 @@ import net.java.sip.communicator.service.gui.Container; import net.java.sip.communicator.service.keybindings.*; import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.util.*; import org.osgi.framework.*; import com.explodingpixels.macwidgets.*; diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java index 7962e872f..5f122c297 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java @@ -20,7 +20,9 @@ import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.gui.event.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; + +import org.jitsi.util.*; /** * Manages chat windows and panels. diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatWritePanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatWritePanel.java index 7829c825f..1c3149968 100755 --- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatWritePanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatWritePanel.java @@ -21,7 +21,7 @@ import net.java.sip.communicator.impl.gui.customcontrols.*; import net.java.sip.communicator.impl.gui.main.chat.menus.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.gui.event.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ContactPhotoPanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ContactPhotoPanel.java index 8f95667a3..54c8ac634 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/ContactPhotoPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/ContactPhotoPanel.java @@ -188,4 +188,4 @@ public String getToolTipText(MouseEvent event) { return chatSession.getChatName(); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/FontChooser.java b/src/net/java/sip/communicator/impl/gui/main/chat/FontChooser.java index c0f287621..4945aed0b 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/FontChooser.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/FontChooser.java @@ -14,9 +14,10 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; + /** * The FontChooserDialog is a dialog for font selection * diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatContactRoleIcon.java b/src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatContactRoleIcon.java index 1468b5e3c..80b3a8c85 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatContactRoleIcon.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatContactRoleIcon.java @@ -50,4 +50,4 @@ public static Icon getRoleIcon(ChatRoomMemberRole role) } return i; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatRoomSubjectPanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatRoomSubjectPanel.java index 724b932b1..75e46abba 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatRoomSubjectPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatRoomSubjectPanel.java @@ -15,11 +15,12 @@ import net.java.sip.communicator.impl.gui.customcontrols.*; import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; + /** * The panel containing the subject of the chat room and the configuration * button. diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java b/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java index 39eb97261..64e08b74d 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java @@ -20,12 +20,12 @@ import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; -// Java 1.6 has javax.swing.SwingWorker so we have to disambiguate. -import org.jdesktop.swingworker.SwingWorker; +import org.jdesktop.swingworker.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; +// Java 1.6 has javax.swing.SwingWorker so we have to disambiguate. /** * The ConferenceChatManager is the one that manages both chat room and diff --git a/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomList.java b/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomList.java index 2df98ef7d..e936e4338 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomList.java +++ b/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomList.java @@ -10,10 +10,10 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.main.chat.conference.*; -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.configuration.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java b/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java index edec4b746..74c006f1a 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java +++ b/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java @@ -11,7 +11,7 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.main.chat.conference.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; diff --git a/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomRightButtonMenu.java b/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomRightButtonMenu.java index 576a49002..d5be43c4f 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomRightButtonMenu.java +++ b/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomRightButtonMenu.java @@ -21,6 +21,8 @@ import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; + /** * The ChatRoomsListRightButtonMenu is the menu, opened when user clicks * with the right mouse button on the chat rooms list panel. It's the one that diff --git a/src/net/java/sip/communicator/impl/gui/main/chatroomslist/joinforms/JoinChatRoomWizard.java b/src/net/java/sip/communicator/impl/gui/main/chatroomslist/joinforms/JoinChatRoomWizard.java index 1b8c66226..3d29b72ff 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chatroomslist/joinforms/JoinChatRoomWizard.java +++ b/src/net/java/sip/communicator/impl/gui/main/chatroomslist/joinforms/JoinChatRoomWizard.java @@ -75,4 +75,4 @@ public void wizardFinished(WizardEvent e) newChatRoom.getChatRoomProvider()); } } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/chatroomslist/joinforms/JoinChatRoomWizardPage2.java b/src/net/java/sip/communicator/impl/gui/main/chatroomslist/joinforms/JoinChatRoomWizardPage2.java index d39b6f271..4f23b02a9 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chatroomslist/joinforms/JoinChatRoomWizardPage2.java +++ b/src/net/java/sip/communicator/impl/gui/main/chatroomslist/joinforms/JoinChatRoomWizardPage2.java @@ -160,4 +160,4 @@ public void removeUpdate(DocumentEvent e) public void changedUpdate(DocumentEvent e) {} } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/configforms/ConfigurationFrame.java b/src/net/java/sip/communicator/impl/gui/main/configforms/ConfigurationFrame.java index 77ceba8f5..054b5c0be 100644 --- a/src/net/java/sip/communicator/impl/gui/main/configforms/ConfigurationFrame.java +++ b/src/net/java/sip/communicator/impl/gui/main/configforms/ConfigurationFrame.java @@ -13,9 +13,10 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.main.*; import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; import net.java.sip.communicator.util.swing.*; +import org.jitsi.util.*; import org.osgi.framework.*; import com.explodingpixels.macwidgets.*; diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java index d38df5e47..f92eb915e 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java @@ -1548,4 +1548,4 @@ public void run() } } } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListUtils.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListUtils.java index 817d71008..18a630e7c 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListUtils.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListUtils.java @@ -98,4 +98,4 @@ else if (errorCode } }.start(); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/GroupNode.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/GroupNode.java index d988c3e79..11753db19 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/GroupNode.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/GroupNode.java @@ -456,4 +456,4 @@ private void refreshSelection(int lastSelectedIndex, int newSelectedIndex) sipCommTreeUI.selectionChanged(oldSelectionPath, newSelectionPath); } } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFieldUI.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFieldUI.java index 06a680380..bf85c9e20 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFieldUI.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFieldUI.java @@ -351,4 +351,4 @@ public static ComponentUI createUI(JComponent c) { return new SearchFieldUI(); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactDetail.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactDetail.java index 26670893f..c50e0c263 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactDetail.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactDetail.java @@ -201,4 +201,4 @@ public void setPrefix(String prefix) * null if the detail doesn't support presence */ public abstract PresenceStatus getPresenceStatus(); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/UnknownContactPanel.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/UnknownContactPanel.java index 6549cb0c9..38ce960c8 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/UnknownContactPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/UnknownContactPanel.java @@ -259,4 +259,4 @@ public void setVisible(boolean isVisible) super.setVisible(isVisible); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIContact.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIContact.java index dc834e1f9..e6735cb3c 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIContact.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIContact.java @@ -608,4 +608,4 @@ public JPopupMenu getRightButtonMenu() { return new MetaContactRightButtonMenu(metaContact); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContact.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContact.java index d64c382e3..ae728ecc0 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContact.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContact.java @@ -17,7 +17,8 @@ import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.OperationSetMessageWaiting.MessageType; import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.service.resources.*; + +import org.jitsi.service.resources.*; /** * The NotificationContact represents a notification entry shown in diff --git a/src/net/java/sip/communicator/impl/gui/main/login/DefaultSecurityAuthority.java b/src/net/java/sip/communicator/impl/gui/main/login/DefaultSecurityAuthority.java index 96caa5463..e2c975366 100644 --- a/src/net/java/sip/communicator/impl/gui/main/login/DefaultSecurityAuthority.java +++ b/src/net/java/sip/communicator/impl/gui/main/login/DefaultSecurityAuthority.java @@ -147,4 +147,4 @@ public boolean isUserNameEditable() { return isUserNameEditable; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/main/menus/AutoAnswerMenu.java b/src/net/java/sip/communicator/impl/gui/main/menus/AutoAnswerMenu.java index cfcaf17b8..e3bd95f93 100644 --- a/src/net/java/sip/communicator/impl/gui/main/menus/AutoAnswerMenu.java +++ b/src/net/java/sip/communicator/impl/gui/main/menus/AutoAnswerMenu.java @@ -10,17 +10,18 @@ import java.awt.event.*; import java.awt.image.*; +import javax.swing.*; +import javax.swing.border.*; + import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; -import org.osgi.framework.*; -import javax.swing.*; -import javax.swing.border.*; +import org.jitsi.service.resources.*; +import org.osgi.framework.*; /** * The auto answer menu dynamically adds/removes menu items for enabled/disabled diff --git a/src/net/java/sip/communicator/impl/gui/main/menus/FileMenu.java b/src/net/java/sip/communicator/impl/gui/main/menus/FileMenu.java index 1c8aa6d35..ddf214562 100644 --- a/src/net/java/sip/communicator/impl/gui/main/menus/FileMenu.java +++ b/src/net/java/sip/communicator/impl/gui/main/menus/FileMenu.java @@ -20,11 +20,12 @@ import net.java.sip.communicator.impl.gui.main.contactlist.addgroup.*; import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; + /** * The FileMenu is a menu in the main application menu bar that * contains "New account". diff --git a/src/net/java/sip/communicator/impl/gui/main/menus/HelpMenu.java b/src/net/java/sip/communicator/impl/gui/main/menus/HelpMenu.java index 4a3c0ae55..6cf1680bc 100644 --- a/src/net/java/sip/communicator/impl/gui/main/menus/HelpMenu.java +++ b/src/net/java/sip/communicator/impl/gui/main/menus/HelpMenu.java @@ -9,13 +9,13 @@ import java.awt.event.*; import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.impl.gui.event.*; import net.java.sip.communicator.impl.gui.main.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.gui.Container; -import net.java.sip.communicator.service.resources.*; +import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; + /** * The HelpMenu is a menu in the main application menu bar. * diff --git a/src/net/java/sip/communicator/impl/gui/main/menus/MainMenu.java b/src/net/java/sip/communicator/impl/gui/main/menus/MainMenu.java index e5f840c34..47b8e07c9 100755 --- a/src/net/java/sip/communicator/impl/gui/main/menus/MainMenu.java +++ b/src/net/java/sip/communicator/impl/gui/main/menus/MainMenu.java @@ -10,7 +10,8 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.main.*; -import net.java.sip.communicator.service.resources.*; + +import org.jitsi.service.resources.*; /** * The main menu bar. This is the menu bar that appears on top of the main diff --git a/src/net/java/sip/communicator/impl/gui/main/presence/GlobalStatusSelectorBox.java b/src/net/java/sip/communicator/impl/gui/main/presence/GlobalStatusSelectorBox.java index e831a30f8..5bfde2490 100644 --- a/src/net/java/sip/communicator/impl/gui/main/presence/GlobalStatusSelectorBox.java +++ b/src/net/java/sip/communicator/impl/gui/main/presence/GlobalStatusSelectorBox.java @@ -18,7 +18,7 @@ import net.java.sip.communicator.impl.gui.lookandfeel.*; import net.java.sip.communicator.impl.gui.main.*; import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.service.systray.*; diff --git a/src/net/java/sip/communicator/impl/gui/main/presence/StatusSelectorMenu.java b/src/net/java/sip/communicator/impl/gui/main/presence/StatusSelectorMenu.java index 8b0df4cce..4cc7968a1 100644 --- a/src/net/java/sip/communicator/impl/gui/main/presence/StatusSelectorMenu.java +++ b/src/net/java/sip/communicator/impl/gui/main/presence/StatusSelectorMenu.java @@ -13,7 +13,7 @@ import javax.swing.*; import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; diff --git a/src/net/java/sip/communicator/impl/gui/main/presence/avatar/imagepicker/WebcamDialog.java b/src/net/java/sip/communicator/impl/gui/main/presence/avatar/imagepicker/WebcamDialog.java index 4429d9f1d..db16279d8 100644 --- a/src/net/java/sip/communicator/impl/gui/main/presence/avatar/imagepicker/WebcamDialog.java +++ b/src/net/java/sip/communicator/impl/gui/main/presence/avatar/imagepicker/WebcamDialog.java @@ -13,10 +13,13 @@ import javax.swing.*; import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.service.audionotifier.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; +import net.java.sip.communicator.util.swing.TransparentPanel; + +import org.jitsi.service.audionotifier.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.util.swing.*; /** * A dialog showing the webcam and allowing the user to grap a snapshot diff --git a/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf b/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf index 4b8512a24..2673e6ab1 100644 --- a/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf +++ b/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf @@ -4,17 +4,30 @@ Bundle-Description: An implementation of the UI service. Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes -Import-Package: org.osgi.framework, - net.java.sip.communicator.service.audionotifier, +Import-Package: com.apple.eawt, + com.sun.jna.examples, + javax.accessibility, + javax.imageio, + javax.swing, + javax.swing.border, + javax.swing.event, + javax.swing.filechooser, + javax.swing.plaf, + javax.swing.plaf.basic, + javax.swing.plaf.metal, + javax.swing.table, + javax.swing.text, + javax.swing.text.html, + javax.swing.tree, + javax.swing.undo, net.java.sip.communicator.service.browserlauncher, net.java.sip.communicator.service.callhistory, net.java.sip.communicator.service.callhistory.event, - net.java.sip.communicator.service.configuration, net.java.sip.communicator.service.contacteventhandler, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, + net.java.sip.communicator.service.contactsource, net.java.sip.communicator.service.desktop, - net.java.sip.communicator.service.fileaccess, net.java.sip.communicator.service.filehistory, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, @@ -26,39 +39,29 @@ Import-Package: org.osgi.framework, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.protocol.icqconstants, net.java.sip.communicator.service.protocol.media, + net.java.sip.communicator.service.replacement, + net.java.sip.communicator.service.replacement.smilies, net.java.sip.communicator.service.resources, net.java.sip.communicator.service.shutdown, net.java.sip.communicator.service.systray, - net.java.sip.communicator.service.neomedia, - net.java.sip.communicator.service.neomedia.event, - net.java.sip.communicator.service.neomedia.device, - net.java.sip.communicator.service.neomedia.format, - net.java.sip.communicator.service.contactsource, - net.java.sip.communicator.service.replacement, - net.java.sip.communicator.service.replacement.smilies, net.java.sip.communicator.util, net.java.sip.communicator.util.event, net.java.sip.communicator.util.skin, - net.java.sip.communicator.util.swing.transparent, net.java.sip.communicator.util.swing, net.java.sip.communicator.util.swing.border, net.java.sip.communicator.util.swing.event, net.java.sip.communicator.util.swing.plaf, - javax.accessibility, - javax.imageio, - javax.swing, - javax.swing.border, - javax.swing.event, - javax.swing.filechooser, - javax.swing.plaf, - javax.swing.plaf.basic, - javax.swing.plaf.metal, - javax.swing.table, - javax.swing.text, - javax.swing.text.html, - javax.swing.tree, - javax.swing.undo, - com.sun.jna.examples, + net.java.sip.communicator.util.swing.transparent, org.jdesktop.jdic.desktop, - say.swing, - com.apple.eawt + org.jitsi.service.audionotifier, + org.jitsi.service.configuration, + org.jitsi.service.fileaccess, + org.jitsi.service.neomedia, + org.jitsi.service.neomedia.event, + org.jitsi.service.neomedia.device, + org.jitsi.service.neomedia.format, + org.jitsi.service.resources, + org.jitsi.util, + org.jitsi.util.swing, + org.osgi.framework, + say.swing diff --git a/src/net/java/sip/communicator/impl/gui/utils/ConfigurationManager.java b/src/net/java/sip/communicator/impl/gui/utils/ConfigurationManager.java index 3ec0530ed..73c078bb5 100644 --- a/src/net/java/sip/communicator/impl/gui/utils/ConfigurationManager.java +++ b/src/net/java/sip/communicator/impl/gui/utils/ConfigurationManager.java @@ -11,7 +11,7 @@ import java.util.List; import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; import org.osgi.framework.*; diff --git a/src/net/java/sip/communicator/impl/gui/utils/SoundProperties.java b/src/net/java/sip/communicator/impl/gui/utils/SoundProperties.java index 76d0aaf84..a4933f5ea 100644 --- a/src/net/java/sip/communicator/impl/gui/utils/SoundProperties.java +++ b/src/net/java/sip/communicator/impl/gui/utils/SoundProperties.java @@ -7,7 +7,8 @@ package net.java.sip.communicator.impl.gui.utils; import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.service.resources.*; + +import org.jitsi.service.resources.*; /** * Manages the access to the properties file containing all sounds paths. diff --git a/src/net/java/sip/communicator/impl/hid/HIDServiceImpl.java b/src/net/java/sip/communicator/impl/hid/HIDServiceImpl.java index 82a887102..3e5c48712 100644 --- a/src/net/java/sip/communicator/impl/hid/HIDServiceImpl.java +++ b/src/net/java/sip/communicator/impl/hid/HIDServiceImpl.java @@ -10,7 +10,9 @@ import java.awt.event.*; import net.java.sip.communicator.service.hid.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; + +import org.jitsi.util.*; /** * Implementation of the HID service to provide way of regenerate key press diff --git a/src/net/java/sip/communicator/impl/hid/hid.manifest.mf b/src/net/java/sip/communicator/impl/hid/hid.manifest.mf index 504fb2dcc..a4db319f9 100644 --- a/src/net/java/sip/communicator/impl/hid/hid.manifest.mf +++ b/src/net/java/sip/communicator/impl/hid/hid.manifest.mf @@ -5,5 +5,6 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, + org.jitsi.util, net.java.sip.communicator.util -Export-Package: net.java.sip.communicator.service.hid \ No newline at end of file +Export-Package: net.java.sip.communicator.service.hid diff --git a/src/net/java/sip/communicator/impl/history/HistoryServiceImpl.java b/src/net/java/sip/communicator/impl/history/HistoryServiceImpl.java index 48214eb85..e4139d91c 100644 --- a/src/net/java/sip/communicator/impl/history/HistoryServiceImpl.java +++ b/src/net/java/sip/communicator/impl/history/HistoryServiceImpl.java @@ -11,16 +11,16 @@ import javax.xml.parsers.*; -import org.osgi.framework.*; -import org.w3c.dom.*; -import org.xml.sax.*; - -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.fileaccess.*; import net.java.sip.communicator.service.history.*; import net.java.sip.communicator.service.history.records.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.fileaccess.*; +import org.osgi.framework.*; +import org.w3c.dom.*; +import org.xml.sax.*; + /** * @author Alexander Pelov * @author Damian Minkov diff --git a/src/net/java/sip/communicator/impl/history/history.manifest.mf b/src/net/java/sip/communicator/impl/history/history.manifest.mf index bc08a6d90..249408945 100644 --- a/src/net/java/sip/communicator/impl/history/history.manifest.mf +++ b/src/net/java/sip/communicator/impl/history/history.manifest.mf @@ -5,8 +5,8 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.fileaccess, + org.jitsi.service.configuration, + org.jitsi.service.fileaccess, net.java.sip.communicator.service.history, net.java.sip.communicator.service.history.records, org.w3c.dom, diff --git a/src/net/java/sip/communicator/impl/keybindings/KeybindingsActivator.java b/src/net/java/sip/communicator/impl/keybindings/KeybindingsActivator.java index aad960a16..f8ca35755 100644 --- a/src/net/java/sip/communicator/impl/keybindings/KeybindingsActivator.java +++ b/src/net/java/sip/communicator/impl/keybindings/KeybindingsActivator.java @@ -6,11 +6,11 @@ */ package net.java.sip.communicator.impl.keybindings; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.keybindings.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/keybindings/KeybindingsServiceImpl.java b/src/net/java/sip/communicator/impl/keybindings/KeybindingsServiceImpl.java index 35efb39ff..d294166f2 100644 --- a/src/net/java/sip/communicator/impl/keybindings/KeybindingsServiceImpl.java +++ b/src/net/java/sip/communicator/impl/keybindings/KeybindingsServiceImpl.java @@ -10,17 +10,18 @@ import java.io.*; import java.text.*; import java.util.*; -import java.util.List; //disambiguation +import java.util.List; import javax.swing.*; -import org.osgi.framework.*; - -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.fileaccess.*; import net.java.sip.communicator.service.keybindings.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.fileaccess.*; +import org.osgi.framework.*; +//disambiguation + /** * Service that concerns keybinding mappings used by various parts of the UI. * Persistence is handled as follows when started: diff --git a/src/net/java/sip/communicator/impl/keybindings/keybindings.manifest.mf b/src/net/java/sip/communicator/impl/keybindings/keybindings.manifest.mf index 278a3c998..716b666ee 100644 --- a/src/net/java/sip/communicator/impl/keybindings/keybindings.manifest.mf +++ b/src/net/java/sip/communicator/impl/keybindings/keybindings.manifest.mf @@ -6,9 +6,9 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.util, - net.java.sip.communicator.service.fileaccess, + org.jitsi.service.fileaccess, net.java.sip.communicator.service.gui, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, javax.swing Export-Package: net.java.sip.communicator.service.keybindings diff --git a/src/net/java/sip/communicator/impl/ldap/LdapActivator.java b/src/net/java/sip/communicator/impl/ldap/LdapActivator.java index 23f691e36..d47f3e1bd 100644 --- a/src/net/java/sip/communicator/impl/ldap/LdapActivator.java +++ b/src/net/java/sip/communicator/impl/ldap/LdapActivator.java @@ -6,16 +6,15 @@ */ package net.java.sip.communicator.impl.ldap; -import java.util.HashMap; -import java.util.Map; +import java.util.*; -import org.osgi.framework.*; - -import net.java.sip.communicator.util.*; -import net.java.sip.communicator.service.contactsource.ContactSourceService; +import net.java.sip.communicator.service.contactsource.*; import net.java.sip.communicator.service.ldap.*; -import net.java.sip.communicator.service.protocol.PhoneNumberI18nService; -import net.java.sip.communicator.service.resources.ResourceManagementService; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.*; + +import org.jitsi.service.resources.*; +import org.osgi.framework.*; /** * Activates the LdapService diff --git a/src/net/java/sip/communicator/impl/ldap/LdapDirectorySetImpl.java b/src/net/java/sip/communicator/impl/ldap/LdapDirectorySetImpl.java index 2631fc2ed..734921986 100644 --- a/src/net/java/sip/communicator/impl/ldap/LdapDirectorySetImpl.java +++ b/src/net/java/sip/communicator/impl/ldap/LdapDirectorySetImpl.java @@ -9,7 +9,7 @@ import java.util.*; import net.java.sip.communicator.util.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.ldap.*; import net.java.sip.communicator.service.ldap.event.*; diff --git a/src/net/java/sip/communicator/impl/ldap/LdapDirectorySettingsImpl.java b/src/net/java/sip/communicator/impl/ldap/LdapDirectorySettingsImpl.java index b30093d4c..940772a38 100644 --- a/src/net/java/sip/communicator/impl/ldap/LdapDirectorySettingsImpl.java +++ b/src/net/java/sip/communicator/impl/ldap/LdapDirectorySettingsImpl.java @@ -8,7 +8,7 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.credentialsstorage.*; import net.java.sip.communicator.service.ldap.*; diff --git a/src/net/java/sip/communicator/impl/ldap/LdapServiceImpl.java b/src/net/java/sip/communicator/impl/ldap/LdapServiceImpl.java index 9791f4e42..da18a0783 100644 --- a/src/net/java/sip/communicator/impl/ldap/LdapServiceImpl.java +++ b/src/net/java/sip/communicator/impl/ldap/LdapServiceImpl.java @@ -11,7 +11,7 @@ import org.osgi.framework.*; import net.java.sip.communicator.service.certificate.CertificateService; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.contactsource.ContactSourceService; import net.java.sip.communicator.service.credentialsstorage.*; import net.java.sip.communicator.service.ldap.*; diff --git a/src/net/java/sip/communicator/impl/ldap/ldap.manifest.mf b/src/net/java/sip/communicator/impl/ldap/ldap.manifest.mf index 248ca893b..4bd450d3e 100644 --- a/src/net/java/sip/communicator/impl/ldap/ldap.manifest.mf +++ b/src/net/java/sip/communicator/impl/ldap/ldap.manifest.mf @@ -12,14 +12,14 @@ Import-Package: org.osgi.framework, javax.net.ssl, net.java.sip.communicator.util, net.java.sip.communicator.service.certificate, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.credentialsstorage, net.java.sip.communicator.service.ldap, net.java.sip.communicator.service.ldap.event, net.java.sip.communicator.service.contactsource, net.java.sip.communicator.service.protocol, net.java.sip.communicator.util.swing, - net.java.sip.communicator.service.resources + org.jitsi.service.resources, net.java.sip.communicator.service.resources Export-Package: net.java.sip.communicator.service.ldap, net.java.sip.communicator.service.ldap.event Metadata-Location: /net/java/sip/communicator/impl/ldap/ldap.metadata.xml diff --git a/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java b/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java index 563cf4646..3eb3c5bf5 100644 --- a/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java +++ b/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java @@ -6,14 +6,11 @@ */ package net.java.sip.communicator.impl.msghistory; +import java.beans.*; import java.io.*; import java.util.*; -import java.beans.*; - -import org.osgi.framework.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.contactlist.*; import net.java.sip.communicator.service.history.*; import net.java.sip.communicator.service.history.event.*; @@ -25,6 +22,9 @@ import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; +import org.osgi.framework.*; + /** * The Message History Service stores messages exchanged through the various * protocols diff --git a/src/net/java/sip/communicator/impl/msghistory/msghistory.manifest.mf b/src/net/java/sip/communicator/impl/msghistory/msghistory.manifest.mf index e2733eefe..e6379edba 100644 --- a/src/net/java/sip/communicator/impl/msghistory/msghistory.manifest.mf +++ b/src/net/java/sip/communicator/impl/msghistory/msghistory.manifest.mf @@ -5,9 +5,9 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, - net.java.sip.communicator.service.fileaccess, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, + org.jitsi.service.fileaccess, net.java.sip.communicator.service.history, net.java.sip.communicator.service.history.event, net.java.sip.communicator.service.msghistory, diff --git a/src/net/java/sip/communicator/impl/neomedia/AbstractRTPConnector.java b/src/net/java/sip/communicator/impl/neomedia/AbstractRTPConnector.java deleted file mode 100755 index 931e9ca19..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/AbstractRTPConnector.java +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.io.*; -import java.net.*; - -import javax.media.rtp.*; - -import net.java.sip.communicator.service.neomedia.*; - -/** - * Provides a base/default implementation of RTPConnector which has - * factory methods for its control and data input and output streams and has an - * associated StreamConnector. - * - * @author Bing SU (nova.su@gmail.com) - * @author Lyubomir Marinov - */ -public abstract class AbstractRTPConnector - implements RTPConnector -{ - /** - * The pair of datagram sockets for RTP and RTCP traffic that this instance - * uses in the form of a StreamConnector. - */ - protected final StreamConnector connector; - - /** - * RTCP packet input stream used by RTPManager. - */ - private RTPConnectorInputStream controlInputStream; - - /** - * RTCP packet output stream used by RTPManager. - */ - private RTPConnectorOutputStream controlOutputStream; - - /** - * RTP packet input stream used by RTPManager. - */ - private RTPConnectorInputStream dataInputStream; - - /** - * RTP packet output stream used by RTPManager. - */ - private RTPConnectorOutputStream dataOutputStream; - - /** - * Initializes a new AbstractRTPConnector which is to use a given - * pair of datagram sockets for RTP and RTCP traffic specified in the form - * of a StreamConnector. - * - * @param connector the pair of datagram sockets for RTP and RTCP traffic - * the new instance is to use - */ - public AbstractRTPConnector(StreamConnector connector) - { - if (connector == null) - throw new NullPointerException("connector"); - - this.connector = connector; - } - - /** - * Add a stream target. A stream target is the destination address which - * this RTP session will send its data to. For a single session, we can add - * multiple SessionAddresses, and for each address, one copy of data will be - * sent to. - * - * @param target Destination target address - * @throws IOException if there was a socket-related error while adding the - * specified target - */ - public void addTarget(SessionAddress target) - throws IOException - { - InetAddress controlAddress = target.getControlAddress(); - - if (controlAddress != null) - { - getControlOutputStream() - .addTarget( - controlAddress, - target.getControlPort()); - } - - getDataOutputStream() - .addTarget( - target.getDataAddress(), - target.getDataPort()); - } - - /** - * Closes all sockets, stream, and the StreamConnector that this - * RTPConnector is using. - */ - public void close() - { - if (dataOutputStream != null) - { - dataOutputStream.close(); - dataOutputStream = null; - } - if (controlOutputStream != null) - { - controlOutputStream.close(); - controlOutputStream = null; - } - if (dataInputStream != null) - { - dataInputStream.close(); - dataInputStream = null; - } - if (controlInputStream != null) - { - controlInputStream.close(); - controlInputStream = null; - } - - connector.close(); - } - - /** - * Creates the RTCP packet input stream to be used by RTPManager. - * - * @return a new RTCP packet input stream to be used by RTPManager - * @throws IOException if an error occurs during the creation of the RTCP - * packet input stream - */ - protected abstract RTPConnectorInputStream createControlInputStream() - throws IOException; - - /** - * Creates the RTCP packet output stream to be used by RTPManager. - * - * @return a new RTCP packet output stream to be used by RTPManager - * @throws IOException if an error occurs during the creation of the RTCP - * packet output stream - */ - protected abstract RTPConnectorOutputStream createControlOutputStream() - throws IOException; - - /** - * Creates the RTP packet input stream to be used by RTPManager. - * - * @return a new RTP packet input stream to be used by RTPManager - * @throws IOException if an error occurs during the creation of the RTP - * packet input stream - */ - protected abstract RTPConnectorInputStream createDataInputStream() - throws IOException; - - /** - * Creates the RTP packet output stream to be used by RTPManager. - * - * @return a new RTP packet output stream to be used by RTPManager - * @throws IOException if an error occurs during the creation of the RTP - * packet output stream - */ - protected abstract RTPConnectorOutputStream createDataOutputStream() - throws IOException; - - /** - * Gets the StreamConnector which represents the pair of datagram - * sockets for RTP and RTCP traffic used by this instance. - * - * @return the StreamConnector which represents the pair of - * datagram sockets for RTP and RTCP traffic used by this instance - */ - public final StreamConnector getConnector() - { - return connector; - } - - /** - * Returns the input stream that is handling incoming RTCP packets. - * - * @return the input stream that is handling incoming RTCP packets. - * - * @throws IOException if an error occurs during the creation of the RTCP - * packet input stream - */ - public RTPConnectorInputStream getControlInputStream() - throws IOException - { - return getControlInputStream(true); - } - - /** - * Gets the PushSourceStream which gives access to the RTCP data - * received from the remote targets and optionally creates it if it does not - * exist yet. - * - * @param create true to create the PushSourceStream which - * gives access to the RTCP data received from the remote targets if it does - * not exist yet; otherwise, false - * @return the PushBufferStream which gives access to the RTCP data - * received from the remote targets; null if it does not exist yet - * and create is false - * @throws IOException if creating the PushSourceStream fails - */ - protected RTPConnectorInputStream getControlInputStream(boolean create) - throws IOException - { - if ((controlInputStream == null) && create) - controlInputStream = createControlInputStream(); - return controlInputStream; - } - - /** - * Returns the input stream that is handling outgoing RTCP packets. - * - * @return the input stream that is handling outgoing RTCP packets. - * - * @throws IOException if an error occurs during the creation of the RTCP - * packet output stream - */ - public RTPConnectorOutputStream getControlOutputStream() - throws IOException - { - return getControlOutputStream(true); - } - - /** - * Gets the OutputDataStream which is used to write RTCP data to be - * sent to from the remote targets and optionally creates it if it does not - * exist yet. - * - * @param create true to create the OutputDataStream which - * is to be used to write RTCP data to be sent to the remote targets if it - * does not exist yet; otherwise, false - * @return the OutputDataStream which is used to write RTCP data to - * be sent to the remote targets; null if it does not exist yet and - * create is false - * @throws IOException if creating the OutputDataStream fails - */ - protected RTPConnectorOutputStream getControlOutputStream(boolean create) - throws IOException - { - if ((controlOutputStream == null) && create) - controlOutputStream = createControlOutputStream(); - return controlOutputStream; - } - - /** - * Returns the input stream that is handling incoming RTP packets. - * - * @return the input stream that is handling incoming RTP packets. - * - * @throws IOException if an error occurs during the creation of the RTP - * packet input stream - */ - public RTPConnectorInputStream getDataInputStream() - throws IOException - { - return getDataInputStream(true); - } - - /** - * Gets the PushSourceStream which gives access to the RTP data - * received from the remote targets and optionally creates it if it does not - * exist yet. - * - * @param create true to create the PushSourceStream which - * gives access to the RTP data received from the remote targets if it does - * not exist yet; otherwise, false - * @return the PushBufferStream which gives access to the RTP data - * received from the remote targets; null if it does not exist yet - * and create is false - * @throws IOException if creating the PushSourceStream fails - */ - protected RTPConnectorInputStream getDataInputStream(boolean create) - throws IOException - { - if ((dataInputStream == null) && create) - dataInputStream = createDataInputStream(); - return dataInputStream; - } - - /** - * Returns the input stream that is handling outgoing RTP packets. - * - * @return the input stream that is handling outgoing RTP packets. - * - * @throws IOException if an error occurs during the creation of the RTP - */ - public RTPConnectorOutputStream getDataOutputStream() - throws IOException - { - return getDataOutputStream(true); - } - - /** - * Gets the OutputDataStream which is used to write RTP data to be - * sent to from the remote targets and optionally creates it if it does not - * exist yet. - * - * @param create true to create the OutputDataStream which - * is to be used to write RTP data to be sent to the remote targets if it - * does not exist yet; otherwise, false - * @return the OutputDataStream which is used to write RTP data to - * be sent to the remote targets; null if it does not exist yet and - * create is false - * @throws IOException if creating the OutputDataStream fails - */ - public RTPConnectorOutputStream getDataOutputStream(boolean create) - throws IOException - { - if ((dataOutputStream == null) && create) - dataOutputStream = createDataOutputStream(); - return dataOutputStream; - } - - /** - * Provides a dummy implementation to {@link - * RTPConnector#getReceiveBufferSize()} that always returns -1. - */ - public int getReceiveBufferSize() - { - // Not applicable - return -1; - } - - /** - * Provides a dummy implementation to {@link - * RTPConnector#getRTCPBandwidthFraction()} that always returns -1. - */ - public double getRTCPBandwidthFraction() - { - // Not applicable - return -1; - } - - /** - * Provides a dummy implementation to {@link - * RTPConnector#getRTCPSenderBandwidthFraction()} that always returns - * -1. - */ - public double getRTCPSenderBandwidthFraction() - { - // Not applicable - return -1; - } - - /** - * Provides a dummy implementation to {@link - * RTPConnector#getSendBufferSize()} that always returns -1. - */ - public int getSendBufferSize() - { - // Not applicable - return -1; - } - - /** - * Removes a target from our session. If a target is removed, there will be - * no data sent to that address. - * - * @param target Destination target to be removed - */ - public void removeTarget(SessionAddress target) - { - if (controlOutputStream != null) - controlOutputStream - .removeTarget( - target.getControlAddress(), - target.getControlPort()); - - if (dataOutputStream != null) - dataOutputStream - .removeTarget( - target.getDataAddress(), - target.getDataPort()); - } - - /** - * Remove all stream targets. After this operation is done. There will be - * no targets receiving data, so no data will be sent. - */ - public void removeTargets() - { - if (controlOutputStream != null) - controlOutputStream.removeTargets(); - - if (dataOutputStream != null) - dataOutputStream.removeTargets(); - } - - /** - * Provides a dummy implementation to {@link - * RTPConnector#setReceiveBufferSize(int)}. - * - * @param size ignored. - */ - public void setReceiveBufferSize(int size) - throws IOException - { - // Nothing should be done here :-) - } - - /** - * Provides a dummy implementation to {@link - * RTPConnector#setSendBufferSize(int)}. - * - * @param size ignored. - */ - public void setSendBufferSize(int size) - throws IOException - { - // Nothing should be done here :-) - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/AbstractVolumeControl.java b/src/net/java/sip/communicator/impl/neomedia/AbstractVolumeControl.java deleted file mode 100644 index 3b8a9eeca..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/AbstractVolumeControl.java +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.awt.*; -import java.lang.ref.*; -import java.util.*; -import java.util.List; - -import javax.media.*; - -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.event.*; -import net.java.sip.communicator.util.*; - -/** - * Controls media service volume input or output. If a playback volume level - * is set we change it on all current players, as we synchronize volume - * on all players. Implements interface exposed from media service, also - * implements the interface used in the Renderer part of JMF and merges the two - * functionalities to work as one. - * - * @author Damian Minkov - * @author Lyubomir Marinov - */ -public class AbstractVolumeControl - implements VolumeControl, - GainControl -{ - /** - * The Logger used by the VolumeControlImpl class and - * its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(AbstractVolumeControl.class); - - /** - * The minimum volume level accepted by AbstractVolumeControl. - */ - private static final float MIN_VOLUME_LEVEL = 0.0F; - - /** - * The minimum volume level expressed in percent accepted by - * AbstractVolumeControl. - */ - public static final int MIN_VOLUME_PERCENT = 0; - - /** - * The maximum volume level accepted by AbstractVolumeControl. - */ - private static final float MAX_VOLUME_LEVEL = 1.0F; - - /** - * The maximum volume level expressed in percent accepted by - * AbstractVolumeControl. - */ - public static final int MAX_VOLUME_PERCENT = 200; - - /** - * The default volume level. - */ - private static final float DEFAULT_VOLUME_LEVEL - = MIN_VOLUME_LEVEL - + (MAX_VOLUME_LEVEL - MIN_VOLUME_LEVEL) - / ((MAX_VOLUME_PERCENT - MIN_VOLUME_PERCENT) / 100); - - /** - * The VolumeChangeListeners interested in volume change events - * through the VolumeControl interface. - *

- * Because the instances of AbstractVolumeControl are global at the - * time of this writing and, consequently, they cause the - * VolumeChangeListeners to be leaked, the listeners are referenced - * using WeakReferences. - *

- */ - private final List> - volumeChangeListeners - = new ArrayList>(); - - /** - * Listeners interested in volume change inside FMJ/JMF. - */ - private List gainChangeListeners; - - /** - * The current volume level. - */ - private float volumeLevel = DEFAULT_VOLUME_LEVEL; - - /** - * Current mute state, by default we start unmuted. - */ - private boolean mute = false; - - /** - * Current level in db. - */ - private float db; - - /** - * The initial volume level, when this instance was created. - */ - private final float initialVolumeLevel; - - /** - * The name of the configuration property which specifies the value of the - * volume level of this AbstractVolumeControl. - */ - private final String volumeLevelConfigurationPropertyName; - - /** - * Creates volume control instance and initializes initial level value - * if stored in the configuration service. - * - * @param volumeLevelConfigurationPropertyName the name of the configuration - * property which specifies the value of the volume level of the new - * instance - */ - public AbstractVolumeControl( - String volumeLevelConfigurationPropertyName) - { - this.volumeLevelConfigurationPropertyName - = volumeLevelConfigurationPropertyName; - - // Read the initial volume level from the ConfigurationService. - float initialVolumeLevel = DEFAULT_VOLUME_LEVEL; - - try - { - ConfigurationService cfg - = NeomediaActivator.getConfigurationService(); - - if (cfg != null) - { - String initialVolumeLevelString - = cfg.getString(this.volumeLevelConfigurationPropertyName); - - if (initialVolumeLevelString != null) - { - initialVolumeLevel - = Float.parseFloat(initialVolumeLevelString); - if(logger.isDebugEnabled()) - { - logger.debug( - "Restored volume: " + initialVolumeLevelString); - } - } - } - } - catch (Throwable t) - { - logger.warn("Error restoring volume", t); - } - - this.initialVolumeLevel = initialVolumeLevel; - this.volumeLevel = this.initialVolumeLevel; - } - - /** - * Applies the gain specified by gainControl to the signal defined - * by the length number of samples given in buffer - * starting at offset. - * - * @param gainControl the GainControl which specifies the gain to - * apply - * @param buffer the samples of the signal to apply the gain to - * @param offset the start of the samples of the signal in buffer - * @param length the number of samples of the signal given in - * buffer - */ - public static void applyGain( - GainControl gainControl, - byte[] buffer, int offset, int length) - { - if (gainControl.getMute()) - Arrays.fill(buffer, offset, offset + length, (byte) 0); - else - { - // Assign a maximum of MAX_VOLUME_PERCENT to the volume scale. - float level = gainControl.getLevel() * (MAX_VOLUME_PERCENT / 100); - - if (level != 1) - { - for (int i = offset, toIndex = offset + length; - i < toIndex; - i += 2) - { - int i1 = i + 1; - short s = (short) ((buffer[i] & 0xff) | (buffer[i1] << 8)); - - /* Clip, don't wrap. */ - int si = s; - - si = (int) (si * level); - if (si > Short.MAX_VALUE) - s = Short.MAX_VALUE; - else if (si < Short.MIN_VALUE) - s = Short.MIN_VALUE; - else - s = (short) si; - - buffer[i] = (byte) s; - buffer[i1] = (byte) (s >> 8); - } - } - } - } - - /** - * Current volume value. - * - * @return the current volume level. - * - * @see net.java.sip.communicator.service.neomedia.VolumeControl - */ - public float getVolume() - { - return volumeLevel; - } - - /** - * Get the current gain set for this - * object as a value between 0.0 and 1.0 - * - * @return The gain in the level scale (0.0-1.0). - * - * @see javax.media.GainControl - */ - public float getLevel() - { - return volumeLevel; - } - - /** - * Returns the minimum allowed volume value. - * - * @return the minimum allowed volume value. - * - * @see net.java.sip.communicator.service.neomedia.VolumeControl - */ - public float getMinValue() - { - return MIN_VOLUME_LEVEL; - } - - /** - * Returns the maximum allowed volume value. - * - * @return the maximum allowed volume value. - * - * @see net.java.sip.communicator.service.neomedia.VolumeControl - */ - public float getMaxValue() - { - return MAX_VOLUME_LEVEL; - } - - /** - * Changes volume level. - * - * @param value the new level to set. - * @return the actual level which was set. - * - * @see net.java.sip.communicator.service.neomedia.VolumeControl - */ - public float setVolume(float value) - { - return this.setVolumeLevel(value); - } - - /** - * Set the gain using a floating point scale - * with values between 0.0 and 1.0. - * 0.0 is silence; 1.0 is the loudest - * useful level that this GainControl supports. - * - * @param level The new gain value specified in the level scale. - * @return The level that was actually set. - * - * @see javax.media.GainControl - */ - public float setLevel(float level) - { - return this.setVolumeLevel(level); - } - - /** - * Internal implementation combining setting level from JMF - * and from outside Media Service. - * - * @param value the new value, changed if different from current - * volume settings. - * @return the value that was changed or just the current one if - * the same. - */ - private float setVolumeLevel(float value) - { - if (value < MIN_VOLUME_LEVEL) - value = MIN_VOLUME_LEVEL; - else if (value > MAX_VOLUME_LEVEL) - value = MAX_VOLUME_LEVEL; - - if (volumeLevel == value) - return value; - - volumeLevel = value; - fireVolumeChange(); - - /* - * Save the current volume level in the ConfigurationService so that we - * can restore it on the next application run. - */ - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - - if (cfg != null) - { - cfg.setProperty( - this.volumeLevelConfigurationPropertyName, - String.valueOf(volumeLevel)); - } - - float f1 = value / initialVolumeLevel; - - db - = (float) - ((Math.log(((double)f1 != 0.0D) ? f1 : 0.0001D) - / Math.log(10D)) - * 20D); - fireGainEvents(); - - return volumeLevel; - } - - /** - * Mutes current sound. - * - * @param mute mutes/unmutes. - */ - public void setMute(boolean mute) - { - if (this.mute != mute) - { - this.mute = mute; - - fireVolumeChange(); - fireGainEvents(); - } - } - - /** - * Get mute state of sound. - * - * @return mute state of sound. - */ - public boolean getMute() - { - return mute; - } - - /** - * Set the gain in decibels. - * Setting the gain to 0.0 (the default) implies that the audio - * signal is neither amplified nor attenuated. - * Positive values amplify the audio signal and negative values attenuate - * the signal. - * - * @param gain The new gain in dB. - * @return The gain that was actually set. - * - * @see javax.media.GainControl - */ - public float setDB(float gain) - { - if(this.db != gain) - { - this.db = gain; - - float f1 = (float)Math.pow(10D, (double)this.db / 20D); - float volumeLevel = f1 * this.initialVolumeLevel; - - setVolumeLevel(volumeLevel); - } - return this.db; - } - - /** - * Get the current gain set for this object in dB. - * @return The gain in dB. - */ - public float getDB() - { - return this.db; - } - - /** - * Register for gain change update events. - * A GainChangeEvent is posted when the state - * of the GainControl changes. - * - * @param listener The object to deliver events to. - */ - public void addGainChangeListener(GainChangeListener listener) - { - if(listener != null) - { - if(gainChangeListeners == null) - gainChangeListeners = new ArrayList(); - gainChangeListeners.add(listener); - } - } - - /** - * Remove interest in gain change update events. - * - * @param listener The object that has been receiving events. - */ - public void removeGainChangeListener(GainChangeListener listener) - { - if(listener != null && gainChangeListeners != null) - gainChangeListeners.remove(listener); - } - - /** - * Adds a VolumeChangeListener to be informed for any change - * in the volume levels. - * - * @param listener volume change listener. - */ - public void addVolumeChangeListener(VolumeChangeListener listener) - { - synchronized (volumeChangeListeners) - { - Iterator> i - = volumeChangeListeners.iterator(); - boolean contains = false; - - while (i.hasNext()) - { - VolumeChangeListener l = i.next().get(); - - if (l == null) - i.remove(); - else if (l.equals(listener)) - contains = true; - } - if(!contains) - volumeChangeListeners.add( - new WeakReference(listener)); - } - } - - /** - * Removes a VolumeChangeListener. - * - * @param listener the volume change listener to be removed. - */ - public void removeVolumeChangeListener(VolumeChangeListener listener) - { - synchronized (volumeChangeListeners) - { - Iterator> i - = volumeChangeListeners.iterator(); - - while (i.hasNext()) - { - VolumeChangeListener l = i.next().get(); - - if ((l == null) || l.equals(listener)) - i.remove(); - } - } - } - - /** - * Fire a change in volume to interested listeners. - */ - private void fireVolumeChange() - { - List ls; - - synchronized (volumeChangeListeners) - { - Iterator> i - = volumeChangeListeners.iterator(); - - ls - = new ArrayList( - volumeChangeListeners.size()); - while (i.hasNext()) - { - VolumeChangeListener l = i.next().get(); - - if (l == null) - i.remove(); - else - ls.add(l); - } - } - - VolumeChangeEvent changeEvent - = new VolumeChangeEvent(this, volumeLevel, mute); - - for(VolumeChangeListener l : ls) - l.volumeChange(changeEvent); - } - - /** - * Fire events informing for our current state. - */ - private void fireGainEvents() - { - if(gainChangeListeners != null) - { - GainChangeEvent gainchangeevent - = new GainChangeEvent(this, mute, db, volumeLevel); - - for(GainChangeListener gainchangelistener : gainChangeListeners) - gainchangelistener.gainChange(gainchangeevent); - } - } - - /** - * Not used. - * @return null - */ - public Component getControlComponent() - { - return null; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/ArrayIOUtils.java b/src/net/java/sip/communicator/impl/neomedia/ArrayIOUtils.java deleted file mode 100644 index 78bef257e..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/ArrayIOUtils.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -/** - * Implements functionality aiding the reading and writing in little endian of - * byte arrays and primitive types such as short. - * - * @author Lyubomir Marinov - */ -public class ArrayIOUtils -{ - - /** - * Reads a short integer from a specific series of bytes starting the - * reading at a specific offset in it. The difference with - * {@link #readShort(byte[], int)} is that the read short integer is an - * int which has been formed by reading two bytes, not a - * short. - * - * @param input the series of bytes to read the short integer from - * @param inputOffset the offset in input at which the reading of - * the short integer is to start - * @return a short integer in the form of int read from the - * specified series of bytes starting at the specified offset in it - */ - public static int readInt16(byte[] input, int inputOffset) - { - return ((input[inputOffset + 1] << 8) | (input[inputOffset] & 0x00FF)); - } - - /** - * Reads a short integer from a specific series of bytes starting the - * reading at a specific offset in it. - * - * @param input the series of bytes to read the short integer from - * @param inputOffset the offset in input at which the reading of - * the short integer is to start - * @return a short integer in the form of short read from the - * specified series of bytes starting at the specified offset in it - */ - public static short readShort(byte[] input, int inputOffset) - { - return - (short) - ((input[inputOffset + 1] << 8) - | (input[inputOffset] & 0x00FF)); - } - - /** - * Converts a short integer to a series of bytes and writes the result into - * a specific output array of bytes starting the writing at a specific - * offset in it. The difference with {@link #writeShort(short, byte[], int)} - * is that the input is an int and just two bytes of it are - * written. - * - * @param input the short integer to be written out as a series of bytes - * specified as an integer i.e. the value to be converted is contained in - * only two of the four bytes made available by the integer - * @param output the output to receive the conversion of the specified short - * integer to a series of bytes - * @param outputOffset the offset in output at which the writing of - * the result of the conversion is to be started - */ - public static void writeInt16(int input, byte[] output, int outputOffset) - { - output[outputOffset] = (byte) (input & 0xFF); - output[outputOffset + 1] = (byte) (input >> 8); - } - - /** - * Converts a short integer to a series of bytes and writes the result into - * a specific output array of bytes starting the writing at a specific - * offset in it. - * - * @param input the short integer to be written out as a series of bytes - * specified as short - * @param output the output to receive the conversion of the specified short - * integer to a series of bytes - * @param outputOffset the offset in output at which the writing of - * the result of the conversion is to be started - */ - public static void writeShort(short input, byte[] output, int outputOffset) - { - writeInt16(input, output, outputOffset); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/AudioMediaStreamImpl.java b/src/net/java/sip/communicator/impl/neomedia/AudioMediaStreamImpl.java deleted file mode 100644 index 1717c978c..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/AudioMediaStreamImpl.java +++ /dev/null @@ -1,484 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.util.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.impl.neomedia.transform.dtmf.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.event.*; -import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.util.*; - -/** - * Extends MediaStreamImpl in order to provide an implementation of - * AudioMediaStream. - * - * @author Lyubomir Marinov - * @author Emil Ivov - */ -public class AudioMediaStreamImpl - extends MediaStreamImpl - implements AudioMediaStream -{ - - /** - * The Logger used by the AudioMediaStreamImpl class and - * its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(AudioMediaStreamImpl.class); - - /** - * The transformer that we use for sending and receiving DTMF packets. - */ - private DtmfTransformEngine dtmfTransfrmEngine ; - - /** - * List of DTMF listeners; - */ - private List dtmfListeners = new ArrayList(); - - /** - * List of RTP format strings which are supported by SIP Communicator in - * addition to the JMF standard formats. - * - * @see #registerCustomCodecFormats(StreamRTPManager) - */ - private static final AudioFormat[] CUSTOM_CODEC_FORMATS - = new AudioFormat[] - { - /* - * these formats are specific, since RTP uses format numbers - * with no parameters. - */ - new AudioFormat( - Constants.ALAW_RTP, - 8000, - 8, - 1, - Format.NOT_SPECIFIED, - AudioFormat.SIGNED), - new AudioFormat( - Constants.G722_RTP, - 8000, - Format.NOT_SPECIFIED /* sampleSizeInBits */, - 1) - }; - - /** - * The listener that gets notified of changes in the audio level of - * remote conference participants. - */ - private CsrcAudioLevelListener csrcAudioLevelListener = null; - - /** - * Initializes a new AudioMediaStreamImpl instance which will use - * the specified MediaDevice for both capture and playback of audio - * exchanged via the specified StreamConnector. - * - * @param connector the StreamConnector the new instance is to use - * for sending and receiving audio - * @param device the MediaDevice the new instance is to use for - * both capture and playback of audio exchanged via the specified - * StreamConnector - * @param srtpControl a control which is already created, used to control - * the srtp operations. - */ - public AudioMediaStreamImpl(StreamConnector connector, - MediaDevice device, - SrtpControl srtpControl) - { - super(connector, device, srtpControl); - - if(logger.isTraceEnabled()) - logger.trace("Created Audio Stream with hashCode " + hashCode()); - } - - /** - * Performs any optional configuration on the BufferControl of the - * specified RTPManager which is to be used as the - * RTPManager of this MediaStreamImpl. - * - * @param rtpManager the RTPManager which is to be used by this - * MediaStreamImpl - * @param bufferControl the BufferControl of rtpManager on - * which any optional configuration is to be performed - */ - @Override - protected void configureRTPManagerBufferControl( - StreamRTPManager rtpManager, - BufferControl bufferControl) - { - /* - * It appears that if we don't do this managers don't play. You can try - * some other buffer size to see if you can get better smoothness. - */ - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - long bufferLength = 100; - - if (cfg != null) - { - String bufferLengthStr - = cfg.getString(PROPERTY_NAME_RECEIVE_BUFFER_LENGTH); - - try - { - if ((bufferLengthStr != null) && (bufferLengthStr.length() > 0)) - bufferLength = Long.parseLong(bufferLengthStr); - } - catch (NumberFormatException nfe) - { - logger.warn( - bufferLengthStr - + " is not a valid receive buffer length/long value", - nfe); - } - } - - bufferLength = bufferControl.setBufferLength(bufferLength); - if (logger.isTraceEnabled()) - logger.trace("Set receiver buffer length to " + bufferLength); - - bufferControl.setEnabledThreshold(true); - bufferControl.setMinimumThreshold(100); - } - - /** - * A stub that allows audio oriented streams to create and keep a reference - * to a DtmfTransformEngine. - * - * @return a DtmfTransformEngine if this is an audio oriented - * stream and null otherwise. - */ - @Override - protected DtmfTransformEngine createDtmfTransformEngine() - { - if(this.dtmfTransfrmEngine == null) - this.dtmfTransfrmEngine = new DtmfTransformEngine(this); - - return this.dtmfTransfrmEngine; - } - - /** - * Adds a DTMFListener to this AudioMediaStream which is - * to receive notifications when the remote party starts sending DTMF tones - * to us. - * - * @param listener the DTMFListener to register for notifications - * about the remote party starting sending of DTM tones to this - * AudioMediaStream - * @see AudioMediaStream#addDTMFListener(DTMFListener) - */ - public void addDTMFListener(DTMFListener listener) - { - if(!dtmfListeners.contains(listener)) - { - dtmfListeners.add(listener); - } - } - - /** - * Sets listener as the SimpleAudioLevelListener - * registered to receive notifications from our device session for changes - * in the levels of the party that's at the other end of this stream. - * - * @param listener the SimpleAudioLevelListener that we'd like to - * register or null if we want to stop stream audio level - * measurements. - */ - public void setStreamAudioLevelListener(SimpleAudioLevelListener listener) - { - getDeviceSession().setStreamAudioLevelListener(listener); - } - - /** - * Registers listener as the CsrcAudioLevelListener that - * will receive notifications for changes in the levels of conference - * participants that the remote party could be mixing. - * - * @param listener the CsrcAudioLevelListener that we'd like to - * register or null if we'd like to stop receiving notifications. - */ - public void setCsrcAudioLevelListener(CsrcAudioLevelListener listener) - { - this.csrcAudioLevelListener = listener; - } - - /** - * Registers {@link #CUSTOM_CODEC_FORMATS} with a specific - * RTPManager. - * - * @param rtpManager the RTPManager to register - * {@link #CUSTOM_CODEC_FORMATS} with - * @see MediaStreamImpl#registerCustomCodecFormats(StreamRTPManager) - */ - @Override - protected void registerCustomCodecFormats(StreamRTPManager rtpManager) - { - super.registerCustomCodecFormats(rtpManager); - - for (AudioFormat format : CUSTOM_CODEC_FORMATS) - { - if (logger.isDebugEnabled()) - logger.debug("registering format " + format + - " with RTP manager"); - - /* - * NOTE (mkoch@rowa.de): com.sun.media.rtp.RtpSessionMgr.addFormat - * leaks memory, since it stores the Format in a static Vector. - * AFAIK there is no easy way around it, but the memory impact - * should not be too bad. - */ - rtpManager.addFormat( format, - MediaUtils.getRTPPayloadType( - format.getEncoding(), format.getSampleRate())); - } - } - - /** - * Removes listener from the list of DTMFListeners - * registered with this AudioMediaStream to receive notifications - * about incoming DTMF tones. - * - * @param listener the DTMFListener to no longer be notified by - * this AudioMediaStream about incoming DTMF tones - * @see AudioMediaStream#removeDTMFListener(DTMFListener) - */ - public void removeDTMFListener(DTMFListener listener) - { - dtmfListeners.remove(listener); - } - - /** - * Starts sending the specified DTMFTone until the - * stopSendingDTMF() method is called (Excepts for INBAND DTMF, - * which stops by itself this is why where there is no need to call the - * stopSendingDTMF). Callers should keep in mind the fact that calling this - * method would most likely interrupt all audio transmission until the - * corresponding stop method is called. Also, calling this method - * successively without invoking the corresponding stop method between the - * calls will simply replace the DTMFTone from the first call with - * that from the second. - * - * @param tone the DTMFTone to start sending. - * @param dtmfMethod The kind of DTMF used (RTP, SIP-INOF or INBAND). - * - * @see AudioMediaStream#startSendingDTMF(DTMFTone, DTMFMethod) - */ - public void startSendingDTMF(DTMFTone tone, DTMFMethod dtmfMethod) - { - switch(dtmfMethod) - { - case RTP_DTMF: - if(dtmfTransfrmEngine != null) - { - DTMFRtpTone t = DTMFRtpTone.mapTone(tone); - if(t != null) - { - dtmfTransfrmEngine.startSending(t); - } - } - break; - case SIP_INFO_DTMF: - // This kind of DTMF is not manged directly by the - // OperationSetDTMFSipImpl. - break; - case INBAND_DTMF: - MediaDeviceSession deviceSession = getDeviceSession(); - - if (deviceSession != null) - { - deviceSession.addDTMF(DTMFInbandTone.mapTone(tone)); - } - break; - } - } - - /** - * Interrupts transmission of a DTMFTone started with the - * startSendingDTMF() method. Has no effect if no tone is currently - * being sent. - * - * @param dtmfMethod The kind of DTMF used (RTP, SIP-INOF or INBAND). - * - * @see AudioMediaStream#stopSendingDTMF(DTMFMethod) - */ - public void stopSendingDTMF(DTMFMethod dtmfMethod) - { - switch(dtmfMethod) - { - case RTP_DTMF: - if(dtmfTransfrmEngine != null) - { - dtmfTransfrmEngine.stopSendingDTMF(); - } - break; - case SIP_INFO_DTMF: - // The SIP-INFO DTMF is not manged directly by the - // OperationSetDTMFSipImpl. - break; - case INBAND_DTMF: - // The INBAND DTMF is send by impluse of constant duration and - // does not need to be stopped explecitely. - break; - } - } - - /** - * In addition to calling - * {@link MediaStreamImpl#addRTPExtension(byte, RTPExtension)} - * this method enables sending of CSRC audio levels. The reason we are - * doing this here rather than in the super class is that CSRC levels only - * make sense for audio streams so we don't want them enabled in any other - * kind. - * - * @param extensionID the ID assigned to rtpExtension for the - * lifetime of this stream. - * @param rtpExtension the RTPExtension that is being added to this stream. - */ - @Override - public void addRTPExtension(byte extensionID, RTPExtension rtpExtension) - { - super.addRTPExtension(extensionID, rtpExtension); - - if (RTPExtension.CSRC_AUDIO_LEVEL_URN.equals( - rtpExtension.getURI().toString())) - { - getCsrcEngine().setCsrcAudioLevelAudioLevelExtensionID( - extensionID, - rtpExtension.getDirection()); - } - } - - /** - * Sets listener as the SimpleAudioLevelListener - * registered to receive notifications from our device session for changes - * in the levels of the audio that this stream is sending out. - * - * @param listener the SimpleAudioLevelListener that we'd like to - * register or null if we want to stop local audio level - * measurements. - */ - public void setLocalUserAudioLevelListener( - SimpleAudioLevelListener listener) - { - getDeviceSession().setLocalUserAudioLevelListener(listener); - } - - /** - * Returns the MediaDeviceSession associated with this stream - * after first casting it to AudioMediaDeviceSession since this is, - * after all, an AudioMediaStreamImpl. - * - * @return the AudioMediaDeviceSession associated with this stream. - */ - @Override - public AudioMediaDeviceSession getDeviceSession() - { - return (AudioMediaDeviceSession)super.getDeviceSession(); - } - - /** - * Returns the last audio level that was measured by the underlying device - * session for the specified ssrc (where ssrc could also - * correspond to our local sync source identifier). - * - * @param ssrc the SSRC ID whose last measured audio level we'd like to - * retrieve. - * - * @return the audio level that was last measured for the specified - * ssrc or -1 if no level has been cached for that ID. - */ - public int getLastMeasuredAudioLevel(long ssrc) - { - AudioMediaDeviceSession devSession = getDeviceSession(); - - if (devSession == null) - return -1; - - if ( ssrc == getLocalSourceID() ) - return devSession.getLastMeasuredLocalUserAudioLevel(); - else - return devSession.getLastMeasuredAudioLevel(ssrc); - } - - /** - * Delivers the audioLevels map to whoever's interested. This - * method is meant for use primarily by the transform engine handling - * incoming RTP packets (currently CsrcTransformEngine). - * - * @param audioLevels a array mapping CSRC IDs to audio levels in - * consecutive elements. - */ - public void fireConferenceAudioLevelEvent(long[] audioLevels) - { - CsrcAudioLevelListener csrcAudioLevelListener - = this.csrcAudioLevelListener; - - if (csrcAudioLevelListener != null) - csrcAudioLevelListener.audioLevelsReceived(audioLevels); - } - - /** - * Delivers the DTMF tones. This - * method is meant for use primarily by the transform engine handling - * incoming RTP packets (currently DtmfTransformEngine). - * - * @param tone the new tone - * @param end is end or start of tone. - */ - public void fireDTMFEvent(DTMFRtpTone tone, boolean end) - { - Iterator iter = dtmfListeners.iterator(); - DTMFToneEvent ev = new DTMFToneEvent(this, tone); - while (iter.hasNext()) - { - DTMFListener listener = iter.next(); - if(end) - listener.dtmfToneReceptionEnded(ev); - else - listener.dtmfToneReceptionStarted(ev); - } - } - - /** - * Releases the resources allocated by this instance in the course of its - * execution and prepares it to be garbage collected. - * - * @see MediaStream#close() - */ - @Override - public void close() - { - super.close(); - - if(dtmfTransfrmEngine != null) - { - dtmfTransfrmEngine = null; - } - } - - /** - * The priority of the audio is 3, which is meant to be higher than - * other threads and higher than the video one. - * @return audio priority. - */ - @Override - protected int getPriority() - { - return 3; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/CallRecordingConfigForm.java b/src/net/java/sip/communicator/impl/neomedia/CallRecordingConfigForm.java index 3e202666e..da76fa1fd 100644 --- a/src/net/java/sip/communicator/impl/neomedia/CallRecordingConfigForm.java +++ b/src/net/java/sip/communicator/impl/neomedia/CallRecordingConfigForm.java @@ -12,12 +12,15 @@ import javax.swing.*; import javax.swing.event.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.resources.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; import net.java.sip.communicator.util.swing.*; +import org.jitsi.impl.neomedia.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.resources.*; +import org.jitsi.util.*; + /** * The saved calls management and configuration form. * diff --git a/src/net/java/sip/communicator/impl/neomedia/DeviceConfigurationComboBoxModel.java b/src/net/java/sip/communicator/impl/neomedia/DeviceConfigurationComboBoxModel.java index f5128da0d..1130c82bb 100644 --- a/src/net/java/sip/communicator/impl/neomedia/DeviceConfigurationComboBoxModel.java +++ b/src/net/java/sip/communicator/impl/neomedia/DeviceConfigurationComboBoxModel.java @@ -16,8 +16,8 @@ import javax.swing.*; import javax.swing.event.*; -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.*; +import org.jitsi.impl.neomedia.device.*; +import org.jitsi.service.neomedia.*; /** * @author Lubomir Marinov diff --git a/src/net/java/sip/communicator/impl/neomedia/EncodingConfigurationTableModel.java b/src/net/java/sip/communicator/impl/neomedia/EncodingConfigurationTableModel.java index cf8a763e2..fc2cf2e35 100644 --- a/src/net/java/sip/communicator/impl/neomedia/EncodingConfigurationTableModel.java +++ b/src/net/java/sip/communicator/impl/neomedia/EncodingConfigurationTableModel.java @@ -10,10 +10,11 @@ import javax.swing.table.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.format.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.format.*; +import org.jitsi.impl.neomedia.*; +import org.jitsi.impl.neomedia.codec.*; +import org.jitsi.impl.neomedia.format.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.format.*; /** * Implements {@link TableModel} for {@link EncodingConfiguration}. diff --git a/src/net/java/sip/communicator/impl/neomedia/MediaConfiguration.java b/src/net/java/sip/communicator/impl/neomedia/MediaConfiguration.java index f8bae0453..06bd30765 100644 --- a/src/net/java/sip/communicator/impl/neomedia/MediaConfiguration.java +++ b/src/net/java/sip/communicator/impl/neomedia/MediaConfiguration.java @@ -16,14 +16,18 @@ import javax.swing.event.*; import javax.swing.table.*; -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.event.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; +import net.java.sip.communicator.util.swing.TransparentPanel; + +import org.jitsi.impl.neomedia.*; +import org.jitsi.impl.neomedia.device.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.device.*; +import org.jitsi.service.neomedia.event.*; +import org.jitsi.service.resources.*; +import org.jitsi.util.swing.*; /** * @author Lyubomir Marinov diff --git a/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java b/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java deleted file mode 100644 index 7bf29cee3..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java +++ /dev/null @@ -1,1496 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.awt.*; -import java.awt.event.*; -import java.beans.*; -import java.io.*; -import java.util.*; -import java.util.List; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; -import javax.media.protocol.*; -import javax.swing.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.codec.video.*; -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.impl.neomedia.format.*; -import net.java.sip.communicator.impl.neomedia.transform.sdes.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.format.*; -import net.java.sip.communicator.service.resources.*; -import net.java.sip.communicator.util.*; -import net.java.sip.communicator.util.event.*; -import net.java.sip.communicator.util.swing.*; - -import org.json.*; - -import com.sun.media.util.*; - -/** - * Implements MediaService for JMF. - * - * @author Lyubomir Marinov - * @author Dmitri Melnikov - */ -public class MediaServiceImpl - extends PropertyChangeNotifier - implements MediaService -{ - /** - * The Logger used by the MediaServiceImpl class and its - * instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(MediaServiceImpl.class); - - /** - * The name of the boolean ConfigurationService property - * which indicates whether the detection of audio CaptureDevices is - * to be disabled. The default value is false i.e. the audio - * CaptureDevices are detected. - */ - public static final String DISABLE_AUDIO_SUPPORT_PNAME - = "net.java.sip.communicator.service.media.DISABLE_AUDIO_SUPPORT"; - - /** - * The name of the boolean ConfigurationService property - * which indicates whether the detection of video CaptureDevices is - * to be disabled. The default value is false i.e. the video - * CaptureDevices are detected. - */ - public static final String DISABLE_VIDEO_SUPPORT_PNAME - = "net.java.sip.communicator.service.media.DISABLE_VIDEO_SUPPORT"; - - /** - * The prefix of the property names the values of which specify the dynamic - * payload type preferences. - */ - private static final String DYNAMIC_PAYLOAD_TYPE_PREFERENCES_PNAME_PREFIX - = "net.java.sip.communicator.impl.neomedia.dynamicPayloadTypePreferences"; - - /** - * The value of the devices property of MediaServiceImpl - * when no MediaDevices are available. Explicitly defined in order - * to reduce unnecessary allocations. - */ - private static final List EMPTY_DEVICES - = Collections.emptyList(); - - /** - * The name of the System boolean property which specifies whether - * the loading of the JMF/FMJ Registry is to be disabled. - */ - private static final String JMF_REGISTRY_DISABLE_LOAD - = "net.sf.fmj.utility.JmfRegistry.disableLoad"; - - /** - * The indicator which determines whether the loading of the JMF/FMJ - * Registry is disabled. - */ - private static boolean jmfRegistryDisableLoad; - - /** - * The indicator which determined whether - * {@link #postInitializeOnce(MediaServiceImpl)} has been executed in order - * to perform one-time initialization after initializing the first instance - * of MediaServiceImpl. - */ - private static boolean postInitializeOnce; - - /** - * The CaptureDevice user choices such as the default audio and - * video capture devices. - */ - private final DeviceConfiguration deviceConfiguration - = new DeviceConfiguration(); - - /** - * The PropertyChangeListener which listens to - * {@link #deviceConfiguration}. - */ - private final PropertyChangeListener - deviceConfigurationPropertyChangeListener - = new PropertyChangeListener() - { - public void propertyChange(PropertyChangeEvent event) - { - deviceConfigurationPropertyChange(event); - } - }; - - /** - * The list of audio MediaDevices reported by this instance when - * its {@link MediaService#getDevices(MediaType, MediaUseCase)} method is - * called with an argument {@link MediaType#AUDIO}. - */ - private final List audioDevices - = new ArrayList(); - - /** - * The format-related user choices such as the enabled and disabled codecs - * and the order of their preference. - */ - private final EncodingConfiguration encodingConfiguration - = new EncodingConfiguration(); - - /** - * The MediaFormatFactory through which MediaFormat - * instances may be created for the purposes of working with the - * MediaStreams created by this MediaService. - */ - private MediaFormatFactory formatFactory; - - /** - * The one and only MediaDevice instance with - * MediaDirection not allowing sending and MediaType equal - * to AUDIO. - */ - private MediaDevice nonSendAudioDevice; - - /** - * The one and only MediaDevice instance with - * MediaDirection not allowing sending and MediaType equal - * to VIDEO. - */ - private MediaDevice nonSendVideoDevice; - - /** - * The list of video MediaDevices reported by this instance when - * its {@link MediaService#getDevices(MediaType, MediaUseCase)} method is - * called with an argument {@link MediaType#VIDEO}. - */ - private final List videoDevices - = new ArrayList(); - - /** - * A {@link Map} that binds indicates whatever preferences this - * media service implementation may have for the RTP payload type numbers - * that get dynamically assigned to {@link MediaFormat}s with no static - * payload type. The method is useful for formats such as "telephone-event" - * for example that is statically assigned the 101 payload type by some - * legacy systems. Signalling protocol implementations such as SIP and XMPP - * should make sure that, whenever this is possible, they assign to formats - * the dynamic payload type returned in this {@link Map}. - */ - private static Map dynamicPayloadTypePreferences; - - /** - * The volume control of the media service playback. - */ - private static VolumeControl outputVolumeControl; - - /** - * The volume control of the media service capture. - */ - private static VolumeControl inputVolumeControl; - - /** - * Listeners interested in Recorder events without the need to - * have access to their instances. - */ - private final List recorderListeners = - new ArrayList(); - - static - { - setupFMJ(); - } - - /** - * Initializes a new MediaServiceImpl instance. - */ - public MediaServiceImpl() - { - /* - * XXX The deviceConfiguration is initialized and referenced by this - * instance so adding deviceConfigurationPropertyChangeListener does not - * need a matching removal. - */ - deviceConfiguration.addPropertyChangeListener( - deviceConfigurationPropertyChangeListener); - - /* - * Perform one-time initialization after initializing the first instance - * of MediaServiceImpl. - */ - synchronized (MediaServiceImpl.class) - { - if (!postInitializeOnce) - { - postInitializeOnce = true; - postInitializeOnce(this); - } - } - } - - /** - * Create a MediaStream which will use a specific - * MediaDevice for capture and playback of media. The new instance - * will not have a StreamConnector at the time of its construction - * and a StreamConnector will be specified later on in order to - * enable the new instance to send and receive media. - * - * @param device the MediaDevice to be used by the new instance for - * capture and playback of media - * @return a newly-created MediaStream which will use the specified - * device for capture and playback of media - * @see MediaService#createMediaStream(MediaDevice) - */ - public MediaStream createMediaStream(MediaDevice device) - { - return createMediaStream(null, device); - } - - /** - * Creates a new MediaStream instance which will use the specified - * MediaDevice for both capture and playback of media exchanged - * via the specified StreamConnector. - * - * @param connector the StreamConnector that the new - * MediaStream instance is to use for sending and receiving media - * @param device the MediaDevice that the new MediaStream - * instance is to use for both capture and playback of media exchanged via - * the specified connector - * @return a new MediaStream instance - * @see MediaService#createMediaStream(StreamConnector, MediaDevice) - */ - public MediaStream createMediaStream( - StreamConnector connector, - MediaDevice device) - { - return createMediaStream(connector, device, null); - } - - /** - * Creates a new MediaStream instance which will use the specified - * MediaDevice for both capture and playback of media exchanged - * via the specified StreamConnector. - * - * @param connector the StreamConnector that the new - * MediaStream instance is to use for sending and receiving media - * @param device the MediaDevice that the new MediaStream - * instance is to use for both capture and playback of media exchanged via - * the specified connector - * @param srtpControl a control which is already created, used to control - * the srtp operations. - * - * @return a new MediaStream instance - * @see MediaService#createMediaStream(StreamConnector, MediaDevice) - */ - public MediaStream createMediaStream( - StreamConnector connector, - MediaDevice device, - SrtpControl srtpControl) - { - switch (device.getMediaType()) - { - case AUDIO: - return new AudioMediaStreamImpl(connector, device, srtpControl); - case VIDEO: - return new VideoMediaStreamImpl(connector, device, srtpControl); - default: - return null; - } - } - - /** - * Creates a new MediaDevice which uses a specific - * MediaDevice to capture and play back media and performs mixing - * of the captured media and the media played back by any other users of the - * returned MediaDevice. For the AUDIO MediaType, - * the returned device is commonly referred to as an audio mixer. The - * MediaType of the returned MediaDevice is the same as - * the MediaType of the specified device. - * - * @param device the MediaDevice which is to be used by the - * returned MediaDevice to actually capture and play back media - * @return a new MediaDevice instance which uses device to - * capture and play back media and performs mixing of the captured media and - * the media played back by any other users of the returned - * MediaDevice instance - * @see MediaService#createMixer(MediaDevice) - */ - public MediaDevice createMixer(MediaDevice device) - { - switch (device.getMediaType()) - { - case AUDIO: - return new AudioMixerMediaDevice((AudioMediaDeviceImpl) device); - case VIDEO: - return new VideoTranslatorMediaDevice((MediaDeviceImpl) device); - default: - /* - * TODO If we do not support mixing, should we return null or rather - * a MediaDevice with INACTIVE MediaDirection? - */ - return null; - } - } - - /** - * Gets the default MediaDevice for the specified - * MediaType. - * - * @param mediaType a MediaType value indicating the type of media - * to be handled by the MediaDevice to be obtained - * @param useCase the MediaUseCase to obtain the - * MediaDevice list for - * @return the default MediaDevice for the specified - * mediaType if such a MediaDevice exists; otherwise, - * null - * @see MediaService#getDefaultDevice(MediaType, MediaUseCase) - */ - public MediaDevice getDefaultDevice( - MediaType mediaType, - MediaUseCase useCase) - { - CaptureDeviceInfo captureDeviceInfo; - - switch (mediaType) - { - case AUDIO: - captureDeviceInfo - = getDeviceConfiguration().getAudioCaptureDevice(); - break; - case VIDEO: - captureDeviceInfo - = getDeviceConfiguration().getVideoCaptureDevice(useCase); - break; - default: - captureDeviceInfo = null; - break; - } - - MediaDevice defaultDevice = null; - - if (captureDeviceInfo != null) - { - for (MediaDevice device : getDevices(mediaType, useCase)) - { - if ((device instanceof MediaDeviceImpl) - && captureDeviceInfo.equals( - ((MediaDeviceImpl) device) - .getCaptureDeviceInfo())) - { - defaultDevice = device; - break; - } - } - } - if (defaultDevice == null) - { - switch (mediaType) - { - case AUDIO: - defaultDevice = getNonSendAudioDevice(); - break; - case VIDEO: - defaultDevice = getNonSendVideoDevice(); - break; - default: - /* - * There is no MediaDevice with direction which does not allow - * sending and mediaType other than AUDIO and VIDEO. - */ - break; - } - } - - /* - * Don't use the device in case the user has disabled all codecs for - * that kind of media. - */ - if ((defaultDevice != null) - && (defaultDevice.getSupportedFormats().isEmpty())) - { - defaultDevice = null; - } - return defaultDevice; - } - - /** - * Gets the CaptureDevice user choices such as the default audio - * and video capture devices. - * - * @return the CaptureDevice user choices such as the default audio - * and video capture devices. - */ - public DeviceConfiguration getDeviceConfiguration() - { - return deviceConfiguration; - } - - /** - * Gets a list of the MediaDevices known to this - * MediaService and handling the specified MediaType. - * - * @param mediaType the MediaType to obtain the - * MediaDevice list for - * @param useCase the MediaUseCase to obtain the - * MediaDevice list for - * @return a new List of MediaDevices known to this - * MediaService and handling the specified MediaType. The - * returned List is a copy of the internal storage and, - * consequently, modifications to it do not affect this instance. Despite - * the fact that a new List instance is returned by each call to - * this method, the MediaDevice instances are the same if they are - * still known to this MediaService to be available. - * @see MediaService#getDevices(MediaType, MediaUseCase) - */ - public List getDevices( - MediaType mediaType, - MediaUseCase useCase) - { - List cdis; - List privateDevices; - - if (MediaType.VIDEO.equals(mediaType)) - { - /* - * In case a video capture device has been added to or removed from - * system (i.e. webcam, monitor, etc.), rescan the video capture - * devices. - */ - DeviceSystem.initializeDeviceSystems(MediaType.VIDEO); - } - - switch (mediaType) - { - case AUDIO: - cdis = getDeviceConfiguration().getAvailableAudioCaptureDevices(); - privateDevices = audioDevices; - break; - case VIDEO: - cdis - = getDeviceConfiguration().getAvailableVideoCaptureDevices( - useCase); - privateDevices = videoDevices; - break; - default: - /* - * MediaService does not understand MediaTypes other than AUDIO and - * VIDEO. - */ - return EMPTY_DEVICES; - } - - List publicDevices; - - synchronized (privateDevices) - { - if ((cdis == null) - || (cdis.size() <= 0)) - privateDevices.clear(); - else - { - Iterator deviceIter - = privateDevices.iterator(); - - while (deviceIter.hasNext()) - { - Iterator cdiIter = cdis.iterator(); - CaptureDeviceInfo captureDeviceInfo - = deviceIter.next().getCaptureDeviceInfo(); - boolean deviceIsFound = false; - - while (cdiIter.hasNext()) - { - if (captureDeviceInfo.equals(cdiIter.next())) - { - deviceIsFound = true; - cdiIter.remove(); - break; - } - } - if (!deviceIsFound) - deviceIter.remove(); - } - - for (CaptureDeviceInfo cdi : cdis) - { - if (cdi == null) - continue; - - MediaDeviceImpl device; - - switch (mediaType) - { - case AUDIO: - device = new AudioMediaDeviceImpl(cdi); - break; - case VIDEO: - device - = new MediaDeviceImpl(cdi, mediaType); - break; - default: - device = null; - break; - } - if (device != null) - privateDevices.add(device); - } - } - - publicDevices = new ArrayList(privateDevices); - } - - /* - * If there are no MediaDevice instances of the specified mediaType, - * make sure that there is at least one MediaDevice which does not allow - * sending. - */ - if (publicDevices.isEmpty()) - { - MediaDevice nonSendDevice; - - switch (mediaType) - { - case AUDIO: - nonSendDevice = getNonSendAudioDevice(); - break; - case VIDEO: - nonSendDevice = getNonSendVideoDevice(); - break; - default: - /* - * There is no MediaDevice with direction not allowing sending - * and mediaType other than AUDIO and VIDEO. - */ - nonSendDevice = null; - break; - } - if (nonSendDevice != null) - publicDevices.add(nonSendDevice); - } - - return publicDevices; - } - - /** - * Gets the format-related user choices such as the enabled and disabled - * codecs and the order of their preference. - * - * @return the format-related user choices such as the enabled and disabled - * codecs and the order of their preference - */ - public EncodingConfiguration getEncodingConfiguration() - { - return encodingConfiguration; - } - - /** - * Gets the MediaFormatFactory through which MediaFormat - * instances may be created for the purposes of working with the - * MediaStreams created by this MediaService. - * - * @return the MediaFormatFactory through which - * MediaFormat instances may be created for the purposes of working - * with the MediaStreams created by this MediaService - * @see MediaService#getFormatFactory() - */ - public MediaFormatFactory getFormatFactory() - { - if (formatFactory == null) - formatFactory = new MediaFormatFactoryImpl(); - return formatFactory; - } - - /** - * Gets the one and only MediaDevice instance with - * MediaDirection not allowing sending and MediaType equal - * to AUDIO. - * - * @return the one and only MediaDevice instance with - * MediaDirection not allowing sending and MediaType equal - * to AUDIO - */ - private MediaDevice getNonSendAudioDevice() - { - if (nonSendAudioDevice == null) - nonSendAudioDevice = new AudioMediaDeviceImpl(); - return nonSendAudioDevice; - } - - /** - * Gets the one and only MediaDevice instance with - * MediaDirection not allowing sending and MediaType equal - * to VIDEO. - * - * @return the one and only MediaDevice instance with - * MediaDirection not allowing sending and MediaType equal - * to VIDEO - */ - private MediaDevice getNonSendVideoDevice() - { - if (nonSendVideoDevice == null) - nonSendVideoDevice = new MediaDeviceImpl(MediaType.VIDEO); - return nonSendVideoDevice; - } - - /** - * Initializes a new ZrtpControl instance which is to control all - * ZRTP options. - * - * @return a new ZrtpControl instance which is to control all ZRTP - * options - */ - public ZrtpControl createZrtpControl() - { - return new ZrtpControlImpl(); - } - - /** - * Initializes a new SDesControl instance which is to control all - * SDes options. - * - * @return a new SDesControl instance which is to control all SDes - * options - */ - public SDesControl createSDesControl() - { - return new SDesControlImpl(); - } - - /** - * Gets the VolumeControl which controls the volume level of audio - * output/playback. - * - * @return the VolumeControl which controls the volume level of - * audio output/playback - * @see MediaService#getOutputVolumeControl() - */ - public VolumeControl getOutputVolumeControl() - { - if (outputVolumeControl == null) - { - outputVolumeControl - = new AbstractVolumeControl( - VolumeControl.PLAYBACK_VOLUME_LEVEL_PROPERTY_NAME); - } - return outputVolumeControl; - } - - /** - * Gets the VolumeControl which controls the volume level of audio - * input/capture. - * - * @return the VolumeControl which controls the volume level of - * audio input/capture - * @see MediaService#getInputVolumeControl() - */ - public VolumeControl getInputVolumeControl() - { - if (inputVolumeControl == null) - { - inputVolumeControl - = new AbstractVolumeControl( - VolumeControl.CAPTURE_VOLUME_LEVEL_PROPERTY_NAME); - } - return inputVolumeControl; - } - - /** - * Get available screens. - * - * @return screens - */ - public List getAvailableScreenDevices() - { - ScreenDevice screens[] = ScreenDeviceImpl.getAvailableScreenDevices(); - List screenList; - - if ((screens != null) && (screens.length != 0)) - screenList = new ArrayList(Arrays.asList(screens)); - else - screenList = Collections.emptyList(); - return screenList; - } - - /** - * Get default screen device. - * - * @return default screen device - */ - public ScreenDevice getDefaultScreenDevice() - { - List screens = getAvailableScreenDevices(); - int width = 0; - int height = 0; - ScreenDevice best = null; - - for (ScreenDevice screen : screens) - { - java.awt.Dimension res = screen.getSize(); - - if ((res != null) && ((width < res.width) || (height < res.height))) - { - width = res.width; - height = res.height; - best = screen; - } - } - return best; - } - - /** - * Creates a new Recorder instance that can be used to record a - * call which captures and plays back media using a specific - * MediaDevice. - * - * @param device the MediaDevice which is used for media capture - * and playback by the call to be recorded - * @return a new Recorder instance that can be used to record a - * call which captures and plays back media using the specified - * MediaDevice - * @see MediaService#createRecorder(MediaDevice) - */ - public Recorder createRecorder(MediaDevice device) - { - if (device instanceof AudioMixerMediaDevice) - return new RecorderImpl((AudioMixerMediaDevice) device); - else - return null; - } - - /** - * Returns a {@link Map} that binds indicates whatever preferences this - * media service implementation may have for the RTP payload type numbers - * that get dynamically assigned to {@link MediaFormat}s with no static - * payload type. The method is useful for formats such as "telephone-event" - * for example that is statically assigned the 101 payload type by some - * legacy systems. Signaling protocol implementations such as SIP and XMPP - * should make sure that, whenever this is possible, they assign to formats - * the dynamic payload type returned in this {@link Map}. - * - * @return a {@link Map} binding some formats to a preferred dynamic RTP - * payload type number. - */ - public Map getDynamicPayloadTypePreferences() - { - if(dynamicPayloadTypePreferences == null) - { - dynamicPayloadTypePreferences = new HashMap(); - - /* - * Set the dynamicPayloadTypePreferences to their default values. If - * the user chooses to override them through the - * ConfigurationService, they will be overwritten later on. - */ - MediaFormat telephoneEvent - = MediaUtils.getMediaFormat("telephone-event", 8000); - if (telephoneEvent != null) - dynamicPayloadTypePreferences.put(telephoneEvent, (byte) 101); - - MediaFormat h264 - = MediaUtils.getMediaFormat( - "H264", - VideoMediaFormatImpl.DEFAULT_CLOCK_RATE); - if (h264 != null) - dynamicPayloadTypePreferences.put(h264, (byte) 99); - - /* - * Try to load dynamicPayloadTypePreferences from the - * ConfigurationService. - */ - ConfigurationService cfg - = NeomediaActivator.getConfigurationService(); - - if (cfg != null) - { - String prefix = DYNAMIC_PAYLOAD_TYPE_PREFERENCES_PNAME_PREFIX; - List propertyNames - = cfg.getPropertyNamesByPrefix(prefix, true); - - for (String propertyName : propertyNames) - { - /* - * The dynamic payload type is the name of the property name - * and the format which prefers it is the property value. - */ - byte dynamicPayloadTypePreference = 0; - Throwable exception = null; - - try - { - dynamicPayloadTypePreference - = Byte.parseByte( - propertyName.substring( - prefix.length() + 1)); - } - catch (IndexOutOfBoundsException ioobe) - { - exception = ioobe; - } - catch (NumberFormatException nfe) - { - exception = nfe; - } - if (exception != null) - { - logger.warn( - "Ignoring dynamic payload type preference" - + " which could not be parsed: " - + propertyName, - exception); - continue; - } - - String source = cfg.getString(propertyName); - - if ((source != null) && (source.length() != 0)) - { - try - { - JSONObject json = new JSONObject(source); - String encoding - = json.getString( - MediaFormatImpl.ENCODING_PNAME); - int clockRate - = json.getInt(MediaFormatImpl.CLOCK_RATE_PNAME); - Map fmtps - = new HashMap(); - - if (json.has( - MediaFormatImpl.FORMAT_PARAMETERS_PNAME)) - { - JSONObject jsonFmtps - = json.getJSONObject( - MediaFormatImpl - .FORMAT_PARAMETERS_PNAME); - Iterator jsonFmtpsIter = jsonFmtps.keys(); - - while (jsonFmtpsIter.hasNext()) - { - String key - = jsonFmtpsIter.next().toString(); - String value = jsonFmtps.getString(key); - - fmtps.put(key, value); - } - } - - MediaFormat mediaFormat - = MediaUtils.getMediaFormat( - encoding, clockRate, - fmtps); - - if (mediaFormat != null) - { - dynamicPayloadTypePreferences.put( - mediaFormat, - dynamicPayloadTypePreference); - } - } - catch (JSONException jsone) - { - logger.warn( - "Ignoring dynamic payload type preference" - + " which could not be parsed: " - + source, - jsone); - } - } - } - } - } - return dynamicPayloadTypePreferences; - } - - /** - * Creates a preview component for the specified device(video device) used - * to show video preview from that device. - * - * @param device the video device - * @param preferredWidth the width we prefer for the component - * @param preferredHeight the height we prefer for the component - * @return the preview component. - */ - public Object getVideoPreviewComponent( - MediaDevice device, - int preferredWidth, int preferredHeight) - { - ResourceManagementService resources = NeomediaActivator.getResources(); - String noPreviewText - = (resources == null) - ? "" - : resources.getI18NString("impl.media.configform.NO_PREVIEW"); - JLabel noPreview = new JLabel(noPreviewText); - - noPreview.setHorizontalAlignment(SwingConstants.CENTER); - noPreview.setVerticalAlignment(SwingConstants.CENTER); - - final JComponent videoContainer = new VideoContainer(noPreview, false); - - if ((preferredWidth > 0) && (preferredHeight > 0)) - videoContainer.setPreferredSize( - new Dimension(preferredWidth, preferredHeight)); - - try - { - CaptureDeviceInfo captureDeviceInfo; - - if ((device != null) && - ((captureDeviceInfo - = ((MediaDeviceImpl)device) - .getCaptureDeviceInfo()) - != null)) - { - DataSource dataSource - = Manager.createDataSource(captureDeviceInfo.getLocator()); - - /* - * Don't let the size be uselessly small just because the - * videoContainer has too small a preferred size. - */ - if ((preferredWidth < 128) || (preferredHeight < 96)) - { - preferredWidth = 128; - preferredHeight = 96; - } - VideoMediaStreamImpl.selectVideoSize( - dataSource, - preferredWidth, preferredHeight); - - // A Player is documented to be created on a connected - // DataSource. - dataSource.connect(); - - Processor player = Manager.createProcessor(dataSource); - final MediaLocator locator = dataSource.getLocator(); - - player.addControllerListener(new ControllerListener() - { - public void controllerUpdate(ControllerEvent event) - { - controllerUpdateForPreview( - event, - videoContainer, - locator); - } - }); - player.configure(); - } - } - catch (Throwable t) - { - if (t instanceof ThreadDeath) - throw (ThreadDeath) t; - logger.error("Failed to create video preview", t); - } - - return videoContainer; - } - - /** - * Listens and shows the video in the video container when needed. - * @param event the event when player has ready visual component. - * @param videoContainer the container. - * @param locator input DataSource locator - */ - private static void controllerUpdateForPreview( - ControllerEvent event, - JComponent videoContainer, - MediaLocator locator) - { - if (event instanceof ConfigureCompleteEvent) - { - Processor player = (Processor) event.getSourceController(); - - /* - * Use SwScaler for the scaling since it produces an image with - * better quality and add the "flip" effect to the video. - */ - TrackControl[] trackControls = player.getTrackControls(); - - if ((trackControls != null) && (trackControls.length != 0)) - try - { - for (TrackControl trackControl : trackControls) - { - Codec codecs[] = null; - SwScaler scaler = new SwScaler(); - - // do not flip desktop - if (DeviceSystem.LOCATOR_PROTOCOL_IMGSTREAMING.equals( - locator.getProtocol())) - codecs = new Codec[] { scaler }; - else - codecs = new Codec[] { new HFlip(), scaler }; - - trackControl.setCodecChain(codecs); - break; - } - } - catch (UnsupportedPlugInException upiex) - { - logger.warn( - "Failed to add SwScaler/VideoFlipEffect to " + - "codec chain", upiex); - } - - // Turn the Processor into a Player. - try - { - player.setContentDescriptor(null); - } - catch (NotConfiguredError nce) - { - logger.error( - "Failed to set ContentDescriptor of Processor", - nce); - } - - player.realize(); - } - else if (event instanceof RealizeCompleteEvent) - { - Player player = (Player) event.getSourceController(); - Component video = player.getVisualComponent(); - - showPreview(videoContainer, video, player); - } - } - - /** - * Shows the preview panel. - * @param previewContainer the container - * @param preview the preview component. - * @param player the player. - */ - private static void showPreview( - final JComponent previewContainer, - final Component preview, - final Player player) - { - if (!SwingUtilities.isEventDispatchThread()) - { - SwingUtilities.invokeLater(new Runnable() - { - public void run() - { - showPreview(previewContainer, preview, player); - } - }); - return; - } - - previewContainer.removeAll(); - - if (preview != null) - { - HierarchyListener hierarchyListener = new HierarchyListener() - { - private Window window; - - private WindowListener windowListener; - - public void dispose() - { - if (windowListener != null) - { - if (window != null) - { - window.removeWindowListener(windowListener); - window = null; - } - windowListener = null; - } - preview.removeHierarchyListener(this); - - disposePlayer(player); - - /* - * We've just disposed the player which created the preview - * component so the preview component is of no use - * regardless of whether the Media configuration form will - * be redisplayed or not. And since the preview component - * appears to be a huge object even after its player is - * disposed, make sure to not reference it. - */ - previewContainer.remove(preview); - } - - public void hierarchyChanged(HierarchyEvent event) - { - if ((event.getChangeFlags() - & HierarchyEvent.DISPLAYABILITY_CHANGED) - == 0) - return; - - if (!preview.isDisplayable()) - { - dispose(); - return; - } - else - player.start(); - - if (windowListener == null) - { - window = SwingUtilities.windowForComponent(preview); - if (window != null) - { - windowListener = new WindowAdapter() - { - @Override - public void windowClosing(WindowEvent event) - { - dispose(); - } - }; - window.addWindowListener(windowListener); - } - } - } - }; - preview.addHierarchyListener(hierarchyListener); - - previewContainer.add(preview); - - previewContainer.revalidate(); - previewContainer.repaint(); - } - else - disposePlayer(player); - } - - /** - * Dispose the player used for the preview. - * @param player the player. - */ - private static void disposePlayer(Player player) - { - player.stop(); - player.deallocate(); - player.close(); - } - - /** - * Get a MediaDevice for a part of desktop streaming/sharing. - * - * @param width width of the part - * @param height height of the part - * @param x origin of the x coordinate (relative to the full desktop) - * @param y origin of the y coordinate (relative to the full desktop) - * @return MediaDevice representing the part of desktop or null - * if problem - */ - public MediaDevice getMediaDeviceForPartialDesktopStreaming( - int width, int height, int x, int y) - { - MediaDevice device = null; - String name = "Partial desktop streaming"; - Dimension size = null; - int multiple = 0; - int tmpX = (x < 0)? 0: x; - int tmpY = (y < 0)? 0: y; - Point p = new Point(tmpX, tmpY); - ScreenDevice dev = getScreenForPoint(p); - int display = -1; - - if(dev != null) - display = dev.getIndex(); - else - return null; - - /* on Mac OS X, width have to be a multiple of 16 */ - if(OSUtils.IS_MAC) - { - multiple = Math.round(width / 16f); - width = multiple * 16; - } - else - { - /* JMF filter graph seems to not like odd width */ - multiple = Math.round(width / 2f); - width = multiple * 2; - } - - /* JMF filter graph seems to not like odd height */ - multiple = Math.round(height / 2f); - height = multiple * 2; - - size = new Dimension(width, height); - - Format formats[] = new Format[] - { - new AVFrameFormat( - size, - Format.NOT_SPECIFIED, - FFmpeg.PIX_FMT_ARGB, - Format.NOT_SPECIFIED), - new RGBFormat( - size, // size - Format.NOT_SPECIFIED, // maxDataLength - Format.byteArray, // dataType - Format.NOT_SPECIFIED, // frameRate - 32, // bitsPerPixel - 2 /* red */, - 3 /* green */, - 4 /* blue */) - }; - - Rectangle bounds = ((ScreenDeviceImpl)dev).getBounds(); - x -= bounds.x; - y -= bounds.y; - - CaptureDeviceInfo devInfo - = new CaptureDeviceInfo( - name + " " + display, - new MediaLocator( - DeviceSystem.LOCATOR_PROTOCOL_IMGSTREAMING - + ":" - + display - + "," - + x - + "," - + y), - formats); - - device = new MediaDeviceImpl(devInfo, MediaType.VIDEO); - return device; - } - - /** - * If the MediaDevice corresponds to partial desktop streaming - * device. - * - * @param mediaDevice MediaDevice - * @return true if MediaDevice is a partial desktop streaming - * device, false otherwise - */ - public boolean isPartialStreaming(MediaDevice mediaDevice) - { - MediaDeviceImpl dev = (MediaDeviceImpl)mediaDevice; - CaptureDeviceInfo devInfo = dev.getCaptureDeviceInfo(); - - return - (devInfo != null) - && devInfo.getName().startsWith("Partial desktop streaming"); - } - - /** - * Find the screen device that contains specified point. - * - * @param p point coordinates - * @return screen device that contains point - */ - public ScreenDevice getScreenForPoint(Point p) - { - for(ScreenDevice dev : getAvailableScreenDevices()) - if(dev.containsPoint(p)) - return dev; - return null; - } - - /** - * Gets the origin of a specific desktop streaming device. - * - * @param mediaDevice the desktop streaming device to get the origin on - * @return the origin of the specified desktop streaming device - */ - public Point getOriginForDesktopStreamingDevice(MediaDevice mediaDevice) - { - MediaDeviceImpl dev = (MediaDeviceImpl)mediaDevice; - CaptureDeviceInfo devInfo = dev.getCaptureDeviceInfo(); - if(devInfo == null) - return null; - MediaLocator locator = devInfo.getLocator(); - - if(!DeviceSystem.LOCATOR_PROTOCOL_IMGSTREAMING.equals( - locator.getProtocol())) - return null; - - String remainder = locator.getRemainder(); - String split[] = remainder.split(","); - int index - = Integer.parseInt( - ((split != null) && (split.length > 1)) - ? split[0] - : remainder); - - List devs = getAvailableScreenDevices(); - - if (devs.size() - 1 >= index) - { - Rectangle r = ((ScreenDeviceImpl) devs.get(index)).getBounds(); - - return new Point(r.x, r.y); - } - - return null; - } - - /** - * Those interested in Recorder events add listener through MediaService. - * This way they don't need to have access to the Recorder instance. - * Adds a new Recorder.Listener to the list of listeners - * interested in notifications from a Recorder. - * - * @param listener the new Recorder.Listener to be added to the - * list of listeners interested in notifications from Recorders. - */ - public void addRecorderListener(Recorder.Listener listener) - { - synchronized(recorderListeners) - { - if(!recorderListeners.contains(listener)) - recorderListeners.add(listener); - } - } - - /** - * Removes an existing Recorder.Listener from the list of listeners - * interested in notifications from Recorders. - * - * @param listener the existing Listener to be removed from the - * list of listeners interested in notifications from Recorders - */ - public void removeRecorderListener(Recorder.Listener listener) - { - synchronized(recorderListeners) - { - recorderListeners.remove(listener); - } - } - - /** - * Gives access to currently registered Recorder.Listeners. - * @return currently registered Recorder.Listeners. - */ - public Iterator getRecorderListeners() - { - return recorderListeners.iterator(); - } - - /** - * Notifies this instance that the value of a property of - * {@link #deviceConfiguration} has changed. - * - * @param event a PropertyChangeEvent which specifies the name of - * the property which had its value changed and the old and the new values - * of that property - */ - private void deviceConfigurationPropertyChange(PropertyChangeEvent event) - { - String propertyName = event.getPropertyName(); - - if (DeviceConfiguration.AUDIO_CAPTURE_DEVICE.equals(propertyName) - || DeviceConfiguration.VIDEO_CAPTURE_DEVICE.equals( - propertyName)) - { - /* - * We do not know the old value of the property at the time of this - * writing. We cannot report the new value either because we do not - * know the MediaType and the MediaUseCase. - */ - firePropertyChange(DEFAULT_DEVICE, null, null); - } - } - - /** - * Initializes a new RTPTranslator which is to forward RTP and RTCP - * traffic between multiple MediaStreams. - * - * @return a new RTPTranslator which is to forward RTP and RTCP - * traffic between multiple MediaStreams - * @see MediaService#createRTPTranslator() - */ - public RTPTranslator createRTPTranslator() - { - return new RTPTranslatorImpl(); - } - - /** - * Gets the indicator which determines whether the loading of the JMF/FMJ - * Registry has been disabled. - * - * @return true if the loading of the JMF/FMJ Registry has - * been disabled; otherwise, false - */ - public static boolean isJmfRegistryDisableLoad() - { - return jmfRegistryDisableLoad; - } - - /** - * Performs one-time initialization after initializing the first instance of - * MediaServiceImpl. - * - * @param mediaServiceImpl the MediaServiceImpl instance which has - * caused the need to perform the one-time initialization - */ - private static void postInitializeOnce(MediaServiceImpl mediaServiceImpl) - { - new ZrtpFortunaEntropyGatherer( - mediaServiceImpl.getDeviceConfiguration()) - .setEntropy(); - } - - /** - * Sets up FMJ for execution. For example, sets properties which instruct - * FMJ whether it is to create a log, where the log is to be created. - */ - private static void setupFMJ() - { - /* - * Since FMJ is part of neomedia, FMJ's log should be enabled when - * neomedia's log is enabled. - */ - Registry.set("allowLogging", logger.isDebugEnabled()); - - /* - * Disable the loading of .fmj.registry because Kertesz Laszlo has - * reported that audio input devices duplicate after restarting Jitsi. - * Besides, Jitsi does not really need .fmj.registry on startup. - */ - if (System.getProperty(JMF_REGISTRY_DISABLE_LOAD) == null) - System.setProperty(JMF_REGISTRY_DISABLE_LOAD, "true"); - jmfRegistryDisableLoad - = "true".equalsIgnoreCase(System.getProperty( - JMF_REGISTRY_DISABLE_LOAD)); - - String scHomeDirLocation - = System.getProperty( - ConfigurationService.PNAME_SC_HOME_DIR_LOCATION); - - if (scHomeDirLocation != null) - { - String scHomeDirName - = System.getProperty( - ConfigurationService.PNAME_SC_HOME_DIR_NAME); - - if (scHomeDirName != null) - { - File scHomeDir = new File(scHomeDirLocation, scHomeDirName); - - /* Write FMJ's log in Jitsi's log directory. */ - Registry.set( - "secure.logDir", - new File(scHomeDir, "log").getPath()); - - /* Write FMJ's registry in Jitsi's user data directory. */ - String jmfRegistryFilename - = "net.sf.fmj.utility.JmfRegistry.filename"; - - if (System.getProperty(jmfRegistryFilename) == null) - { - System.setProperty( - jmfRegistryFilename, - new File(scHomeDir, ".fmj.registry").getAbsolutePath()); - } - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/MediaStreamImpl.java b/src/net/java/sip/communicator/impl/neomedia/MediaStreamImpl.java deleted file mode 100644 index e48941cfa..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/MediaStreamImpl.java +++ /dev/null @@ -1,2476 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.io.*; -import java.net.*; -import java.util.*; -import java.beans.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; -import javax.media.protocol.*; -import javax.media.rtp.*; -import javax.media.rtp.event.*; -import javax.media.rtp.rtcp.*; - -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.impl.neomedia.format.*; -import net.java.sip.communicator.impl.neomedia.transform.*; -import net.java.sip.communicator.impl.neomedia.transform.csrc.*; -import net.java.sip.communicator.impl.neomedia.transform.dtmf.*; -import net.java.sip.communicator.impl.neomedia.transform.rtcp.*; -import net.java.sip.communicator.impl.neomedia.transform.zrtp.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.format.*; -import net.java.sip.communicator.util.*; - -/** - * Implements MediaStream using JMF. - * - * @author Lyubomir Marinov - * @author Emil Ivov - * @author Sebastien Vincent - */ -public class MediaStreamImpl - extends AbstractMediaStream - implements ReceiveStreamListener, - SendStreamListener, - SessionListener, - RemoteListener -{ - /** - * The Logger used by the MediaStreamImpl class and its - * instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(MediaStreamImpl.class); - - /** - * The name of the property indicating the length of our receive buffer. - */ - protected static final String PROPERTY_NAME_RECEIVE_BUFFER_LENGTH - = "net.java.sip.communicator.impl.neomedia.RECEIVE_BUFFER_LENGTH"; - - /** - * The session with the MediaDevice this instance uses for both - * capture and playback of media. - */ - private MediaDeviceSession deviceSession; - - /** - * The PropertyChangeListener which listens to - * {@link #deviceSession} and changes in the values of its - * {@link MediaDeviceSession#OUTPUT_DATA_SOURCE} property. - */ - private final PropertyChangeListener deviceSessionPropertyChangeListener - = new PropertyChangeListener() - { - public void propertyChange(PropertyChangeEvent event) - { - String propertyName = event.getPropertyName(); - - if (MediaDeviceSession.OUTPUT_DATA_SOURCE.equals(propertyName)) - deviceSessionOutputDataSourceChanged(); - else if (MediaDeviceSession.SSRC_LIST.equals(propertyName)) - deviceSessionSsrcListChanged(event); - } - }; - - /** - * The MediaDirection in which this MediaStream is allowed - * to stream media. - */ - private MediaDirection direction; - - /** - * The Map of associations in this MediaStream and the - * RTPManager it utilizes of (dynamic) RTP payload types to - * MediaFormats. - */ - private final Map dynamicRTPPayloadTypes - = new HashMap(); - - /** - * The ReceiveStreams this instance plays back on its associated - * MediaDevice. - */ - private final List receiveStreams - = new LinkedList(); - - /** - * The RTPConnector through which this instance sends and receives - * RTP and RTCP traffic. The instance is a TransformConnector in - * order to also enable packet transformations. - */ - private AbstractRTPConnector rtpConnector; - - /** - * The one and only MediaStreamTarget this instance has added as a - * target in {@link #rtpConnector}. - */ - private MediaStreamTarget rtpConnectorTarget; - - /** - * The RTPManager which utilizes {@link #rtpConnector} and sends - * and receives RTP and RTCP traffic on behalf of this MediaStream. - */ - private StreamRTPManager rtpManager; - - /** - * The RTPTranslator, if any, which forwards RTP and RTCP traffic - * between this and other MediaStreams. - */ - private RTPTranslator rtpTranslator; - - /** - * The indicator which determines whether {@link #createSendStreams()} has - * been executed for {@link #rtpManager}. If true, the - * SendStreams have to be recreated when the MediaDevice, - * respectively the MediaDeviceSession, of this instance is - * changed. - */ - private boolean sendStreamsAreCreated = false; - - /** - * The indicator which determines whether {@link #start()} has been called - * on this MediaStream without {@link #stop()} or {@link #close()}. - */ - private boolean started = false; - - /** - * The MediaDirection in which this instance is started. For - * example, {@link MediaDirection#SENDRECV} if this instances is both - * sending and receiving data (e.g. RTP and RTCP) or - * {@link MediaDirection#SENDONLY} if this instance is only sending data. - */ - private MediaDirection startedDirection; - - /** - * The SSRC identifiers of the party that we are exchanging media with. - */ - private final Vector remoteSourceIDs = new Vector(1, 1); - - /** - * Our own SSRC identifier. - */ - private long localSourceID = -1; - - /** - * The list of CSRC IDs contributing to the media that this - * MediaStream is sending to its remote party. - */ - private long[] localContributingSourceIDList = null; - - /** - * The indicator which determines whether this MediaStream is set - * to transmit "silence" instead of the actual media fed from its - * MediaDevice. - */ - private boolean mute = false; - - /** - * The map of currently active RTPExtensions and the IDs that they - * have been assigned for the lifetime of this MediaStream. - */ - private final Map activeRTPExtensions - = new Hashtable(); - - /** - * The engine that we are using in order to add CSRC lists in conference - * calls, send CSRC sound levels, and handle incoming levels and CSRC lists. - */ - private CsrcTransformEngine csrcEngine; - - /** - * The SrtpControl which controls the SRTP functionality of this - * MediaStream. - */ - private final SrtpControl srtpControl; - - /** - * Number of received sender reports. Used for logging and debugging only. - */ - private long numberOfReceivedSenderReports = 0; - - /** - * The minimum inter arrival jitter value the other party has reported. - */ - private long maxRemoteInterArrivalJitter = 0; - - /** - * The maximum inter arrival jitter value the other party has reported. - */ - private long minRemoteInterArrivalJitter = -1; - - /** - * Engine chain reading sent RTCP sender reports and stores/prints - * statistics. - */ - private StatisticsEngine statisticsEngine = null; - - /** - * The MediaStreamStatsImpl object used to compute the statistics about - * this MediaStreamImpl. - */ - private MediaStreamStatsImpl mediaStreamStatsImpl; - - /** - * Initializes a new MediaStreamImpl instance which will use the - * specified MediaDevice for both capture and playback of media. - * The new instance will not have an associated StreamConnector and - * it must be set later for the new instance to be able to exchange media - * with a remote peer. - * - * @param device the MediaDevice the new instance is to use for - * both capture and playback of media - * @param srtpControl an existing control instance to control the SRTP - * operations - */ - public MediaStreamImpl(MediaDevice device, SrtpControl srtpControl) - { - this(null, device, srtpControl); - } - - /** - * Initializes a new MediaStreamImpl instance which will use the - * specified MediaDevice for both capture and playback of media - * exchanged via the specified StreamConnector. - * - * @param connector the StreamConnector the new instance is to use - * for sending and receiving media or null if the - * StreamConnector of the new instance is to not be set at - * initialization time but specified later on - * @param device the MediaDevice the new instance is to use for - * both capture and playback of media exchanged via the specified - * StreamConnector - * @param srtpControl an existing control instance to control the ZRTP - * operations or null if a new control instance is to be created by - * the new MediaStreamImpl - */ - public MediaStreamImpl( - StreamConnector connector, - MediaDevice device, - SrtpControl srtpControl) - { - /* - * XXX Set the device early in order to make sure that it is of the - * right type because we do not support just about any MediaDevice yet. - */ - setDevice(device); - - // TODO Add option to disable ZRTP, e.g. by implementing a NullControl. - // If you change the default behavior (initiates a ZrtpControlImpl if - // the srtpControl attribute is null), please accordingly modify the - // CallPeerMediaHandler.initStream function. - this.srtpControl - = (srtpControl == null) - ? NeomediaActivator.getMediaServiceImpl() - .createZrtpControl() - : srtpControl; - - if (connector != null) - setConnector(connector); - - this.mediaStreamStatsImpl = new MediaStreamStatsImpl(this); - - } - - /** - * Performs any optional configuration on a specific - * RTPConnectorOuputStream of an RTPManager to be used by - * this MediaStreamImpl. Allows extenders to override. - * - * @param dataOutputStream the RTPConnectorOutputStream to be used - * by an RTPManager of this MediaStreamImpl and to be - * configured - */ - protected void configureDataOutputStream( - RTPConnectorOutputStream dataOutputStream) - { - dataOutputStream.setPriority(getPriority()); - } - - /** - * Performs any optional configuration on a specific - * RTPConnectorInputStream of an RTPManager to be used by - * this MediaStreamImpl. Allows extenders to override. - * - * @param dataInputStream the RTPConnectorInputStream to be used - * by an RTPManager of this MediaStreamImpl and to be - * configured - */ - protected void configureDataInputStream( - RTPConnectorInputStream dataInputStream) - { - dataInputStream.setPriority(getPriority()); - } - - /** - * Performs any optional configuration on the BufferControl of the - * specified RTPManager which is to be used as the - * RTPManager of this MediaStreamImpl. Allows extenders to - * override. - * - * @param rtpManager the RTPManager which is to be used by this - * MediaStreamImpl - * @param bufferControl the BufferControl of rtpManager on - * which any optional configuration is to be performed - */ - protected void configureRTPManagerBufferControl( - StreamRTPManager rtpManager, - BufferControl bufferControl) - { - } - - /** - * Creates a chain of transform engines for use with this stream. Note - * that this is the only place where the TransformEngineChain is - * and should be manipulated to avoid problems with the order of the - * transformers. - * - * @return the TransformEngineChain that this stream should be - * using. - */ - private TransformEngineChain createTransformEngineChain() - { - ArrayList engineChain - = new ArrayList(4); - - // CSRCs and audio levels - if (csrcEngine == null) - csrcEngine = new CsrcTransformEngine(this); - engineChain.add(csrcEngine); - - // DTMF - DtmfTransformEngine dtmfEngine = createDtmfTransformEngine(); - - if (dtmfEngine != null) - engineChain.add(dtmfEngine); - - // RTCP Statistics - if (statisticsEngine == null) - statisticsEngine = new StatisticsEngine(this); - engineChain.add(statisticsEngine); - - // SRTP - engineChain.add(srtpControl.getTransformEngine()); - - return - new TransformEngineChain( - engineChain.toArray( - new TransformEngine[engineChain.size()])); - } - - /** - * A stub that allows audio oriented streams to create and keep a reference - * to a DtmfTransformEngine. - * - * @return a DtmfTransformEngine if this is an audio oriented - * stream and null otherwise. - */ - protected DtmfTransformEngine createDtmfTransformEngine() - { - return null; - } - - /** - * Adds a new association in this MediaStream of the specified RTP - * payload type with the specified MediaFormat in order to allow it - * to report rtpPayloadType in RTP flows sending and receiving - * media in format. Usually, rtpPayloadType will be in the - * range of dynamic RTP payload types. - * - * @param rtpPayloadType the RTP payload type to be associated in this - * MediaStream with the specified MediaFormat - * @param format the MediaFormat to be associated in this - * MediaStream with rtpPayloadType - * @see MediaStream#addDynamicRTPPayloadType(byte, MediaFormat) - */ - public void addDynamicRTPPayloadType( - byte rtpPayloadType, - MediaFormat format) - { - @SuppressWarnings("unchecked") - MediaFormatImpl mediaFormatImpl - = (MediaFormatImpl) format; - - synchronized (dynamicRTPPayloadTypes) - { - dynamicRTPPayloadTypes.put(Byte.valueOf(rtpPayloadType), format); - - if (rtpManager != null) - rtpManager.addFormat( - mediaFormatImpl.getFormat(), - rtpPayloadType); - } - } - - /** - * Maps or updates the mapping between extensionID and - * rtpExtension. If rtpExtension's MediaDirection - * attribute is set to INACTIVE the mapping is removed from the - * local extensions table and the extension would not be transmitted or - * handled by this stream's RTPConnector. - * - * @param extensionID the ID that is being mapped to rtpExtension - * @param rtpExtension the RTPExtension that we are mapping. - */ - public void addRTPExtension(byte extensionID, RTPExtension rtpExtension) - { - synchronized (activeRTPExtensions) - { - if(rtpExtension.getDirection() == MediaDirection.INACTIVE) - activeRTPExtensions.remove(extensionID); - else - activeRTPExtensions.put(extensionID, rtpExtension); - } - } - - /** - * Returns a map containing all currently active RTPExtensions in - * use by this stream. - * - * @return a map containing all currently active RTPExtensions in - * use by this stream. - */ - public Map getActiveRTPExtensions() - { - synchronized (activeRTPExtensions) - { - return new HashMap(activeRTPExtensions); - } - } - - /** - * Returns the ID currently assigned to a specific RTP extension. - * - * @param rtpExtension the RTP extension to get the currently assigned ID of - * @return the ID currently assigned to the specified RTP extension or - * -1 if no ID has been defined for this extension so far - */ - public byte getActiveRTPExtensionID(RTPExtension rtpExtension) - { - synchronized (activeRTPExtensions) - { - Set> extSet - = this.activeRTPExtensions.entrySet(); - - for (Map.Entry entry : extSet) - { - if (entry.getValue().equals(rtpExtension)) - return entry.getKey(); - } - } - - return -1; - } - - /** - * Returns the engine that is responsible for adding the list of CSRC - * identifiers to outgoing RTP packets during a conference. - * - * @return the engine that is responsible for adding the list of CSRC - * identifiers to outgoing RTP packets during a conference. - */ - protected CsrcTransformEngine getCsrcEngine() - { - return csrcEngine; - } - - /** - * Releases the resources allocated by this instance in the course of its - * execution and prepares it to be garbage collected. - * - * @see MediaStream#close() - */ - public void close() - { - stop(); - closeSendStreams(); - - srtpControl.cleanup(); - - if (csrcEngine != null) - { - csrcEngine.close(); - csrcEngine = null; - } - - if (rtpConnector != null) - rtpConnector.removeTargets(); - rtpConnectorTarget = null; - - if (rtpManager != null) - { - if (logger.isInfoEnabled()) - printFlowStatistics(rtpManager); - - rtpManager.removeReceiveStreamListener(this); - rtpManager.removeSendStreamListener(this); - rtpManager.removeSessionListener(this); - rtpManager.removeRemoteListener(this); - try - { - rtpManager.dispose(); - rtpManager = null; - } - catch (Throwable t) - { - if (t instanceof ThreadDeath) - throw (ThreadDeath) t; - - /* - * Analysis of heap dumps and application logs suggests that - * RTPManager#dispose() may throw an exception after a - * NullPointerException has been thrown by SendStream#close() as - * documented in - * #stopSendStreams(Iterable, boolean). It is - * unknown at the time of this writing whether we can do - * anything to prevent the exception here but it is clear that, - * if we let it go through, we will not release at least one - * capture device (i.e. we will at least skip the - * MediaDeviceSession#close() bellow). For example, if the - * exception is thrown for the audio stream in a call, its - * capture device will not be released and any video stream will - * not get its #close() method called at all. - */ - logger.error("Failed to dispose of RTPManager", t); - } - } - - if (deviceSession != null) - deviceSession.close(); - } - - /** - * Closes the SendStreams this instance is sending to its remote - * peer. - */ - private void closeSendStreams() - { - stopSendStreams(true); - } - - /** - * Creates new SendStream instances for the streams of - * {@link #deviceSession} through {@link #rtpManager}. - */ - private void createSendStreams() - { - StreamRTPManager rtpManager = getRTPManager(); - MediaDeviceSession deviceSession = getDeviceSession(); - DataSource dataSource = deviceSession.getOutputDataSource(); - int streamCount; - - if (dataSource instanceof PushBufferDataSource) - { - PushBufferStream[] streams - = ((PushBufferDataSource) dataSource).getStreams(); - - streamCount = (streams == null) ? 0 : streams.length; - } - else if (dataSource instanceof PushDataSource) - { - PushSourceStream[] streams - = ((PushDataSource) dataSource).getStreams(); - - streamCount = (streams == null) ? 0 : streams.length; - } - else if (dataSource instanceof PullBufferDataSource) - { - PullBufferStream[] streams - = ((PullBufferDataSource) dataSource).getStreams(); - - streamCount = (streams == null) ? 0 : streams.length; - } - else if (dataSource instanceof PullDataSource) - { - PullSourceStream[] streams - = ((PullDataSource) dataSource).getStreams(); - - streamCount = (streams == null) ? 0 : streams.length; - } - else - streamCount = (dataSource == null) ? 0 : 1; - - /* - * XXX We came up with a scenario in our testing in which G.722 would - * work fine for the first call since the start of the application and - * then it would fail for subsequent calls, JMF would complain that the - * G.722 RTP format is unknown to the RTPManager. Since - * RTPManager#createSendStream(DataSource, int) is one of the cases in - * which the formats registered with the RTPManager are necessary, - * register them (again) just before we use them. - */ - registerCustomCodecFormats(rtpManager); - - for (int streamIndex = 0; streamIndex < streamCount; streamIndex++) - { - try - { - SendStream sendStream - = rtpManager.createSendStream(dataSource, streamIndex); - - if (logger.isTraceEnabled()) - logger - .trace( - "Created SendStream" - + " with hashCode " - + sendStream.hashCode() - + " for " - + toString(dataSource) - + " and streamIndex " - + streamIndex - + " in RTPManager with hashCode " - + rtpManager.hashCode()); - - long localSSRC = sendStream.getSSRC(); - - if (getLocalSourceID() != localSSRC) - setLocalSourceID(localSSRC); - - /* - * If a ZRTP engine is available, then let it know about the - * SSRC of the new SendStream. Currently, ZRTP supports only one - * SSRC per engine. - */ - TransformEngine engine = srtpControl.getTransformEngine(); - - if ((engine != null) && (engine instanceof ZRTPTransformEngine)) - ((ZRTPTransformEngine)engine).setOwnSSRC(localSSRC); - } - catch (IOException ioe) - { - logger - .error( - "Failed to create send stream for data source " - + dataSource - + " and stream index " - + streamIndex, - ioe); - } - catch (UnsupportedFormatException ufe) - { - logger - .error( - "Failed to create send stream for data source " - + dataSource - + " and stream index " - + streamIndex - + " because of failed format " - + ufe.getFailedFormat(), - ufe); - } - } - sendStreamsAreCreated = true; - - if (logger.isTraceEnabled()) - { - @SuppressWarnings("unchecked") - Vector sendStreams = rtpManager.getSendStreams(); - int sendStreamCount - = (sendStreams == null) ? 0 : sendStreams.size(); - - logger - .trace( - "Total number of SendStreams in RTPManager with hashCode " - + rtpManager.hashCode() - + " is " - + sendStreamCount); - } - } - - /** - * Notifies this MediaStream that the MediaDevice (and - * respectively the MediaDeviceSession with it) which this instance - * uses for capture and playback of media has been changed. Allows extenders - * to override and provide additional processing of oldValue and - * newValue. - * - * @param oldValue the MediaDeviceSession with the - * MediaDevice this instance used work with - * @param newValue the MediaDeviceSession with the - * MediaDevice this instance is to work with - */ - protected void deviceSessionChanged( - MediaDeviceSession oldValue, - MediaDeviceSession newValue) - { - recreateSendStreams(); - } - - /** - * Notifies this instance that the output DataSource of its - * MediaDeviceSession has changed. Recreates the - * SendStreams of this instance as necessary so that it, for - * example, continues streaming after the change if it was streaming before - * the change. - */ - private void deviceSessionOutputDataSourceChanged() - { - recreateSendStreams(); - } - - /** - * Recalculates the list of CSRC identifiers that this MediaStream - * needs to include in RTP packets bound to its interlocutor. The method - * uses the list of SSRC identifiers currently handled by our device - * (possibly a mixer), then removes the SSRC ID of this stream's - * interlocutor. If this turns out to be the only SSRC currently in the list - * we set the list of local CSRC identifiers to null since this is obviously - * a non-conf call and we don't need to be advertising CSRC lists. If that's - * not the case, we also add our own SSRC to the list of IDs and cache the - * entire list. - * - * @param evt the PropetyChangeEvent containing the list of SSRC - * identifiers handled by our device session before and after it changed. - */ - private void deviceSessionSsrcListChanged(PropertyChangeEvent evt) - { - long[] ssrcArray = (long[])evt.getNewValue(); - - // the list is empty - if(ssrcArray == null) - { - this.localContributingSourceIDList = null; - return; - } - - int elementsToRemove = 0; - Vector remoteSourceIDs = this.remoteSourceIDs; - - //in case of a conf call the mixer would return all SSRC IDs that are - //currently contributing including this stream's counterpart. We need - //to remove that last one since that's where we will be sending our - //csrc list - for(long csrc : ssrcArray) - if (remoteSourceIDs.contains(csrc)) - elementsToRemove ++; - - //we don't seem to be in a conf call since the list only contains the - //SSRC id of the party that we are directly interacting with. - if (elementsToRemove >= ssrcArray.length) - { - this.localContributingSourceIDList = null; - return; - } - - //prepare the new array. make it big enough to also add the local - //SSRC id but do not make it bigger than 15 since that's the maximum - //for RTP. - int cc = Math.min(ssrcArray.length - elementsToRemove + 1, 15); - - long[] csrcArray = new long[cc]; - - for (int i = 0,j = 0; - (i < ssrcArray.length) && (j < csrcArray.length - 1); - i++) - { - long ssrc = ssrcArray[i]; - - if (!remoteSourceIDs.contains(ssrc)) - { - csrcArray[j] = ssrc; - j++; - } - } - - csrcArray[csrcArray.length - 1] = getLocalSourceID(); - - this.localContributingSourceIDList = csrcArray; - } - - /** - * Sets the target of this MediaStream to which it is to send and - * from which it is to receive data (e.g. RTP) and control data (e.g. RTCP). - * In contrast to {@link #setTarget(MediaStreamTarget)}, sets the specified - * target on this MediaStreamImpl even if its current - * target is equal to the specified one. - * - * @param target the MediaStreamTarget describing the data - * (e.g. RTP) and the control data (e.g. RTCP) locations to which this - * MediaStream is to send and from which it is to receive - * @see MediaStreamImpl#setTarget(MediaStreamTarget) - */ - private void doSetTarget(MediaStreamTarget target) - { - rtpConnector.removeTargets(); - rtpConnectorTarget = null; - - boolean targetIsSet; - - if (target != null) - { - InetSocketAddress dataAddr = target.getDataAddress(); - InetSocketAddress controlAddr = target.getControlAddress(); - - try - { - rtpConnector - .addTarget( - new SessionAddress( - dataAddr.getAddress(), - dataAddr.getPort(), - controlAddr != null ? controlAddr.getAddress() - : null, - controlAddr != null ? controlAddr.getPort() - : 0)); - targetIsSet = true; - } - catch (IOException ioe) - { - // TODO - targetIsSet = false; - logger.error("Failed to set target " + target, ioe); - } - } - else - targetIsSet = true; - if (targetIsSet) - { - rtpConnectorTarget = target; - - if (logger.isTraceEnabled()) - logger - .trace( - "Set target of " - + getClass().getSimpleName() - + " with hashCode " - + hashCode() - + " to " - + target); - } - } - - /** - * Gets the MediaDevice that this stream uses to play back and - * capture media. - * - * @return the MediaDevice that this stream uses to play back and - * capture media - * @see MediaStream#getDevice() - */ - public AbstractMediaDevice getDevice() - { - return getDeviceSession().getDevice(); - } - - /** - * Gets the MediaDeviceSession which represents the work of this - * MediaStream with its associated MediaDevice. - * - * @return the MediaDeviceSession which represents the work of this - * MediaStream with its associated MediaDevice - */ - public MediaDeviceSession getDeviceSession() - { - return deviceSession; - } - - /** - * Gets the direction in which this MediaStream is allowed to - * stream media. - * - * @return the MediaDirection in which this MediaStream is - * allowed to stream media - * @see MediaStream#getDirection() - */ - public MediaDirection getDirection() - { - if (direction != null) - return direction; - - MediaDeviceSession deviceSession = getDeviceSession(); - - return (deviceSession == null) - ? MediaDirection.INACTIVE - : deviceSession.getDevice().getDirection(); - } - - /** - * Gets the existing associations in this MediaStream of RTP - * payload types to MediaFormats. The returned Map - * only contains associations previously added in this instance with - * {@link #addDynamicRTPPayloadType(byte, MediaFormat)} and not globally or - * well-known associations reported by - * {@link MediaFormat#getRTPPayloadType()}. - * - * @return a Map of RTP payload type expressed as Byte to - * MediaFormat describing the existing (dynamic) associations in - * this instance of RTP payload types to MediaFormats. The - * Map represents a snapshot of the existing associations at the - * time of the getDynamicRTPPayloadTypes() method call and - * modifications to it are not reflected on the internal storage - * @see MediaStream#getDynamicRTPPayloadTypes() - */ - public Map getDynamicRTPPayloadTypes() - { - synchronized (dynamicRTPPayloadTypes) - { - return new HashMap(dynamicRTPPayloadTypes); - } - } - - /** - * Returns the payload type number that has been negotiated for the - * specified encoding or -1 if no payload type has been - * negotiated for it. If multiple formats match the specified - * encoding, then this method would return the first one it - * encounters while iterating through the map. - * - * @param encoding the encoding whose payload type we are trying to obtain. - * - * @return the payload type number that has been negotiated for the - * specified encoding or -1 if no payload type has been - * negotiated for it. - */ - public byte getDynamicRTPPayloadType(String encoding) - { - synchronized (dynamicRTPPayloadTypes) - { - for (Map.Entry entry - : dynamicRTPPayloadTypes.entrySet()) - { - if (entry.getValue().getEncoding().equals(encoding)) - return entry.getKey().byteValue(); - } - return -1; - } - } - - /** - * Gets the MediaFormat that this stream is currently transmitting - * in. - * - * @return the MediaFormat that this stream is currently - * transmitting in - * @see MediaStream#getFormat() - */ - public MediaFormat getFormat() - { - return getDeviceSession().getFormat(); - } - - /** - * Gets the synchronization source (SSRC) identifier of the local peer or - * -1 if it is not yet known. - * - * @return the synchronization source (SSRC) identifier of the local peer - * or -1 if it is not yet known - * @see MediaStream#getLocalSourceID() - */ - public long getLocalSourceID() - { - return this.localSourceID; - } - - /** - * Gets the address that this stream is sending RTCP traffic to. - * - * @return an InetSocketAddress instance indicating the address - * that this stream is sending RTCP traffic to - * @see MediaStream#getRemoteControlAddress() - */ - public InetSocketAddress getRemoteControlAddress() - { - StreamConnector connector = - (rtpConnector != null) ? rtpConnector.getConnector() : null; - - if(connector != null) - { - if(connector.getDataSocket() != null) - { - return (InetSocketAddress)connector.getControlSocket(). - getRemoteSocketAddress(); - } - else if(connector.getDataTCPSocket() != null) - { - return (InetSocketAddress)connector.getControlTCPSocket(). - getRemoteSocketAddress(); - } - } - - return null; - } - - /** - * Gets the address that this stream is sending RTP traffic to. - * - * @return an InetSocketAddress instance indicating the address - * that this stream is sending RTP traffic to - * @see MediaStream#getRemoteDataAddress() - */ - public InetSocketAddress getRemoteDataAddress() - { - StreamConnector connector = - (rtpConnector != null) ? rtpConnector.getConnector() : null; - - if(connector != null) - { - if(connector.getDataSocket() != null) - { - return (InetSocketAddress)connector.getDataSocket(). - getRemoteSocketAddress(); - } - else if(connector.getDataTCPSocket() != null) - { - return (InetSocketAddress)connector.getDataTCPSocket(). - getRemoteSocketAddress(); - } - } - - return null; - } - - /** - * Gets the local address that this stream is sending RTCP traffic from. - * - * @return an InetSocketAddress instance indicating the local - * address that this stream is sending RTCP traffic from. - */ - public InetSocketAddress getLocalControlAddress() - { - StreamConnector connector = - (rtpConnector != null) ? rtpConnector.getConnector() : null; - - if(connector != null) - { - if(connector.getDataSocket() != null) - { - return (InetSocketAddress)connector.getControlSocket(). - getLocalSocketAddress(); - } - else if(connector.getDataTCPSocket() != null) - { - return (InetSocketAddress)connector.getControlTCPSocket(). - getLocalSocketAddress(); - } - } - - return null; - } - - /** - * Gets the local address that this stream is sending RTP traffic from. - * - * @return an InetSocketAddress instance indicating the local - * address that this stream is sending RTP traffic from. - */ - public InetSocketAddress getLocalDataAddress() - { - StreamConnector connector = - (rtpConnector != null) ? rtpConnector.getConnector() : null; - - if(connector != null) - { - if(connector.getDataSocket() != null) - { - return (InetSocketAddress)connector.getDataSocket(). - getLocalSocketAddress(); - } - else if(connector.getDataTCPSocket() != null) - { - return (InetSocketAddress)connector.getDataTCPSocket(). - getLocalSocketAddress(); - } - } - - return null; - } - - /** - * Returns the transport protocol used by the streams. - * - * @return the transport protocol (UDP or TCP) used by the streams. null if - * the stream connector is not instanciated. - */ - public StreamConnector.Protocol getTransportProtocol() - { - StreamConnector connector = - (rtpConnector != null) ? rtpConnector.getConnector() : null; - - if(connector == null) - { - return null; - } - - return connector.getProtocol(); - } - - /** - * Get the synchronization source (SSRC) identifier of the remote peer or - * -1 if it is not yet known. - * - * @return the synchronization source (SSRC) identifier of the remote - * peer or -1 if it is not yet known - * @see MediaStream#getRemoteSourceID() - */ - public long getRemoteSourceID() - { - return remoteSourceIDs.isEmpty() ? -1 : remoteSourceIDs.lastElement(); - } - - /** - * Gets the synchronization source (SSRC) identifiers of the remote peers. - * - * @return the synchronization source (SSRC) identifiers of the remote peers - * @see MediaStream#getRemoteSourceIDs() - */ - public List getRemoteSourceIDs() - { - return Collections.unmodifiableList(remoteSourceIDs); - } - - /** - * Gets the RTPConnector through which this instance sends and - * receives RTP and RTCP traffic. - * - * @return the RTPConnector through which this instance sends and - * receives RTP and RTCP traffic - */ - protected AbstractRTPConnector getRTPConnector() - { - return rtpConnector; - } - - /** - * Gets the RTPManager instance which sends and receives RTP and - * RTCP traffic on behalf of this MediaStream. - * - * @return the RTPManager instance which sends and receives RTP and - * RTCP traffic on behalf of this MediaStream - */ - public StreamRTPManager getRTPManager() - { - if (rtpManager == null) - { - RTPConnector rtpConnector = getRTPConnector(); - - if (rtpConnector == null) - throw new IllegalStateException("rtpConnector"); - - rtpManager = new StreamRTPManager(rtpTranslator); - - registerCustomCodecFormats(rtpManager); - - rtpManager.addReceiveStreamListener(this); - rtpManager.addSendStreamListener(this); - rtpManager.addSessionListener(this); - rtpManager.addRemoteListener(this); - - BufferControl bc - = (BufferControl) - rtpManager.getControl(BufferControl.class.getName()); - if (bc != null) - configureRTPManagerBufferControl(rtpManager, bc); - - rtpManager.initialize(rtpConnector); - - /* - * JMF initializes the local SSRC upon #initialize(RTPConnector) so - * now's the time to ask. - */ - /* - * As JMF keeps the SSRC as a signed int value, convert it to - * unsigned. - */ - setLocalSourceID(rtpManager.getLocalSSRC() & 0xFFFFFFFFL); - } - return rtpManager; - } - - /** - * Gets the SrtpControl which controls the SRTP of this stream. - * - * @return the SrtpControl which controls the SRTP of this stream - */ - public SrtpControl getSrtpControl() - { - return srtpControl; - } - - /** - * Determines whether this MediaStream is set to transmit "silence" - * instead of the media being fed from its MediaDevice. "Silence" - * for video is understood as video data which is not the captured video - * data and may represent, for example, a black image. - * - * @return true if this MediaStream is set to transmit - * "silence" instead of the media fed from its MediaDevice; - * false, otherwise - * @see MediaStream#isMute() - */ - public boolean isMute() - { - MediaDeviceSession deviceSession = getDeviceSession(); - - return (deviceSession == null) ? mute : deviceSession.isMute(); - } - - /** - * Determines whether {@link #start()} has been called on this - * MediaStream without {@link #stop()} or {@link #close()} - * afterwards. - * - * @return true if {@link #start()} has been called on this - * MediaStream without {@link #stop()} or {@link #close()} - * afterwards - * @see MediaStream#isStarted() - */ - public boolean isStarted() - { - return started; - } - - /** - * Recreates the SendStreams of this instance (i.e. of its - * RTPManager) as necessary. For example, if there was no attempt - * to create the SendStreams prior to the call, does nothing. If - * they were created prior to the call, closes them and creates them again. - * If they were not started prior to the call, does not start them after - * recreating them. - */ - private void recreateSendStreams() - { - if (sendStreamsAreCreated) - { - closeSendStreams(); - - if ((getDeviceSession() != null) && (rtpManager != null)) - { - if (MediaDirection.SENDONLY.equals(startedDirection) - || MediaDirection.SENDRECV.equals(startedDirection)) - startSendStreams(); - } - } - } - - /** - * Registers any custom JMF Formats with a specific - * RTPManager. Extenders should override in order to register their - * own customizations and should call back to this super implementation - * during the execution of their override in order to register the - * associations defined in this instance of (dynamic) RTP payload types to - * MediaFormats. - * - * @param rtpManager the RTPManager to register any custom JMF - * Formats with - */ - protected void registerCustomCodecFormats(StreamRTPManager rtpManager) - { - synchronized (dynamicRTPPayloadTypes) - { - for (Map.Entry dynamicRTPPayloadType - : dynamicRTPPayloadTypes.entrySet()) - { - @SuppressWarnings("unchecked") - MediaFormatImpl mediaFormatImpl - = (MediaFormatImpl) - dynamicRTPPayloadType.getValue(); - - rtpManager.addFormat( - mediaFormatImpl.getFormat(), - dynamicRTPPayloadType.getKey()); - } - } - } - - /** - * Notifies this MediaStream implementation that its - * RTPConnector instance has changed from a specific old value to a - * specific new value. Allows extenders to override and perform additional - * processing after this MediaStream has changed its - * RTPConnector instance. - * - * @param oldValue the RTPConnector of this MediaStream - * implementation before it got changed to newValue - * @param newValue the current RTPConnector of this - * MediaStream which replaced oldValue - */ - protected void rtpConnectorChanged( - AbstractRTPConnector oldValue, - AbstractRTPConnector newValue) - { - srtpControl.setConnector(newValue); - - if (newValue != null) - { - /* - * Register the transform engines that we will be using in this - * stream. - */ - if(newValue instanceof RTPTransformUDPConnector) - ((RTPTransformUDPConnector)newValue) - .setEngine(createTransformEngineChain()); - else if(newValue instanceof RTPTransformTCPConnector) - ((RTPTransformTCPConnector)newValue) - .setEngine(createTransformEngineChain()); - - if (rtpConnectorTarget != null) - doSetTarget(rtpConnectorTarget); - } - } - - /** - * Sets the StreamConnector to be used by this instance for sending - * and receiving media. - * - * @param connector the StreamConnector to be used by this instance - * for sending and receiving media - */ - public void setConnector(StreamConnector connector) - { - if (connector == null) - throw new NullPointerException("connector"); - - AbstractRTPConnector oldValue = rtpConnector; - - // Is the StreamConnector really changing? - if ((oldValue != null) && (oldValue.getConnector() == connector)) - return; - - switch (connector.getProtocol()) - { - case UDP: - rtpConnector - = new RTPTransformUDPConnector(connector) - { - @Override - protected TransformUDPOutputStream createDataOutputStream() - throws IOException - { - TransformUDPOutputStream dataOutputStream - = super.createDataOutputStream(); - - if (dataOutputStream != null) - configureDataOutputStream(dataOutputStream); - return dataOutputStream; - } - - @Override - protected TransformUDPInputStream createDataInputStream() - throws IOException - { - TransformUDPInputStream dataInputStream - = super.createDataInputStream(); - - if (dataInputStream != null) - configureDataInputStream(dataInputStream); - return dataInputStream; - } - }; - break; - case TCP: - rtpConnector - = new RTPTransformTCPConnector(connector) - { - @Override - protected TransformTCPOutputStream createDataOutputStream() - throws IOException - { - TransformTCPOutputStream dataOutputStream - = super.createDataOutputStream(); - - if (dataOutputStream != null) - configureDataOutputStream(dataOutputStream); - return dataOutputStream; - } - - @Override - protected TransformTCPInputStream createDataInputStream() - throws IOException - { - TransformTCPInputStream dataInputStream - = super.createDataInputStream(); - - if (dataInputStream != null) - configureDataInputStream(dataInputStream); - return dataInputStream; - } - }; - break; - default: - throw new IllegalArgumentException("connector"); - } - - rtpConnectorChanged(oldValue, rtpConnector); - } - - /** - * Sets the MediaDevice that this stream should use to play back - * and capture media. - *

- * Note: Also resets any previous direction set with - * {@link #setDirection(MediaDirection)} to the direction of the specified - * MediaDevice. - *

- * - * @param device the MediaDevice that this stream should use to - * play back and capture media - * @see MediaStream#setDevice(MediaDevice) - */ - public void setDevice(MediaDevice device) - { - if (device == null) - throw new NullPointerException("device"); - - // Require AbstractMediaDevice for MediaDeviceSession support. - AbstractMediaDevice abstractMediaDevice = (AbstractMediaDevice) device; - - if ((deviceSession == null) || (deviceSession.getDevice() != device)) - { - MediaDeviceSession oldValue = deviceSession; - MediaFormat format; - MediaDirection startedDirection; - - if (deviceSession != null) - { - format = getFormat(); - startedDirection = deviceSession.getStartedDirection(); - - deviceSession.removePropertyChangeListener( - deviceSessionPropertyChangeListener); - - // keep player active - deviceSession.setDisposePlayerOnClose( - !(deviceSession instanceof VideoMediaDeviceSession)); - deviceSession.close(); - deviceSession = null; - } - else - { - format = null; - startedDirection = MediaDirection.INACTIVE; - } - - deviceSession = abstractMediaDevice.createSession(); - - /* - * Copy the playback from the old MediaDeviceSession into the new - * MediaDeviceSession in order to prevent the recreation of the - * playback of the ReceiveStream(s) when just changing the - * MediaDevice of this MediaSteam. - */ - if (oldValue != null) - deviceSession.copyPlayback(oldValue); - - deviceSession.addPropertyChangeListener( - deviceSessionPropertyChangeListener); - - /* - * Setting a new device resets any previously-set direction. - * Otherwise, we risk not being able to set a new device if it is - * mandatory for the new device to fully cover any previously-set - * direction. - */ - direction = null; - - if (deviceSession != null) - { - if (format != null) - deviceSession.setFormat(format); - deviceSession.setMute(mute); - } - deviceSessionChanged(oldValue, deviceSession); - if (deviceSession != null) - { - deviceSession.start(startedDirection); - synchronized (receiveStreams) - { - for (ReceiveStream receiveStream : receiveStreams) - deviceSession.addReceiveStream(receiveStream); - } - } - } - } - - /** - * Sets the direction in which media in this MediaStream is to be - * streamed. If this MediaStream is not currently started, calls to - * {@link #start()} later on will start it only in the specified - * direction. If it is currently started in a direction different - * than the specified, directions other than the specified will be stopped. - * - * @param direction the MediaDirection in which this - * MediaStream is to stream media when it is started - * @see MediaStream#setDirection(MediaDirection) - */ - public void setDirection(MediaDirection direction) - { - if (direction == null) - throw new NullPointerException("direction"); - if(this.direction == direction) - return; - - if(logger.isTraceEnabled()) - logger.trace("Changing direction of stream " + hashCode() - + " from:" + this.direction + " to:" + direction); - - /* - * Make sure that the specified direction is in accord with the - * direction of the MediaDevice of this instance. - */ - MediaDeviceSession deviceSession = getDeviceSession(); - MediaDirection deviceDirection - = (deviceSession == null) - ? MediaDirection.INACTIVE - : deviceSession.getDevice().getDirection(); - - if (!deviceDirection.and(direction).equals(direction)) - throw new IllegalArgumentException("direction"); - - this.direction = direction; - - switch (this.direction) - { - case INACTIVE: - stop(MediaDirection.SENDRECV); - return; - case RECVONLY: - stop(MediaDirection.SENDONLY); - break; - case SENDONLY: - stop(MediaDirection.RECVONLY); - break; - case SENDRECV: - break; - default: - // Don't know what it may be (in the future) so ignore it. - return; - } - if (started) - start(this.direction); - } - - /** - * Sets the MediaFormat that this MediaStream should - * transmit in. - * - * @param format the MediaFormat that this MediaStream - * should transmit in - * @see MediaStream#setFormat(MediaFormat) - */ - public void setFormat(MediaFormat format) - { - MediaDeviceSession deviceSession = getDeviceSession(); - MediaFormatImpl deviceSessionFormat = null; - - if (deviceSession != null) - { - deviceSessionFormat = deviceSession.getFormat(); - if ((deviceSessionFormat != null) - && deviceSessionFormat.equals(format) - && deviceSessionFormat.advancedAttributesAreEqual( - deviceSessionFormat.getAdvancedAttributes(), - format.getAdvancedAttributes())) - return; - } - - if (logger.isTraceEnabled()) - logger.trace( - "Changing format of stream " + hashCode() - + " from: " + deviceSessionFormat - + " to: " + format); - - handleAttributes(format, format.getAdvancedAttributes()); - handleAttributes(format, format.getFormatParameters()); - deviceSession.setFormat(format); - } - - /** - * Handles attributes contained in MediaFormat. - * - * @param format the MediaFormat to handle the attributes of - * @param attrs the attributes Map to handle - */ - protected void handleAttributes( - MediaFormat format, - Map attrs) - { - } - - /** - * Causes this MediaStream to stop transmitting the media being fed - * from this stream's MediaDevice and transmit "silence" instead. - * "Silence" for video is understood as video data which is not the captured - * video data and may represent, for example, a black image. - * - * @param mute true to have this MediaStream transmit - * "silence" instead of the actual media data that it captures from its - * MediaDevice; false to transmit actual media data - * captured from the MediaDevice of this MediaStream - * @see MediaStream#setMute(boolean) - */ - public void setMute(boolean mute) - { - if (this.mute != mute) - { - if(logger.isTraceEnabled()) - logger.trace((mute? "Muting" : "Unmuting") - + " stream with hashcode " + hashCode()); - - this.mute = mute; - - MediaDeviceSession deviceSession = getDeviceSession(); - - if (deviceSession != null) - deviceSession.setMute(this.mute); - } - } - - /** - * Returns the target of this MediaStream to which it is to send - * and from which it is to receive data (e.g. RTP) and control data (e.g. - * RTCP). - * - * @return the MediaStreamTarget describing the data - * (e.g. RTP) and the control data (e.g. RTCP) locations to which this - * MediaStream is to send and from which it is to receive - * @see MediaStream#setTarget(MediaStreamTarget) - */ - public MediaStreamTarget getTarget() - { - return rtpConnectorTarget; - } - - /** - * Sets the target of this MediaStream to which it is to send and - * from which it is to receive data (e.g. RTP) and control data (e.g. RTCP). - * - * @param target the MediaStreamTarget describing the data - * (e.g. RTP) and the control data (e.g. RTCP) locations to which this - * MediaStream is to send and from which it is to receive - * @see MediaStream#setTarget(MediaStreamTarget) - */ - public void setTarget(MediaStreamTarget target) - { - // Short-circuit if setting the same target. - if (target == null) - { - if (rtpConnectorTarget == null) - return; - } - else if (target.equals(rtpConnectorTarget)) - return; - - doSetTarget(target); - } - - /** - * Starts capturing media from this stream's MediaDevice and then - * streaming it through the local StreamConnector toward the - * stream's target address and port. Also puts the MediaStream in a - * listening state which make it play all media received from the - * StreamConnector on the stream's MediaDevice. - * - * @see MediaStream#start() - */ - public void start() - { - start(getDirection()); - started = true; - } - - /** - * Starts the processing of media in this instance in a specific direction. - * - * @param direction a MediaDirection value which represents the - * direction of the processing of media to be started. For example, - * {@link MediaDirection#SENDRECV} to start both capture and playback of - * media in this instance or {@link MediaDirection#SENDONLY} to only start - * the capture of media in this instance - */ - private void start(MediaDirection direction) - { - if (direction == null) - throw new NullPointerException("direction"); - - if (direction.allowsSending() - && ((startedDirection == null) - || !startedDirection.allowsSending())) - { - startSendStreams(); - - getDeviceSession().start(MediaDirection.SENDONLY); - - if (MediaDirection.RECVONLY.equals(startedDirection)) - startedDirection = MediaDirection.SENDRECV; - else if (startedDirection == null) - startedDirection = MediaDirection.SENDONLY; - - logger.info(getFormat().getMediaType().toString() + " codec/freq: " - + getMediaStreamStats().getEncoding() - + "/" + getMediaStreamStats().getEncodingClockRate() + " Hz"); - logger.info(getFormat().getMediaType().toString() - + " remote IP/port: " - + getMediaStreamStats().getRemoteIPAddress() - + "/" + String.valueOf(getMediaStreamStats().getRemotePort())); - } - - if (direction.allowsReceiving() - && ((startedDirection == null) - || !startedDirection.allowsReceiving())) - { - startReceiveStreams(); - - getDeviceSession().start(MediaDirection.RECVONLY); - - if (MediaDirection.SENDONLY.equals(startedDirection)) - startedDirection = MediaDirection.SENDRECV; - else if (startedDirection == null) - startedDirection = MediaDirection.RECVONLY; - } - } - - /** - * Starts the ReceiveStreams that this instance is receiving from - * its remote peer. By design, a MediaStream instance is associated - * with a single ReceiveStream at a time. However, the - * ReceiveStreams are created by RTPManager and it tracks - * multiple ReceiveStreams. In practice, the RTPManager of - * this MediaStreamImpl will have a single ReceiveStream - * in its list. - */ - @SuppressWarnings("unchecked") - private void startReceiveStreams() - { - StreamRTPManager rtpManager = getRTPManager(); - List receiveStreams; - - try - { - receiveStreams = rtpManager.getReceiveStreams(); - } - catch (Exception ex) - { - /* - * It appears that in early call states when there are no streams, a - * NullPointerException could be thrown. Make sure we handle it - * gracefully. - */ - if (logger.isTraceEnabled()) - logger.trace("Failed to retrieve receive streams", ex); - receiveStreams = null; - } - - if (receiveStreams != null) - { - /* - * It turns out that the receiveStreams list of rtpManager can be - * empty. As a workaround, use the receiveStreams of this instance. - */ - if (receiveStreams.isEmpty() && (this.receiveStreams != null)) - receiveStreams = this.receiveStreams; - - for (ReceiveStream receiveStream : receiveStreams) - { - try - { - DataSource receiveStreamDataSource - = receiveStream.getDataSource(); - - /* - * For an unknown reason, the stream DataSource can be null - * at the end of the Call after re-INVITEs have been - * handled. - */ - if (receiveStreamDataSource != null) - receiveStreamDataSource.start(); - } - catch (IOException ioex) - { - logger.warn( - "Failed to start receive stream " + receiveStream, - ioex); - } - } - } - } - - /** - * Starts the SendStreams of the RTPManager of this - * MediaStreamImpl. - */ - private void startSendStreams() - { - /* - * Until it's clear that the SendStreams are required (i.e. we've - * negotiated to send), they will not be created. Otherwise, their - * creation isn't only illogical but also causes the CaptureDevice to - * be used. - */ - if (!sendStreamsAreCreated) - createSendStreams(); - - StreamRTPManager rtpManager = getRTPManager(); - @SuppressWarnings("unchecked") - Iterable sendStreams = rtpManager.getSendStreams(); - - if (sendStreams != null) - { - for (SendStream sendStream : sendStreams) - { - try - { - DataSource sendStreamDataSource - = sendStream.getDataSource(); - - // TODO Are we sure we want to connect here? - sendStreamDataSource.connect(); - sendStream.start(); - sendStreamDataSource.start(); - - if (logger.isTraceEnabled()) - { - logger.trace( - "Started SendStream with hashCode " - + sendStream.hashCode()); - } - } - catch (IOException ioe) - { - logger.warn("Failed to start stream " + sendStream, ioe); - } - } - } - } - - /** - * Stops all streaming and capturing in this MediaStream and closes - * and releases all open/allocated devices/resources. Has no effect if this - * MediaStream is already closed and is simply ignored. - * - * @see MediaStream#stop() - */ - public void stop() - { - stop(MediaDirection.SENDRECV); - started = false; - } - - /** - * Stops the processing of media in this instance in a specific direction. - * - * @param direction a MediaDirection value which represents the - * direction of the processing of media to be stopped. For example, - * {@link MediaDirection#SENDRECV} to stop both capture and playback of - * media in this instance or {@link MediaDirection#SENDONLY} to only stop - * the capture of media in this instance - */ - private void stop(MediaDirection direction) - { - if (direction == null) - throw new NullPointerException("direction"); - - if (rtpManager == null) - return; - - if ((MediaDirection.SENDRECV.equals(direction) - || MediaDirection.SENDONLY.equals(direction)) - && (MediaDirection.SENDRECV.equals(startedDirection) - || MediaDirection.SENDONLY.equals(startedDirection))) - { - stopSendStreams(false); - - if (deviceSession != null) - deviceSession.stop(MediaDirection.SENDONLY); - - if (MediaDirection.SENDRECV.equals(startedDirection)) - startedDirection = MediaDirection.RECVONLY; - else if (MediaDirection.SENDONLY.equals(startedDirection)) - startedDirection = null; - } - - if ((MediaDirection.SENDRECV.equals(direction) - || MediaDirection.RECVONLY.equals(direction)) - && (MediaDirection.SENDRECV.equals(startedDirection) - || MediaDirection.RECVONLY.equals(startedDirection))) - { - stopReceiveStreams(); - - if (deviceSession != null) - deviceSession.stop(MediaDirection.RECVONLY); - - if (MediaDirection.SENDRECV.equals(startedDirection)) - startedDirection = MediaDirection.SENDONLY; - else if (MediaDirection.RECVONLY.equals(startedDirection)) - startedDirection = null; - } - } - - /** - * Stops the ReceiveStreams that this instance is receiving from - * its remote peer. By design, a MediaStream instance is associated - * with a single ReceiveStream at a time. However, the - * ReceiveStreams are created by RTPManager and it tracks - * multiple ReceiveStreams. In practice, the RTPManager of - * this MediaStreamImpl will have a single ReceiveStream - * in its list. - */ - @SuppressWarnings("unchecked") - private void stopReceiveStreams() - { - List receiveStreams; - - try - { - receiveStreams = rtpManager.getReceiveStreams(); - } - catch (Exception ex) - { - /* - * It appears that in early call states when there are no streams, a - * NullPointerException could be thrown. Make sure we handle it - * gracefully. - */ - if (logger.isTraceEnabled()) - logger.trace("Failed to retrieve receive streams", ex); - receiveStreams = null; - } - - if (receiveStreams != null) - { - /* - * It turns out that the receiveStreams list of rtpManager can be - * empty. As a workaround, use the receiveStreams of this instance. - */ - if (receiveStreams.isEmpty() && (this.receiveStreams != null)) - receiveStreams = this.receiveStreams; - - for (ReceiveStream receiveStream : receiveStreams) - { - try - { - if (logger.isTraceEnabled()) - logger.trace( - "Stopping receive stream with hashcode " - + receiveStream.hashCode()); - - DataSource receiveStreamDataSource - = receiveStream.getDataSource(); - - /* - * For an unknown reason, the stream DataSource can be null - * at the end of the Call after re-INVITEs have been - * handled. - */ - if (receiveStreamDataSource != null) - receiveStreamDataSource.stop(); - } - catch (IOException ioex) - { - logger.warn( - "Failed to stop receive stream " + receiveStream, - ioex); - } - } - } - } - - /** - * Stops the SendStreams that this instance is sending to its - * remote peer and optionally closes them. - * - * @param close true to close the SendStreams that this - * instance is sending to its remote peer after stopping them; - * false to only stop them - * @return the SendStreams which were stopped - */ - private Iterable stopSendStreams(boolean close) - { - if (rtpManager == null) - return null; - - @SuppressWarnings("unchecked") - Iterable sendStreams = rtpManager.getSendStreams(); - Iterable stoppedSendStreams - = stopSendStreams(sendStreams, close); - - if (close) - sendStreamsAreCreated = false; - - return stoppedSendStreams; - } - - /** - * Stops specific SendStreams and optionally closes them. - * - * @param sendStreams the SendStreams to be stopped and optionally - * closed - * @param close true to close the specified SendStreams - * after stopping them; false to only stop them - * @return the stopped SendStreams - */ - private Iterable stopSendStreams( - Iterable sendStreams, - boolean close) - { - if (sendStreams == null) - return null; - - for (SendStream sendStream : sendStreams) - try - { - if(logger.isTraceEnabled()) - logger.trace("Stopping send stream with hashcode " - + sendStream.hashCode()); - - sendStream.getDataSource().stop(); - sendStream.stop(); - - if (close) - try - { - sendStream.close(); - } - catch (NullPointerException npe) - { - /* - * Sometimes com.sun.media.rtp.RTCPTransmitter#bye() may - * throw NullPointerException but it does not seem to be - * guaranteed because it does not happen while debugging - * and stopping at a breakpoint on SendStream#close(). - * One of the cases in which it appears upon call - * hang-up is if we do not close the "old" SendStreams - * upon reinvite(s). Though we are now closing such - * SendStreams, ignore the exception here just in case - * because we already ignore IOExceptions. - */ - logger - .error( - "Failed to close stream " + sendStream, - npe); - } - } - catch (IOException ioe) - { - logger.warn("Failed to stop stream " + sendStream, ioe); - } - return sendStreams; - } - - /** - * Returns a human-readable representation of a specific DataSource - * instance in the form of a String value. - * - * @param dataSource the DataSource to return a human-readable - * representation of - * @return a String value which gives a human-readable - * representation of the specified dataSource - */ - public static String toString(DataSource dataSource) - { - StringBuffer str = new StringBuffer(); - - str.append(dataSource.getClass().getSimpleName()); - str.append(" with hashCode "); - str.append(dataSource.hashCode()); - - MediaLocator locator = dataSource.getLocator(); - - if (locator != null) - { - str.append(" and locator "); - str.append(locator); - } - return str.toString(); - } - - /** - * Notifies this ReceiveStreamListener that the RTPManager - * it is registered with has generated an event related to a ReceiveStream. - * - * @param event the ReceiveStreamEvent which specifies the - * ReceiveStream that is the cause of the event and the very type - * of the event - * @see ReceiveStreamListener#update(ReceiveStreamEvent) - */ - public void update(ReceiveStreamEvent event) - { - if (event instanceof NewReceiveStreamEvent) - { - ReceiveStream receiveStream = event.getReceiveStream(); - - if (receiveStream != null) - { - long receiveStreamSSRC = receiveStream.getSSRC(); - - if (logger.isTraceEnabled()) - { - logger.trace( - "Received new ReceiveStream with ssrc " - + receiveStreamSSRC); - } - - addRemoteSourceID(receiveStreamSSRC); - - synchronized (receiveStreams) - { - if (!receiveStreams.contains(receiveStream)) - { - receiveStreams.add(receiveStream); - - MediaDeviceSession deviceSession = getDeviceSession(); - - if (deviceSession != null) - deviceSession.addReceiveStream(receiveStream); - } - } - } - } - else if (event instanceof TimeoutEvent) - { - ReceiveStream receiveStream = event.getReceiveStream(); - - /* - * If we recreate streams, we will already have restarted - * zrtpControl. But when on the other end someone recreates his - * streams, we will receive a ByeEvent (which extends TimeoutEvent) - * and then we must also restart our ZRTP. This happens, for - * example, when we are already in a call and the remote peer - * converts his side of the call into a conference call. - */ - /* - if(!zrtpRestarted) - restartZrtpControl(); - */ - - if (receiveStream != null) - { - synchronized (receiveStreams) - { - if (receiveStreams.contains(receiveStream)) - { - receiveStreams.remove(receiveStream); - - MediaDeviceSession deviceSession = getDeviceSession(); - - if (deviceSession != null) - deviceSession.removeReceiveStream(receiveStream); - } - } - } - } - } - - /** - * Notifies this SendStreamListener that the RTPManager it - * is registered with has generated an event related to a SendStream. - * - * @param event the SendStreamEvent which specifies the - * SendStream that is the cause of the event and the very type of - * the event - * @see SendStreamListener#update(SendStreamEvent) - */ - public void update(SendStreamEvent event) - { - if (event instanceof NewSendStreamEvent) - { - long localSourceID = event.getSendStream().getSSRC(); - - if (getLocalSourceID() != localSourceID) - setLocalSourceID(localSourceID); - } - } - - /** - * Notifies this SessionListener that the RTPManager it is - * registered with has generated an event which pertains to the session as a - * whole and does not belong to a ReceiveStream or a - * SendStream or a remote participant necessarily. - * - * @param event the SessionEvent which specifies the source and the - * very type of the event - * @see SessionListener#update(SessionEvent) - */ - public void update(SessionEvent event) - { - // TODO Auto-generated method stub - } - - /** - * Method called back in the RemoteListener to notify - * listener of all RTP Remote Events.RemoteEvents are one of - * ReceiverReportEvent, SenderReportEvent or RemoteCollisionEvent - * - * @param remoteEvent the event - */ - public void update(RemoteEvent remoteEvent) - { - if(!logger.isInfoEnabled()) - return; - - if(remoteEvent instanceof SenderReportEvent) - { - numberOfReceivedSenderReports++; - - SenderReport report = - ((SenderReportEvent)remoteEvent).getReport(); - - Feedback feedback = null; - long remoteJitter = -1; - - if(report.getFeedbackReports().size() > 0) - { - feedback = (Feedback)report.getFeedbackReports().get(0); - - remoteJitter = feedback.getJitter(); - - if(remoteJitter < minRemoteInterArrivalJitter - ||minRemoteInterArrivalJitter == -1) - minRemoteInterArrivalJitter = remoteJitter; - - if(maxRemoteInterArrivalJitter < remoteJitter) - maxRemoteInterArrivalJitter = remoteJitter; - } - - // As sender reports are received on every 5 seconds - // print every 4th packet, on every 20 seconds - if(numberOfReceivedSenderReports%4 != 1) - return; - - StringBuilder buff - = new StringBuilder(StatisticsEngine.RTP_STAT_PREFIX); - MediaFormat format = getFormat(); - - buff.append("Received a report for ") - .append( - (format == null) - ? "" - : format.getMediaType().toString()) - .append(" stream SSRC:") - .append(getLocalSourceID()) - .append(" [packet count:") - .append(report.getSenderPacketCount()) - .append(", bytes:").append(report.getSenderByteCount()); - - if(feedback != null) - { - buff.append(", interarrival jitter:") - .append(remoteJitter) - .append(", lost packets:").append(feedback.getNumLost()) - .append(", time since previous report:") - .append((int) (feedback.getDLSR() / 65.536)) - .append("ms"); - } - buff.append(" ]"); - logger.info(buff); - } - } - - /** - * Sets the local SSRC identifier and fires the corresponding - * PropertyChangeEvent. - * - * @param localSourceID the SSRC identifier that this stream will be using - * in outgoing RTP packets from now on - */ - protected void setLocalSourceID(long localSourceID) - { - if (this.localSourceID != localSourceID) - { - Long oldValue = this.localSourceID; - - this.localSourceID = localSourceID; - - firePropertyChange(PNAME_LOCAL_SSRC, oldValue, this.localSourceID); - } - } - - /** - * Sets the remote SSRC identifier and fires the corresponding - * PropertyChangeEvent. - * - * @param remoteSourceID the SSRC identifier that this stream will be using - * in outgoing RTP packets from now on. - */ - protected void addRemoteSourceID(long remoteSourceID) - { - Long oldValue = getRemoteSourceID(); - - if(!remoteSourceIDs.contains(remoteSourceID)) - remoteSourceIDs.add(remoteSourceID); - - firePropertyChange(PNAME_REMOTE_SSRC, oldValue, remoteSourceID); - } - - /** - * Returns the list of CSRC identifiers for all parties currently known - * to contribute to the media that this stream is sending toward its remote - * counter part. In other words, the method returns the list of CSRC IDs - * that this stream will include in outgoing RTP packets. This method will - * return an null in case this stream is not part of a mixed - * conference call. - * - * @return a long[] array of CSRC IDs representing parties that are - * currently known to contribute to the media that this stream is sending - * or an null in case this MediaStream is not part of a - * conference call. - */ - public long[] getLocalContributingSourceIDs() - { - return localContributingSourceIDList; - } - - /** - * Returns the List of CSRC identifiers representing the parties - * contributing to the stream that we are receiving from this - * MediaStream's remote party. - * - * @return a List of CSRC identifiers representing the parties - * contributing to the stream that we are receiving from this - * MediaStream's remote party. - */ - public long[] getRemoteContributingSourceIDs() - { - long[] remoteSsrcList = getDeviceSession().getRemoteSSRCList(); - - // TODO implement - - return remoteSsrcList; - } - - /** - * Used to set the priority of the receive/send streams. Underling - * implementations can override this and return different than - * current default value. - * - * @return the priority for the current thread. - */ - protected int getPriority() - { - return Thread.currentThread().getPriority(); - } - - /** - * Prints all statistics available for {@link #rtpManager}. - * - * @param rtpManager the RTPManager to print statistics for - */ - private void printFlowStatistics(StreamRTPManager rtpManager) - { - try - { - if(!logger.isInfoEnabled()) - return; - - //print flow statistics. - GlobalTransmissionStats s = rtpManager.getGlobalTransmissionStats(); - - StringBuilder buff = - new StringBuilder(StatisticsEngine.RTP_STAT_PREFIX); - - buff.append("call stats for outgoing ") - .append(getFormat() != null ? getFormat().getMediaType() : "") - .append(" stream SSRC:") - .append(getLocalSourceID()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("bytes sent: ").append(s.getBytesSent()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("RTP sent: ").append(s.getRTPSent()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("remote reported min interarrival jitter : ") - .append(minRemoteInterArrivalJitter) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("remote reported max interarrival jitter : ") - .append(maxRemoteInterArrivalJitter) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("local collisions: ").append(s.getLocalColls()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("remote collisions: ").append(s.getRemoteColls()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("RTCP sent: ").append(s.getRTCPSent()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("transmit failed: ").append(s.getTransmitFailed()); - - logger.info(buff); - - GlobalReceptionStats rs = rtpManager.getGlobalReceptionStats(); - - buff = new StringBuilder(StatisticsEngine.RTP_STAT_PREFIX); - - buff.append("call stats for incoming ") - .append(getFormat() != null ? getFormat().getMediaType() : "") - .append(" stream SSRC:") - .append(getRemoteSourceID()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("packets received: ").append(rs.getPacketsRecd()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("bytes received: ").append(rs.getBytesRecd()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("packets lost: ").append(statisticsEngine.getLost()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("min interarrival jitter : ") - .append(statisticsEngine.getMinInterArrivalJitter()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("max interarrival jitter : ") - .append(statisticsEngine.getMaxInterArrivalJitter()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("RTCPs received: ").append(rs.getRTCPRecd()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("bad RTCP packets: ").append(rs.getBadRTCPPkts()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("bad RTP packets: ").append(rs.getBadRTPkts()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("local collisions: ").append(rs.getLocalColls()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("malformed BYEs: ").append(rs.getMalformedBye()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("malformed RRs: ").append(rs.getMalformedRR()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("malformed SDESs: ").append(rs.getMalformedSDES()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("malformed SRs: ").append(rs.getMalformedSR()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("packets looped: ").append(rs.getPacketsLooped()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("remote collisions: ").append(rs.getRemoteColls()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("SRRs received: ").append(rs.getSRRecd()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("transmit failed: ").append(rs.getTransmitFailed()) - .append("\n").append(StatisticsEngine.RTP_STAT_PREFIX) - .append("unknown types: ").append(rs.getUnknownTypes()); - - logger.info(buff); - } - catch(Throwable t) - { - logger.error("Error writing statistics", t); - } - } - - /** - * Sets the RTPTranslator which is to forward RTP and RTCP traffic - * between this and other MediaStreams. - * - * @param rtpTranslator the RTPTranslator which is to forward RTP - * and RTCP traffic between this and other MediaStreams - */ - public void setRTPTranslator(RTPTranslator rtpTranslator) - { - if (this.rtpTranslator != rtpTranslator) - { - this.rtpTranslator = rtpTranslator; - } - } - - /** - * Returns a MediaStreamStats object used to get statistics about this - * MediaStream. - * - * @return the MediaStreamStats object used to compute the statistics about - * this MediaStream. - */ - public MediaStreamStats getMediaStreamStats() - { - return this.mediaStreamStatsImpl; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/MediaStreamStatsImpl.java b/src/net/java/sip/communicator/impl/neomedia/MediaStreamStatsImpl.java deleted file mode 100644 index 340ce00d9..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/MediaStreamStatsImpl.java +++ /dev/null @@ -1,665 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.awt.*; -import java.net.*; - -import javax.media.format.*; -import javax.media.rtp.*; - -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.*; -import net.sf.fmj.media.rtp.*; - -/** - * Class used to compute stats concerning a MediaStream. - * - * @author Vincent Lucas - */ -public class MediaStreamStatsImpl - implements MediaStreamStats -{ - - /** - * Enumeation of the direction (DOWNLOAD or UPLOAD) used for the stats. - */ - private enum StreamDirection - { - DOWNLOAD, - UPLOAD - } - - /** - * The MediaStream used to copte the stats. - */ - private MediaStreamImpl mediaStreamImpl; - - /** - * The last time these stats have been updated. - */ - private long updateTimeMs; - - /** - * The last number of received/sent packets. - */ - private long[] nbPackets = {0, 0}; - - /** - * The last number of sent packets when the last feedback has been received. - * This counter is used to compute the upload loss rate. - */ - private long uploadFeedbackNbPackets = 0; - - /** - * The last number of download/upload lost packets. - */ - private long[] nbLost = {0, 0}; - - /** - * The last number of received/sent Bytes. - */ - private long[] nbByte = {0, 0}; - - /** - * The last download/upload loss rate computed (in %). - */ - private double[] percentLoss = {0, 0}; - - /** - * The last used bandwidth computed in download/upload (in Kbit/s). - */ - private double[] rateKiloBitPerSec = {0, 0}; - - /** - * The last jitter received/sent in a RTCP feedback (in RTP timestamp - * units). - */ - private double[] jitterRTPTimestampUnits = {0, 0}; - - /** - * Creates a new instance of stats concerning a MediaStream. - * - * @param mediaStreamImpl The MediaStreamImpl used to compute the stats. - */ - public MediaStreamStatsImpl(MediaStreamImpl mediaStreamImpl) - { - this.updateTimeMs = System.currentTimeMillis(); - this.mediaStreamImpl = mediaStreamImpl; - } - - /** - * Computes and updates information for a specific stream. - */ - public void updateStats() - { - // Gets the current time. - long currentTimeMs = System.currentTimeMillis(); - - // UPdates stats for the download stream. - this.updateStreamDirectionStats( - StreamDirection.DOWNLOAD, - currentTimeMs); - // UPdates stats for the upload stream. - this.updateStreamDirectionStats( - StreamDirection.UPLOAD, - currentTimeMs); - - // Saves the last update values. - this.updateTimeMs = currentTimeMs; - } - - /** - * Computes and updates information for a specific stream. - * - * @param streamDirection The stream direction (DOWNLOAD or UPLOAD) of the - * stream from which this function updates the stats. - * @param currentTime The current time in ms. - */ - private void updateStreamDirectionStats( - StreamDirection streamDirection, - long currentTimeMs) - { - int streamDirectionIndex = streamDirection.ordinal(); - - // Gets the current number of packets correctly received since the - // beginning of this stream. - long newNbRecv = this.getNbPDU(streamDirection); - // Gets the number of byte received/sent since the beginning of this - // stream. - long newNbByte = this.getNbBytes(streamDirection); - - // Computes the number of update steps which has not been done since - // last update. - long nbSteps = newNbRecv - this.nbPackets[streamDirectionIndex]; - // Even if the remote peer does not send any packets (i.e. is - // microphone is muted), Jitsi must updates it stats. Thus, Jitsi - // computes a number of steps equivalent as if Jitsi receives a packet - // each 20ms (default value). - if(nbSteps == 0) - { - nbSteps = (currentTimeMs - this.updateTimeMs) / 20; - } - - // The upload percentLoss is only computed when a new RTCP feedback is - // received. This is not the case for the download percentLoss which is - // updated for each new RTP packet received. - // Computes the loss rate for this stream. - if(streamDirection == StreamDirection.DOWNLOAD) - { - // Gets the current number of losses in download since the beginning - // of this stream. - long newNbLost = - this.getDownloadNbPDULost() - this.nbLost[streamDirectionIndex]; - - updateNbLoss(streamDirection, newNbLost, nbSteps + newNbLost); - } - - // Computes the bandwidth used by this stream. - double newRateKiloBitPerSec = - MediaStreamStatsImpl.computeRateKiloBitPerSec( - newNbByte - this.nbByte[streamDirectionIndex], - currentTimeMs - this.updateTimeMs); - this.rateKiloBitPerSec[streamDirectionIndex] = - MediaStreamStatsImpl.computeEWMA( - nbSteps, - this.rateKiloBitPerSec[streamDirectionIndex], - newRateKiloBitPerSec); - - // Saves the last update values. - this.nbPackets[streamDirectionIndex] = newNbRecv; - this.nbByte[streamDirectionIndex] = newNbByte; - } - - /** - * Returns the local IP address of the MediaStream. - * - * @return the local IP address of the stream. - */ - public String getLocalIPAddress() - { - InetSocketAddress mediaStreamLocalDataAddress = - mediaStreamImpl.getLocalDataAddress(); - if(mediaStreamLocalDataAddress == null) - { - return null; - } - return mediaStreamLocalDataAddress.getAddress().getHostAddress(); - } - - /** - * Returns the local port of the MediaStream. - * - * @return the local port of the stream. - */ - public int getLocalPort() - { - InetSocketAddress mediaStreamLocalDataAddress = - mediaStreamImpl.getLocalDataAddress(); - if(mediaStreamLocalDataAddress == null) - { - return -1; - } - return mediaStreamLocalDataAddress.getPort(); - } - - /** - * Returns the remote IP address of the MediaStream. - * - * @return the remote IP address of the stream. - */ - public String getRemoteIPAddress() - { - MediaStreamTarget mediaStreamTarget = mediaStreamImpl.getTarget(); - // Stops if the endpoint is disconnected. - if(mediaStreamTarget == null) - { - return null; - } - // Gets this stream IP address endpoint. - return mediaStreamTarget.getDataAddress().getAddress().getHostAddress(); - } - - /** - * Returns the remote port of the MediaStream. - * - * @return the remote port of the stream. - */ - public int getRemotePort() - { - MediaStreamTarget mediaStreamTarget = mediaStreamImpl.getTarget(); - // Stops if the endpoint is disconnected. - if(mediaStreamTarget == null) - { - return -1; - } - // Gets this stream port endpoint. - return mediaStreamTarget.getDataAddress().getPort(); - } - - /** - * Returns the MediaStream enconding. - * - * @return the encoding used by the stream. - */ - public String getEncoding() - { - // Gets this stream encoding. - return mediaStreamImpl.getFormat().getEncoding(); - } - - /** - * Returns the MediaStream enconding rate (in Hz).. - * - * @return the encoding rate used by the stream. - */ - public String getEncodingClockRate() - { - // Gets this stream encoding clock rate. - return mediaStreamImpl.getFormat().getRealUsedClockRateString(); - } - - /** - * Returns the upload video format if this stream uploads a video, or null - * if not. - * - * @return the upload video format if this stream uploads a video, or null - * if not. - */ - private VideoFormat getUploadVideoFormat() - { - MediaDeviceSession mediaDeviceSession - = mediaStreamImpl.getDeviceSession(); - - return - (mediaDeviceSession instanceof VideoMediaDeviceSession) - ? ((VideoMediaDeviceSession) mediaDeviceSession) - .getSentVideoFormat() - : null; - } - - /** - * Returns the download video format if this stream downloads a video, or - * null if not. - * - * @return the download video format if this stream downloads a video, or - * null if not. - */ - private VideoFormat getDownloadVideoFormat() - { - MediaDeviceSession mediaDeviceSession - = mediaStreamImpl.getDeviceSession(); - - return - (mediaDeviceSession instanceof VideoMediaDeviceSession) - ? ((VideoMediaDeviceSession) mediaDeviceSession) - .getReceivedVideoFormat() - : null; - } - - /** - * Returns the upload video size if this stream uploads a video, or null if - * not. - * - * @return the upload video size if this stream uploads a video, or null if - * not. - */ - public Dimension getUploadVideoSize() - { - Dimension videoSize = null; - VideoFormat format = this.getUploadVideoFormat(); - if(format != null) - { - videoSize = format.getSize(); - } - return videoSize; - } - - /** - * Returns the download video size if this stream downloads a video, or - * null if not. - * - * @return the download video size if this stream downloads a video, or null - * if not. - */ - public Dimension getDownloadVideoSize() - { - Dimension videoSize = null; - VideoFormat format = this.getDownloadVideoFormat(); - if(format != null) - { - videoSize = format.getSize(); - } - return videoSize; - } - - /** - * Returns the percent loss of the download stream. - * - * @return the last loss rate computed (in %). - */ - public double getDownloadPercentLoss() - { - return this.percentLoss[StreamDirection.DOWNLOAD.ordinal()]; - } - - /** - * Returns the percent loss of the upload stream. - * - * @return the last loss rate computed (in %). - */ - public double getUploadPercentLoss() - { - return this.percentLoss[StreamDirection.UPLOAD.ordinal()]; - } - - /** - * Returns the bandwidth used by this download stream. - * - * @return the last used download bandwidth computed (in Kbit/s). - */ - public double getDownloadRateKiloBitPerSec() - { - return this.rateKiloBitPerSec[StreamDirection.DOWNLOAD.ordinal()]; - } - - /** - * Returns the bandwidth used by this download stream. - * - * @return the last used upload bandwidth computed (in Kbit/s). - */ - public double getUploadRateKiloBitPerSec() - { - return this.rateKiloBitPerSec[StreamDirection.UPLOAD.ordinal()]; - } - - /** - * Returns the jitter average of this download stream. - * - * @return the last jitter average computed (in ms). - */ - public double getDownloadJitterMs() - { - return this.getJitterMs(StreamDirection.DOWNLOAD); - } - - /** - * Returns the jitter average of this upload stream. - * - * @return the last jitter average computed (in ms). - */ - public double getUploadJitterMs() - { - return this.getJitterMs(StreamDirection.UPLOAD); - } - - /** - * Returns the jitter average of this upload/download stream. - * - * @param streamDirection The stream direction (DOWNLOAD or UPLOAD) of the - * stream from which this function retrieve the jitter. - * - * @return the last jitter average computed (in ms). - */ - private double getJitterMs(StreamDirection streamDirection) - { - double mediaFormatClockRate = - this.mediaStreamImpl.getFormat().getClockRate(); - - // RFC3550 says that concerning the RTP timestamp unit (cf. section 5.1 - // RTP Fixed Header Fields, subsection timestamp: 32 bits): - // As an example, for fixed-rate audio the timestamp clock would likely - // increment by one for each sampling period. - // - // Thus we take the jitter (in RTP timestamp units), converts it to - // seconds (deivision by the codec clock rate) and finally converts it - // in Ms (* 1000). - return (this.jitterRTPTimestampUnits[streamDirection.ordinal()] - / mediaFormatClockRate) * 1000.0; - } - - /** - * Updates the jitter stream stats with the new feedback sent. - * - * @param feedback The last RTCP feedback sent by the MediaStream. - * @param streamDirection The stream direction (DOWNLOAD or UPLOAD) of the - * stream from which this function retrieve the jitter. - */ - private void updateJitterRTPTimestampUnits( - RTCPFeedback feedback, - StreamDirection streamDirection) - { - // Updates the download jitter in RTP timestamp units. - // There is no need to compute a jitter average, since (cf. RFC3550, - // section 6.4.1 SR: Sender Report RTCP Packet, subsection interarrival - // jitter: 32 bits) the value contained in the RTCP sender report packet - // contains a mean deviation of the jitter. - this.jitterRTPTimestampUnits[streamDirection.ordinal()] = - feedback.getJitter(); - } - - /** - * Updates this stream stats with the new feedback sent. - * - * @param feedback The last RTCP feedback sent by the MediaStream. - */ - public void updateNewSentFeedback(RTCPFeedback feedback) - { - updateJitterRTPTimestampUnits(feedback, StreamDirection.DOWNLOAD); - - // No need to update the download loss has we have a more accurate value - // in the global reception stats, which are updated for each new packet - // received. - } - - /** - * Updates this stream stats with the new feedback received. - * - * @param feedback The last RTCP feedback received by the MediaStream. - */ - public void updateNewReceivedFeedback(RTCPFeedback feedback) - { - StreamDirection streamDirection = StreamDirection.UPLOAD; - - updateJitterRTPTimestampUnits(feedback, streamDirection); - - // Updates the loss rate with the RTCP sender report feedback, since - // this is the only information source available for the upalod stream. - long uploadNewNbRecv = feedback.getXtndSeqNum(); - long newNbLost = - feedback.getNumLost() - this.nbLost[streamDirection.ordinal()]; - long nbSteps = uploadNewNbRecv - this.uploadFeedbackNbPackets; - - updateNbLoss(streamDirection, newNbLost, nbSteps); - - // Updates the upload loss counters. - this.uploadFeedbackNbPackets = uploadNewNbRecv; - } - - /** - * Updates the number of loss for a given stream. - * - * @param streamDirection The stream direction (DOWNLOAD or UPLOAD) of the - * stream from which this function updates the stats. - * @param newNbLost The last update of the number of lost. - * @param nbSteps The number of elasped steps since the last number of loss - * update. - */ - private void updateNbLoss( - StreamDirection streamDirection, - long newNbLost, - long nbSteps) - { - int streamDirectionIndex = streamDirection.ordinal(); - - double newPercentLoss = MediaStreamStatsImpl.computePercentLoss( - nbSteps, - newNbLost); - this.percentLoss[streamDirectionIndex] = - MediaStreamStatsImpl.computeEWMA( - nbSteps, - this.percentLoss[streamDirectionIndex], - newPercentLoss); - - // Saves the last update number download lost value. - this.nbLost[streamDirectionIndex] += newNbLost; - } - - /** - * Computes the loss rate. - * - * @param nbLostAndRecv The number of lost and received packets. - * @param nbLost The number of lost packets. - * - * @return The loss rate in percent. - */ - private static double computePercentLoss(long nbLostAndRecv, long nbLost) - { - if(nbLostAndRecv == 0) - { - return 0; - } - return ((double) 100 * nbLost) / ((double)(nbLostAndRecv)); - } - - /** - * Computes the bandwidth usage in Kilo bits per secondes. - * - * @param nbByteRecv The number of Byte received. - * @param callNbTimeMsSpent The time spent since the mediaStreamImpl is - * connected to the endpoint. - * - * @return the bandwidth rate computed in Kilo bits per secondes. - */ - private static double computeRateKiloBitPerSec( - long nbByteRecv, - long callNbTimeMsSpent) - { - if(nbByteRecv == 0) - { - return 0; - } - return (nbByteRecv * 8.0 / 1000.0) / (callNbTimeMsSpent / 1000.0); - } - - /** - * Computes an Exponentially Weighted Moving Average (EWMA). Thus, the most - * recent history has a more preponderant importance in the average - * computed. - * - * @param nbStepSinceLastUpdate The number of step which has not been - * computed since last update. In our case the number of packets received - * since the last computation. - * @param lastValue The value computed during the last update. - * @param newValue The value newly computed. - * - * @return The EWMA average computed. - */ - private static double computeEWMA( - long nbStepSinceLastUpdate, - double lastValue, - double newValue) - { - // For each new packet received the EWMA moves by a 0.1 coefficient. - double EWMACoeff = 0.01 * nbStepSinceLastUpdate; - // EWMA must be <= 1. - if(EWMACoeff > 1) - { - EWMACoeff = 1.0; - } - return lastValue * (1.0 - EWMACoeff) + newValue * EWMACoeff; - - } - - /** - * Returns the number of Protocol Data Units (PDU) sent/received since the - * beginning of the session. - * - * @param streamDirection The stream direction (DOWNLOAD or UPLOAD) of the - * stream from which this function retrieve the number of sent/received - * packets. - * - * @return the number of packets sent/received for this stream. - */ - private long getNbPDU(StreamDirection streamDirection) - { - long nbPDU = 0; - StreamRTPManager rtpManager = this.mediaStreamImpl.getRTPManager(); - - if(rtpManager != null) - { - switch(streamDirection) - { - case UPLOAD: - nbPDU = - rtpManager.getGlobalTransmissionStats().getRTPSent(); - break; - case DOWNLOAD: - GlobalReceptionStats globalReceptionStats = - rtpManager.getGlobalReceptionStats(); - nbPDU = - globalReceptionStats.getPacketsRecd() - - globalReceptionStats.getRTCPRecd(); - break; - } - } - return nbPDU; - } - - /** - * Returns the number of Protocol Data Units (PDU) lost in download since - * the beginning of the session. - * - * @return the number of packets lost for this stream. - */ - private long getDownloadNbPDULost() - { - int nbLost = 0; - java.util.List listReceiveStream = - this.mediaStreamImpl.getDeviceSession().getReceiveStreams(); - - for(int i = 0; i < listReceiveStream.size(); ++i) - { - ReceiveStream receiveStream = listReceiveStream.get(i); - nbLost += receiveStream.getSourceReceptionStats().getPDUlost(); - } - - return nbLost; - } - - /** - * Returns the number of sent/received bytes since the beginning of the - * session. - * - * @param streamDirection The stream direction (DOWNLOAD or UPLOAD) of the - * stream from which this function retrieve the number of sent/received - * bytes. - * - * @return the number of sent/received bytes for this stream. - */ - private long getNbBytes(StreamDirection streamDirection) - { - long nbBytes = 0; - StreamRTPManager rtpManager = this.mediaStreamImpl.getRTPManager(); - - if(rtpManager != null) - { - switch(streamDirection) - { - case DOWNLOAD: - nbBytes = - rtpManager.getGlobalReceptionStats().getBytesRecd(); - break; - case UPLOAD: - nbBytes = - rtpManager.getGlobalTransmissionStats().getBytesSent(); - break; - } - } - return nbBytes; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/MediaUtils.java b/src/net/java/sip/communicator/impl/neomedia/MediaUtils.java deleted file mode 100644 index 91b4d29c8..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/MediaUtils.java +++ /dev/null @@ -1,826 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.util.*; - -import javax.media.*; -import javax.media.format.*; -import javax.sdp.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.codec.video.h264.*; -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.impl.neomedia.format.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.format.*; -import net.java.sip.communicator.util.*; - -/** - * Implements static utility methods used by media classes. - * - * @author Emil Ivov - * @author Lyubomir Marinov - */ -public class MediaUtils -{ - /** - * The constant which stands for an empty array of MediaFormats. - * Explicitly defined in order to reduce unnecessary allocations. - */ - public static final MediaFormat[] EMPTY_MEDIA_FORMATS = new MediaFormat[0]; - - /** - * The maximum number of channels for audio that is available through - * MediaUtils. - */ - public static final int MAX_AUDIO_CHANNELS; - - /** - * The maximum sample rate for audio that is available through - * MediaUtils. - */ - public static final double MAX_AUDIO_SAMPLE_RATE; - - /** - * The maximum sample size in bits for audio that is available through - * MediaUtils. - */ - public static final int MAX_AUDIO_SAMPLE_SIZE_IN_BITS; - - /** - * The Map of JMF-specific encodings to well-known encodings as - * defined in RFC 3551. - */ - private static final Map jmfEncodingToEncodings - = new HashMap(); - - /** - * The MediaFormats which do not have RTP payload types assigned by - * RFC 3551 and are thus referred to as having dynamic RTP payload types. - */ - private static final List rtpPayloadTypelessMediaFormats - = new ArrayList(); - - /** - * The Map of RTP payload types (expressed as Strings) to - * MediaFormats. - */ - private static final Map - rtpPayloadTypeStrToMediaFormats - = new HashMap(); - - static - { - addMediaFormats( - (byte) SdpConstants.PCMU, - "PCMU", - MediaType.AUDIO, - AudioFormat.ULAW_RTP, - 8000); - - /* - * Some codecs depend on JMF native libraries which are only available - * on 32-bit Linux and 32-bit Windows. - */ - if(OSUtils.IS_LINUX32 || OSUtils.IS_WINDOWS32) - { - Map g723FormatParams - = new HashMap(); - g723FormatParams.put("annexa", "no"); - g723FormatParams.put("bitrate", "6.3"); - addMediaFormats( - (byte) SdpConstants.G723, - "G723", - MediaType.AUDIO, - AudioFormat.G723_RTP, - g723FormatParams, - null, - 8000); - } - - addMediaFormats( - (byte) SdpConstants.GSM, - "GSM", - MediaType.AUDIO, - AudioFormat.GSM_RTP, - 8000); - addMediaFormats( - (byte) SdpConstants.DVI4_8000, - "DVI4", - MediaType.AUDIO, - AudioFormat.DVI_RTP, - 8000); - addMediaFormats( - (byte) SdpConstants.DVI4_16000, - "DVI4", - MediaType.AUDIO, - AudioFormat.DVI_RTP, - 16000); - addMediaFormats( - (byte) SdpConstants.PCMA, - "PCMA", - MediaType.AUDIO, - Constants.ALAW_RTP, - 8000); - addMediaFormats( - MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN, - "iLBC", - MediaType.AUDIO, - Constants.ILBC_RTP, - 8000); - addMediaFormats( - MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN, - "speex", - MediaType.AUDIO, - Constants.SPEEX_RTP, - 8000, 16000, 32000); - addMediaFormats( - (byte) SdpConstants.G722, - "G722", - MediaType.AUDIO, - Constants.G722_RTP, - 8000); - if (EncodingConfiguration.G729) - { - addMediaFormats( - (byte) SdpConstants.G729, - "G729", - MediaType.AUDIO, - AudioFormat.G729_RTP, - 8000); - } - addMediaFormats( - MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN, - "SILK", - MediaType.AUDIO, - Constants.SILK_RTP, - 8000, 12000, 16000, 24000); - addMediaFormats( - MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN, - "telephone-event", - MediaType.AUDIO, - Constants.TELEPHONE_EVENT, - 8000); - - /* - * We don't really support these. - * - addMediaFormats( - (byte) SdpConstants.JPEG, - "JPEG", - MediaType.VIDEO, - VideoFormat.JPEG_RTP); - addMediaFormats( - (byte) SdpConstants.H263, - "H263", - MediaType.VIDEO, - VideoFormat.H263_RTP); - addMediaFormats( - (byte) SdpConstants.H261, - "H261", - MediaType.VIDEO, - VideoFormat.H261_RTP); - */ - - /* H264 */ - Map h264FormatParams - = new HashMap(); - String packetizationMode = "packetization-mode"; - Map h264AdvancedAttributes - = new HashMap(); - - /* - * Disable PLI since we use the periodic intra-refresh feature of - * FFmpeg/x264. - */ - //h264AdvancedAttributes.put("rtcp-fb", "nack pli"); - - /* - * XXX The initialization of MediaServiceImpl is very complex so it is - * wise to not reference it at the early stage of its initialization. - */ - ScreenDevice screen = ScreenDeviceImpl.getDefaultScreenDevice(); - java.awt.Dimension res = (screen == null) ? null : screen.getSize(); - - h264AdvancedAttributes.put("imageattr", createImageAttr(null, res)); - - // packetization-mode=1 - h264FormatParams.put(packetizationMode, "1"); - - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - - if ((cfg == null) - || cfg - .getString( - "net.java.sip.communicator.impl.neomedia" - + ".codec.video.h264.defaultProfile", - JNIEncoder.MAIN_PROFILE) - .equals(JNIEncoder.MAIN_PROFILE)) - { - // main profile, common features, HD capable level 3.1 - h264FormatParams.put("profile-level-id", "4DE01f"); - } - else - { - // baseline profile, common features, HD capable level 3.1 - h264FormatParams.put("profile-level-id", "42E01f"); - } - - addMediaFormats( - MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN, - "H264", - MediaType.VIDEO, - Constants.H264_RTP, - h264FormatParams, - h264AdvancedAttributes); - /* - * XXX Android's current video CaptureDevice is based on MediaRecorder - * and provides support for packetization-mode=1 only. - */ - if (!OSUtils.IS_ANDROID) - { - // packetization-mode=0 - /* - * XXX At the time of this writing, - * EncodingConfiguration#compareEncodingPreferences(MediaFormat, - * MediaFormat) is incomplete and considers two MediaFormats to be equal - * if they have an equal number of format parameters (given that the - * encodings and clock rates are equal, of course). Either fix the - * method in question or don't add a format parameter for packetization - * mode 0 (which is equivalent to having packetization-mode explicitly - * defined as 0 anyway, according to the respective RFC). - */ - h264FormatParams.remove(packetizationMode); - addMediaFormats( - MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN, - "H264", - MediaType.VIDEO, - Constants.H264_RTP, - h264FormatParams, - h264AdvancedAttributes); - } - - /* H263+ */ - Map h263FormatParams - = new HashMap(); - Map h263AdvancedAttributes - = new LinkedHashMap(); - - /* - * The maximum resolution we can receive is the size of our screen - * device. - */ - if (res != null) - h263FormatParams.put("CUSTOM", res.width + "," + res.height + ",2"); - h263FormatParams.put("VGA", "2"); - h263FormatParams.put("CIF", "1"); - h263FormatParams.put("QCIF", "1"); - - addMediaFormats( - MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN, - "H263-1998", - MediaType.VIDEO, - Constants.H263P_RTP, - h263FormatParams, - h263AdvancedAttributes); - - // Calculate the values of the MAX_AUDIO_* static fields of MediaUtils. - List audioMediaFormats - = new ArrayList( - rtpPayloadTypeStrToMediaFormats.size() - + rtpPayloadTypelessMediaFormats.size()); - - for (MediaFormat[] mediaFormats - : rtpPayloadTypeStrToMediaFormats.values()) - for (MediaFormat mediaFormat : mediaFormats) - if (MediaType.AUDIO.equals(mediaFormat.getMediaType())) - audioMediaFormats.add(mediaFormat); - for (MediaFormat mediaFormat : rtpPayloadTypelessMediaFormats) - if (MediaType.AUDIO.equals(mediaFormat.getMediaType())) - audioMediaFormats.add(mediaFormat); - - int maxAudioChannels = Format.NOT_SPECIFIED; - double maxAudioSampleRate = Format.NOT_SPECIFIED; - int maxAudioSampleSizeInBits = Format.NOT_SPECIFIED; - - for (MediaFormat mediaFormat : audioMediaFormats) - { - AudioMediaFormatImpl audioMediaFormat - = (AudioMediaFormatImpl) mediaFormat; - int channels = audioMediaFormat.getChannels(); - double sampleRate = audioMediaFormat.getClockRate(); - int sampleSizeInBits - = audioMediaFormat.getFormat().getSampleSizeInBits(); - - if (maxAudioChannels < channels) - maxAudioChannels = channels; - if (maxAudioSampleRate < sampleRate) - maxAudioSampleRate = sampleRate; - if (maxAudioSampleSizeInBits < sampleSizeInBits) - maxAudioSampleSizeInBits = sampleSizeInBits; - } - - MAX_AUDIO_CHANNELS = maxAudioChannels; - MAX_AUDIO_SAMPLE_RATE = maxAudioSampleRate; - MAX_AUDIO_SAMPLE_SIZE_IN_BITS = maxAudioSampleSizeInBits; - } - - /** - * Adds a new mapping of a specific RTP payload type to a list of - * MediaFormats of a specific MediaType, with a specific - * JMF encoding and, optionally, with specific clock rates. - * - * @param rtpPayloadType the RTP payload type to be associated with a list - * of MediaFormats - * @param encoding the well-known encoding (name) corresponding to - * rtpPayloadType (in contrast to the JMF-specific encoding - * specified by jmfEncoding) - * @param mediaType the MediaType of the MediaFormats to - * be associated with rtpPayloadType - * @param jmfEncoding the JMF encoding of the MediaFormats to be - * associated with rtpPayloadType - * @param clockRates the optional list of clock rates of the - * MediaFormats to be associated with rtpPayloadType - */ - private static void addMediaFormats( - byte rtpPayloadType, - String encoding, - MediaType mediaType, - String jmfEncoding, - double... clockRates) - { - addMediaFormats( - rtpPayloadType, - encoding, - mediaType, - jmfEncoding, - null, - null, - clockRates); - } - - /** - * Adds a new mapping of a specific RTP payload type to a list of - * MediaFormats of a specific MediaType, with a specific - * JMF encoding and, optionally, with specific clock rates. - * - * @param rtpPayloadType the RTP payload type to be associated with a list - * of MediaFormats - * @param encoding the well-known encoding (name) corresponding to - * rtpPayloadType (in contrast to the JMF-specific encoding - * specified by jmfEncoding) - * @param mediaType the MediaType of the MediaFormats to - * be associated with rtpPayloadType - * @param jmfEncoding the JMF encoding of the MediaFormats to be - * associated with rtpPayloadType - * @param formatParameters the set of format-specific parameters of the - * MediaFormats to be associated with rtpPayloadType - * @param advancedAttributes the set of advanced attributes of the - * MediaFormats to be associated with rtpPayload - * @param clockRates the optional list of clock rates of the - * MediaFormats to be associated with rtpPayloadType - */ - @SuppressWarnings("unchecked") - private static void addMediaFormats( - byte rtpPayloadType, - String encoding, - MediaType mediaType, - String jmfEncoding, - Map formatParameters, - Map advancedAttributes, - double... clockRates) - { - int clockRateCount = clockRates.length; - List mediaFormats - = new ArrayList(clockRateCount); - - if (clockRateCount > 0) - { - for (double clockRate : clockRates) - { - Format format; - - switch (mediaType) - { - case AUDIO: - format = new AudioFormat(jmfEncoding); - break; - case VIDEO: - format - = new ParameterizedVideoFormat( - jmfEncoding, - formatParameters); - break; - default: - throw new IllegalArgumentException("mediaType"); - } - - MediaFormat mediaFormat - = MediaFormatImpl.createInstance( - format, - clockRate, - formatParameters, - advancedAttributes); - - if (mediaFormat != null) - mediaFormats.add(mediaFormat); - } - } - else - { - Format format; - double clockRate; - - switch (mediaType) - { - case AUDIO: - AudioFormat audioFormat = new AudioFormat(jmfEncoding); - - format = audioFormat; - clockRate = audioFormat.getSampleRate(); - break; - case VIDEO: - format - = new ParameterizedVideoFormat( - jmfEncoding, - formatParameters); - clockRate = VideoMediaFormatImpl.DEFAULT_CLOCK_RATE; - break; - default: - throw new IllegalArgumentException("mediaType"); - } - - MediaFormat mediaFormat - = MediaFormatImpl.createInstance( - format, - clockRate, - formatParameters, - advancedAttributes); - - if (mediaFormat != null) - mediaFormats.add(mediaFormat); - } - - if (mediaFormats.size() > 0) - { - if (MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN == rtpPayloadType) - rtpPayloadTypelessMediaFormats.addAll(mediaFormats); - else - rtpPayloadTypeStrToMediaFormats.put( - Byte.toString(rtpPayloadType), - mediaFormats.toArray(EMPTY_MEDIA_FORMATS)); - - jmfEncodingToEncodings.put( - ((MediaFormatImpl) mediaFormats.get(0)) - .getJMFEncoding(), - encoding); - } - } - - /** - * Gets a MediaFormat predefined in MediaUtils which - * represents a specific JMF Format. If there is no such - * representing MediaFormat in MediaUtils, returns - * null. - * - * @param format the JMF Format to get the MediaFormat - * representation for - * @return a MediaFormat predefined in MediaUtils which - * represents format if any; null if there is no such - * representing MediaFormat in MediaUtils - */ - @SuppressWarnings("unchecked") - public static MediaFormat getMediaFormat(Format format) - { - double clockRate; - - if (format instanceof AudioFormat) - clockRate = ((AudioFormat) format).getSampleRate(); - else if (format instanceof VideoFormat) - clockRate = VideoMediaFormatImpl.DEFAULT_CLOCK_RATE; - else - clockRate = Format.NOT_SPECIFIED; - - byte rtpPayloadType = getRTPPayloadType(format.getEncoding(), clockRate); - - if (MediaFormatImpl.RTP_PAYLOAD_TYPE_UNKNOWN != rtpPayloadType) - { - for (MediaFormat mediaFormat : getMediaFormats(rtpPayloadType)) - { - MediaFormatImpl mediaFormatImpl - = (MediaFormatImpl) mediaFormat; - - if (format.matches(mediaFormatImpl.getFormat())) - return mediaFormat; - } - } - return null; - } - - /** - * Gets the MediaFormat known to MediaUtils and having the - * specified well-known encoding (name) and clockRate. - * - * @param encoding the well-known encoding (name) of the - * MediaFormat to get - * @param clockRate the clock rate of the MediaFormat to get - * @return the MediaFormat known to MediaUtils and having - * the specified encoding and clockRate - */ - public static MediaFormat getMediaFormat(String encoding, double clockRate) - { - return getMediaFormat(encoding, clockRate, null); - } - - /** - * Gets the MediaFormat known to MediaUtils and having the - * specified well-known encoding (name), clockRate and - * matching format parameters. - * - * @param encoding the well-known encoding (name) of the - * MediaFormat to get - * @param clockRate the clock rate of the MediaFormat to get - * @param fmtps the format parameters of the MediaFormat to get - * @return the MediaFormat known to MediaUtils and having - * the specified encoding (name), clockRate and matching - * format parameters - */ - public static MediaFormat getMediaFormat( - String encoding, double clockRate, - Map fmtps) - { - for (MediaFormat format : getMediaFormats(encoding)) - if ((format.getClockRate() == clockRate) - && format.formatParametersMatch(fmtps)) - return format; - return null; - } - - /** - * Gets the index of a specific MediaFormat instance within the - * internal storage of MediaUtils. Since the index is in the - * internal storage which may or may not be one and the same for the various - * MediaFormat instances and which may or may not be searched for - * the purposes of determining the index, the index is not to be used as a - * way to determine whether MediaUtils knows the specified - * mediaFormat - * - * @param mediaFormat the MediaFormat to determine the index of - * @return the index of the specified mediaFormat in the internal - * storage of MediaUtils - */ - public static int getMediaFormatIndex(MediaFormat mediaFormat) - { - return rtpPayloadTypelessMediaFormats.indexOf(mediaFormat); - } - - /** - * Gets the MediaFormats predefined in MediaUtils with a - * specific well-known encoding (name) as defined by RFC 3551 "RTP Profile - * for Audio and Video Conferences with Minimal Control". - * - * @param encoding the well-known encoding (name) to get the corresponding - * MediaFormats of - * @return a List of MediaFormats corresponding to the - * specified encoding (name) - */ - @SuppressWarnings("unchecked") - public static List getMediaFormats(String encoding) - { - String jmfEncoding = null; - - for (Map.Entry jmfEncodingToEncoding - : jmfEncodingToEncodings.entrySet()) - if (jmfEncodingToEncoding.getValue().equals(encoding)) - { - jmfEncoding = jmfEncodingToEncoding.getKey(); - break; - } - - List mediaFormats = new ArrayList(); - - if (jmfEncoding != null) - { - for (MediaFormat[] rtpPayloadTypeMediaFormats - : rtpPayloadTypeStrToMediaFormats.values()) - for (MediaFormat rtpPayloadTypeMediaFormat - : rtpPayloadTypeMediaFormats) - if (((MediaFormatImpl) - rtpPayloadTypeMediaFormat) - .getJMFEncoding().equals(jmfEncoding)) - mediaFormats.add(rtpPayloadTypeMediaFormat); - - - if (mediaFormats.size() < 1) - { - for (MediaFormat rtpPayloadTypelessMediaFormat - : rtpPayloadTypelessMediaFormats) - if (((MediaFormatImpl) - rtpPayloadTypelessMediaFormat) - .getJMFEncoding().equals(jmfEncoding)) - mediaFormats.add(rtpPayloadTypelessMediaFormat); - } - } - return mediaFormats; - } - - /** - * Gets the MediaFormats known to MediaUtils and being of - * the specified MediaType. - * - * @param mediaType the MediaType of the MediaFormats to - * get - * @return the MediaFormats known to MediaUtils and being - * of the specified mediaType - */ - public static MediaFormat[] getMediaFormats(MediaType mediaType) - { - List mediaFormats = new ArrayList(); - - for (MediaFormat[] formats : rtpPayloadTypeStrToMediaFormats.values()) - for (MediaFormat format : formats) - if (format.getMediaType().equals(mediaType)) - mediaFormats.add(format); - for (MediaFormat format : rtpPayloadTypelessMediaFormats) - if (format.getMediaType().equals(mediaType)) - mediaFormats.add(format); - return mediaFormats.toArray(EMPTY_MEDIA_FORMATS); - } - - /** - * Gets the MediaFormats (expressed as an array) corresponding to - * a specific RTP payload type. - * - * @param rtpPayloadType the RTP payload type to retrieve the - * corresponding MediaFormats for - * @return an array of MediaFormats corresponding to the specified - * RTP payload type - */ - public static MediaFormat[] getMediaFormats(byte rtpPayloadType) - { - MediaFormat[] mediaFormats - = rtpPayloadTypeStrToMediaFormats.get(Byte.toString(rtpPayloadType)); - - return - (mediaFormats == null) - ? EMPTY_MEDIA_FORMATS - : mediaFormats.clone(); - } - - /** - * Gets the well-known encoding (name) as defined in RFC 3551 "RTP Profile - * for Audio and Video Conferences with Minimal Control" corresponding to a - * given JMF-specific encoding. - * - * @param jmfEncoding the JMF encoding to get the corresponding well-known - * encoding of - * @return the well-known encoding (name) as defined in RFC 3551 "RTP - * Profile for Audio and Video Conferences with Minimal Control" - * corresponding to jmfEncoding if any; otherwise, null - */ - public static String jmfEncodingToEncoding(String jmfEncoding) - { - return jmfEncodingToEncodings.get(jmfEncoding); - } - - /** - * Gets the RTP payload type corresponding to a specific JMF encoding and - * clock rate. - * - * @param jmfEncoding the JMF encoding as returned by - * {@link Format#getEncoding()} or the respective AudioFormat and - * VideoFormat encoding constants to get the corresponding RTP - * payload type of - * @param clockRate the clock rate to be taken into account in the search - * for the RTP payload type if the JMF encoding does not uniquely identify - * it - * @return the RTP payload type corresponding to the specified JMF encoding - * and clock rate if known in RFC 3551 "RTP Profile for Audio and Video - * Conferences with Minimal Control"; otherwise, - * {@link MediaFormat#RTP_PAYLOAD_TYPE_UNKNOWN} - */ - public static byte getRTPPayloadType(String jmfEncoding, double clockRate) - { - if (jmfEncoding == null) - return MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN; - else if (jmfEncoding.equals(AudioFormat.ULAW_RTP)) - return SdpConstants.PCMU; - else if (jmfEncoding.equals(Constants.ALAW_RTP)) - return SdpConstants.PCMA; - else if (jmfEncoding.equals(AudioFormat.GSM_RTP)) - return SdpConstants.GSM; - else if (jmfEncoding.equals(AudioFormat.G723_RTP)) - return SdpConstants.G723; - else if (jmfEncoding.equals(AudioFormat.DVI_RTP) - && (clockRate == 8000)) - return SdpConstants.DVI4_8000; - else if (jmfEncoding.equals(AudioFormat.DVI_RTP) - && (clockRate == 16000)) - return SdpConstants.DVI4_16000; - else if (jmfEncoding.equals(AudioFormat.ALAW)) - return SdpConstants.PCMA; - else if (jmfEncoding.equals(Constants.G722)) - return SdpConstants.G722; - else if (jmfEncoding.equals(Constants.G722_RTP)) - return SdpConstants.G722; - else if (jmfEncoding.equals(AudioFormat.GSM)) - return SdpConstants.GSM; - else if (jmfEncoding.equals(AudioFormat.GSM_RTP)) - return SdpConstants.GSM; - else if (jmfEncoding.equals(AudioFormat.G728_RTP)) - return SdpConstants.G728; - else if (jmfEncoding.equals(AudioFormat.G729_RTP)) - return SdpConstants.G729; - else if (jmfEncoding.equals(VideoFormat.H263_RTP)) - return SdpConstants.H263; - else if (jmfEncoding.equals(VideoFormat.JPEG_RTP)) - return SdpConstants.JPEG; - else if (jmfEncoding.equals(VideoFormat.H261_RTP)) - return SdpConstants.H261; - else - return MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN; - } - - - /** - * Creates value of an imgattr. - * - * http://tools.ietf.org/html/draft-ietf-mmusic-image-attributes-04 - * - * @param sendSize maximum size peer can send - * @param maxRecvSize maximum size peer can display - * @return string that represent imgattr that can be encoded via SIP/SDP or - * XMPP/Jingle - */ - public static String createImageAttr(java.awt.Dimension sendSize, - java.awt.Dimension maxRecvSize) - { - StringBuffer img = new StringBuffer(); - - /* send width */ - if(sendSize != null) - { - /* single value => send [x=width,y=height] */ - /*img.append("send [x="); - img.append((int)sendSize.getWidth()); - img.append(",y="); - img.append((int)sendSize.getHeight()); - img.append("]");*/ - /* send [x=[min-max],y=[min-max]] */ - img.append("send [x=[0-"); - img.append((int)sendSize.getWidth()); - img.append("],y=[0-"); - img.append((int)sendSize.getHeight()); - img.append("]]"); - /* - else - { - // range - img.append(" send [x=["); - img.append((int)minSendSize.getWidth()); - img.append("-"); - img.append((int)maxSendSize.getWidth()); - img.append("],y=["); - img.append((int)minSendSize.getHeight()); - img.append("-"); - img.append((int)maxSendSize.getHeight()); - img.append("]]"); - } - */ - } - else - { - /* can send "all" sizes */ - img.append("send *"); - } - - /* receive size */ - if(maxRecvSize != null) - { - /* basically we can receive any size up to our - * screen display size - */ - - /* recv [x=[min-max],y=[min-max]] */ - img.append(" recv [x=[0-"); - img.append((int)maxRecvSize.getWidth()); - img.append("],y=[0-"); - img.append((int)maxRecvSize.getHeight()); - img.append("]]"); - } - else - { - /* accept all sizes */ - img.append(" recv *"); - } - - return img.toString(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/NeomediaActivator.java b/src/net/java/sip/communicator/impl/neomedia/NeomediaActivator.java index 01a2f0ad6..c25dee583 100644 --- a/src/net/java/sip/communicator/impl/neomedia/NeomediaActivator.java +++ b/src/net/java/sip/communicator/impl/neomedia/NeomediaActivator.java @@ -14,18 +14,20 @@ import javax.swing.*; import net.java.sip.communicator.impl.neomedia.codec.video.h264.*; -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.impl.neomedia.notify.*; -import net.java.sip.communicator.service.audionotifier.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.fileaccess.*; import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.packetlogging.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.impl.neomedia.*; +import org.jitsi.impl.neomedia.device.*; +import org.jitsi.service.audionotifier.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.fileaccess.*; +import org.jitsi.service.libjitsi.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.packetlogging.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** @@ -143,7 +145,7 @@ public void start(BundleContext bundleContext) NeomediaActivator.bundleContext = bundleContext; // MediaService - mediaServiceImpl = new MediaServiceImpl(); + mediaServiceImpl = (MediaServiceImpl) LibJitsi.getMediaService(); bundleContext.registerService( MediaService.class.getName(), @@ -258,8 +260,7 @@ public void propertyChange(PropertyChangeEvent event) // AudioNotifierService AudioNotifierService audioNotifierService - = new AudioNotifierServiceImpl( - mediaServiceImpl.getDeviceConfiguration()); + = LibJitsi.getAudioNotifierService(); audioNotifierService.setMute( (cfg == null) diff --git a/src/net/java/sip/communicator/impl/neomedia/ProcessorUtility.java b/src/net/java/sip/communicator/impl/neomedia/ProcessorUtility.java deleted file mode 100644 index 5a2abd17d..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/ProcessorUtility.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import javax.media.*; - -import net.java.sip.communicator.util.*; - -/** - * A utility class that provides utility functions when working with processors. - * - * @author Emil Ivov - * @author Ken Larson - * @author Lubomir Marinov - */ -public class ProcessorUtility - implements ControllerListener -{ - - /** - * The Logger used by the ProcessorUtility class and its - * instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(ProcessorUtility.class); - - /** - * The Object used for syncing when waiting for a processor to - * enter a specific state. - */ - private final Object stateLock = new Object(); - - /** - * The indicator which determines whether the waiting of this instance on a - * processor for it to enter a specific state has failed. - */ - private boolean failed = false; - - /** - * Initializes a new ProcessorUtility instance. - */ - public ProcessorUtility() - { - } - - /** - * Gets the Object to use for syncing when waiting for a processor - * to enter a specific state. - * - * @return the Object to use for syncing when waiting for a - * processor to enter a specific state - */ - private Object getStateLock() - { - return stateLock; - } - - /** - * Specifies whether the wait operation has failed or completed with - * success. - * - * @param failed true if waiting has failed; false, - * otherwise - */ - private void setFailed(boolean failed) - { - this.failed = failed; - } - - /** - * This method is called when an event is generated by a - * Controller that this listener is registered with. We use - * the event to notify all waiting on our lock and record success or - * failure. - * - * @param ce The event generated. - */ - public void controllerUpdate(ControllerEvent ce) - { - // If there was an error during configure or - // realize, the processor will be closed - if (ce instanceof ControllerClosedEvent) - { - if (ce instanceof ControllerErrorEvent) - logger.warn("ControllerErrorEvent: " + ce); - else - if (logger.isDebugEnabled()) - logger.debug("ControllerClosedEvent: " + ce); - - setFailed(true); - - // All controller events, send a notification - // to the waiting thread in waitForState method. - } - - Object stateLock = getStateLock(); - - synchronized (stateLock) - { - stateLock.notifyAll(); - } - } - - /** - * Waits until processor enters state and returns a boolean - * indicating success or failure of the operation. - * - * @param processor Processor - * @param state one of the Processor.XXXed state vars - * @return true if the state has been reached; false, - * otherwise - */ - public synchronized boolean waitForState(Processor processor, int state) - { - processor.addControllerListener(this); - setFailed(false); - - // Call the required method on the processor - if (state == Processor.Configured) - processor.configure(); - else if (state == Processor.Realized) - processor.realize(); - - // Wait until we get an event that confirms the - // success of the method, or a failure event. - // See StateListener inner class - while ((processor.getState() < state) && !failed) - { - Object stateLock = getStateLock(); - - synchronized (stateLock) - { - try - { - stateLock.wait(); - } - catch (InterruptedException ie) - { - logger - .warn( - "Failed while waiting on Processor " - + processor - + " for state " - + state, - ie); - processor.removeControllerListener(this); - return false; - } - } - } - - processor.removeControllerListener(this); - return !failed; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/RTCPConnectorInputStream.java b/src/net/java/sip/communicator/impl/neomedia/RTCPConnectorInputStream.java deleted file mode 100644 index d25f1eb14..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/RTCPConnectorInputStream.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.io.*; -import java.net.*; -import java.util.*; - -import net.java.sip.communicator.service.neomedia.event.*; - -/** - * @author Bing SU (nova.su@gmail.com) - * @author Lyubomir Marinov - * @author Sebastien Vincent - */ -public class RTCPConnectorInputStream - extends RTPConnectorUDPInputStream -{ - /** - * List of feedback listeners; - */ - private final List rtcpFeedbackListeners - = new ArrayList(); - - /** - * Initializes a new RTCPConnectorInputStream which is to receive - * packet data from a specific UDP socket. - * - * @param socket the UDP socket the new instance is to receive data from - */ - public RTCPConnectorInputStream(DatagramSocket socket) - { - super(socket); - } - - /** - * Add an RTCPFeedbackListener. - * - * @param listener object that will listen to incoming RTCP feedback - * messages. - */ - public void addRTCPFeedbackListener(RTCPFeedbackListener listener) - { - if(!rtcpFeedbackListeners.contains(listener)) - rtcpFeedbackListeners.add(listener); - } - - /** - * Remove an RTCPFeedbackListener. - * - * @param listener object to remove from listening RTCP feedback messages. - */ - public void removeRTCPFeedbackListener(RTCPFeedbackListener listener) - { - rtcpFeedbackListeners.remove(listener); - } - - /** - * Copies the content of the most recently received packet into - * inBuffer. - * - * @param inBuffer the byte[] that we'd like to copy the content - * of the packet to. - * @param offset the position where we are supposed to start writing in - * inBuffer. - * @param length the number of bytes available for writing in - * inBuffer. - * - * @return the number of bytes read - * - * @throws IOException if length is less than the size of the - * packet. - */ - public int read(byte[] inBuffer, int offset, int length) - throws IOException - { - if (ioError) - return -1; - - int pktLength = pkt.getLength(); - - if (length < pktLength) - throw - new IOException("Input buffer not big enough for " + pktLength); - - /* check if RTCP feedback message */ - - /* Feedback message size is minimum 12 bytes: - * Version/Padding/Feedback message type: 1 byte - * Payload type: 1 byte - * Length: 2 bytes - * SSRC of packet sender: 4 bytes - * SSRC of media source: 4 bytes - */ - if(pktLength >= 12) - { - byte data[] = pkt.getBuffer(); - int fmt = 0; - int pt = 0; - - /* get FMT field (last 5 bits of first byte) */ - fmt = (data[0] & 0x1F); - pt |= (data[1] & 0xFF); - - RTCPFeedbackEvent evt = new RTCPFeedbackEvent(this, fmt, pt); - - /* notify feedback listeners */ - for(RTCPFeedbackListener l : rtcpFeedbackListeners) - l.feedbackReceived(evt); - } - - System.arraycopy( - pkt.getBuffer(), pkt.getOffset(), inBuffer, offset, pktLength); - - return pktLength; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/RTCPFeedbackPacket.java b/src/net/java/sip/communicator/impl/neomedia/RTCPFeedbackPacket.java deleted file mode 100644 index 145498bc9..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/RTCPFeedbackPacket.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import javax.media.rtp.*; - -/** - * Represents an RTCP feedback packet as described in RFC4585. - * - * @author Sebastien Vincent - */ -public class RTCPFeedbackPacket -{ - /** - * Feedback message type. - */ - private int fmt = 0; - - /** - * Payload type. - */ - private int payloadType = 0; - - /** - * SSRC of packet sender. - */ - private long senderSSRC = 0; - - /** - * SSRC of media source. - */ - private long sourceSSRC = 0; - - /** - * Constructor. - * - * @param type feedback message type - * @param payloadType payload type - * @param sender sender SSRC - * @param src source SSRC - */ - public RTCPFeedbackPacket(int type, int payloadType, long sender, long src) - { - this.fmt = type; - this.payloadType = payloadType; - this.senderSSRC = sender; - this.sourceSSRC = src; - } - - /** - * Write RTCP packet to output stream of a DatagramSocket. - * - * @param out OutputDataStream of a DatagramSocket - */ - public void writeTo(OutputDataStream out) - { - byte data[] = new byte[12]; - byte vpfmt = (byte)((2 << 7) | (0 << 6) | (byte)fmt); - - data[0] = vpfmt; - data[1] = (byte)payloadType; - - /* length (in 32-bit words minus one) */ - data[2] = 0; - data[3] = 2; /* common packet is 12 bytes so (12/4) - 1 */ - - /* sender SSRC */ - data[4] = (byte)(senderSSRC >> 24); - data[5] = (byte)((senderSSRC >> 16) & 0xFF); - data[6] = (byte)((senderSSRC >> 8) & 0xFF); - data[7] = (byte)(senderSSRC & 0xFF); - - /* source SSRC */ - data[8] = (byte)(sourceSSRC >> 24); - data[9] = (byte)((sourceSSRC >> 16) & 0xFF); - data[10] = (byte)((sourceSSRC >> 8) & 0xFF); - data[11] = (byte)(sourceSSRC & 0xFF); - - /* effective write */ - out.write(data, 0, 12); - } -} - diff --git a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorInputStream.java b/src/net/java/sip/communicator/impl/neomedia/RTPConnectorInputStream.java deleted file mode 100755 index 541a05965..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorInputStream.java +++ /dev/null @@ -1,425 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.io.*; -import java.net.*; - -import javax.media.protocol.*; - -import org.ice4j.socket.*; - -import net.java.sip.communicator.service.packetlogging.*; -import net.java.sip.communicator.util.*; - -/** - * @author Bing SU (nova.su@gmail.com) - * @author Lyubomir Marinov - */ -public abstract class RTPConnectorInputStream - implements PushSourceStream, - Runnable -{ - /** - * The value of the property controls of - * RTPConnectorInputStream when there are no controls. Explicitly - * defined in order to reduce unnecessary allocations. - */ - private static final Object[] EMPTY_CONTROLS = new Object[0]; - - /** - * The length in bytes of the buffers of RTPConnectorInputStream - * receiving packets from the network. - */ - private static final int PACKET_RECEIVE_BUFFER_LENGTH = 4 * 1024; - - /** - * Packet receive buffer - */ - private final byte[] buffer = new byte[PACKET_RECEIVE_BUFFER_LENGTH]; - - /** - * Whether this stream is closed. Used to control the termination of worker - * thread. - */ - protected boolean closed; - - /** - * Caught an IO exception during read from socket - */ - protected boolean ioError = false; - - /** - * The packet data to be read out of this instance through its - * {@link #read(byte[], int, int)} method. - */ - protected RawPacket pkt; - - /** - * SourceTransferHandler object which is used to read packets. - */ - private SourceTransferHandler transferHandler; - - /** - * The Thread receiving packets. - */ - protected Thread receiverThread = null; - - /** - * The DatagramPacketFilters which allow dropping - * DatagramPackets before they are converted into - * RawPackets. - */ - private DatagramPacketFilter[] datagramPacketFilters; - - /** - * Initializes a new RTPConnectorInputStream which is to receive - * packet data from a specific UDP socket. - */ - public RTPConnectorInputStream() - { - // PacketLoggingService - addDatagramPacketFilter( - new DatagramPacketFilter() - { - /** - * Used for debugging. As we don't log every packet, we must - * count them and decide which to log. - */ - private long numberOfPackets = 0; - - public boolean accept(DatagramPacket p) - { - numberOfPackets++; - if (RTPConnectorOutputStream.logPacket(numberOfPackets)) - { - PacketLoggingService packetLogging - = NeomediaActivator.getPacketLogging(); - - if ((packetLogging != null) - && packetLogging.isLoggingEnabled( - PacketLoggingService.ProtocolName - .RTP)) - doLogPacket(p); - } - - return true; - } - }); - } - - /** - * Close this stream, stops the worker thread. - */ - public synchronized void close() - { - } - - /** - * Creates a new RawPacket from a specific DatagramPacket - * in order to have this instance receive its packet data through its - * {@link #read(byte[], int, int)} method. Allows extenders to intercept the - * packet data and possibly filter and/or modify it. - * - * @param datagramPacket the DatagramPacket containing the packet - * data - * @return a new RawPacket containing the packet data of the - * specified DatagramPacket or possibly its modification; - * null to ignore the packet data of the specified - * DatagramPacket and not make it available to this instance - * through its {@link #read(byte[], int, int)} method - */ - protected RawPacket createRawPacket(DatagramPacket datagramPacket) - { - if (pkt == null) - { - return - new RawPacket( - datagramPacket.getData(), - datagramPacket.getOffset(), - datagramPacket.getLength()); - } - pkt.setBuffer(datagramPacket.getData()); - pkt.setLength(datagramPacket.getLength()); - pkt.setOffset(datagramPacket.getOffset()); - return pkt; - } - - /** - * Provides a dummy implementation to {@link - * RTPConnectorInputStream#endOfStream()} that always returns - * false. - * - * @return false, no matter what. - */ - public boolean endOfStream() - { - return false; - } - - /** - * Provides a dummy implementation to {@link - * RTPConnectorInputStream#getContentDescriptor()} that always returns - * null. - * - * @return null, no matter what. - */ - public ContentDescriptor getContentDescriptor() - { - return null; - } - - /** - * Provides a dummy implementation to {@link - * RTPConnectorInputStream#getContentLength()} that always returns - * LENGTH_UNKNOWN. - * - * @return LENGTH_UNKNOWN, no matter what. - */ - public long getContentLength() - { - return pkt.getLength(); - } - - /** - * Provides a dummy implementation to {@link - * RTPConnectorInputStream#getControl(String)} that always returns - * null. - * - * @param controlType ignored. - * - * @return null, no matter what. - */ - public Object getControl(String controlType) - { - return null; - } - - /** - * Provides a dummy implementation to {@link - * RTPConnectorInputStream#getControls()} that always returns - * EMPTY_CONTROLS. - * - * @return EMPTY_CONTROLS, no matter what. - */ - public Object[] getControls() - { - return EMPTY_CONTROLS; - } - - /** - * Provides a dummy implementation to {@link - * RTPConnectorInputStream#getMinimumTransferSize()} that always returns - * 2 * 1024. - * - * @return 2 * 1024, no matter what. - */ - public int getMinimumTransferSize() - { - return 2 * 1024; // twice the MTU size, just to be safe. - } - - /** - * Copies the content of the most recently received packet into - * buffer. - * - * @param buffer the byte[] that we'd like to copy the content of - * the packet to. - * @param offset the position where we are supposed to start writing in - * buffer. - * @param length the number of bytes available for writing in - * buffer. - * - * @return the number of bytes read - * - * @throws IOException if length is less than the size of the - * packet. - */ - public int read(byte[] buffer, int offset, int length) - throws IOException - { - if (ioError) - return -1; - - int pktLength = pkt.getLength(); - - if (length < pktLength) - throw - new IOException("Input buffer not big enough for " + pktLength); - - System.arraycopy( - pkt.getBuffer(), pkt.getOffset(), buffer, offset, pktLength); - - return pktLength; - } - - /** - * Log the packet. - * - * @param packet packet to log - */ - protected abstract void doLogPacket(DatagramPacket packet); - - /** - * Receive packet. - * - * @param p packet for receiving - * @throws IOException if something goes wrong during receiving - */ - protected abstract void receivePacket(DatagramPacket p) - throws IOException; - - /** - * Listens for incoming datagrams, stores them for reading by the - * read method and notifies the local transferHandler - * that there's data to be read. - */ - public void run() - { - DatagramPacket p - = new DatagramPacket(buffer, 0, PACKET_RECEIVE_BUFFER_LENGTH); - - while (!closed) - { - try - { - if (OSUtils.IS_ANDROID) - { - // http://code.google.com/p/android/issues/detail?id=24765 - p.setLength(PACKET_RECEIVE_BUFFER_LENGTH); - } - - receivePacket(p); - } - catch (IOException e) - { - ioError = true; - break; - } - - /* - * Do the DatagramPacketFilters accept the received DatagramPacket? - */ - DatagramPacketFilter[] datagramPacketFilters - = getDatagramPacketFilters(); - boolean accept; - - if (datagramPacketFilters == null) - accept = true; - else - { - accept = true; - for (int i = 0; i < datagramPacketFilters.length; i++) - { - try - { - if (!datagramPacketFilters[i].accept(p)) - { - accept = false; - break; - } - } - catch (Throwable t) - { - if (t instanceof ThreadDeath) - throw (ThreadDeath) t; - } - } - } - - if (accept) - { - pkt = createRawPacket(p); - - /* - * If we got extended, the delivery of the packet may have been - * canceled. - */ - if ((pkt != null) && (transferHandler != null) && !closed) - transferHandler.transferData(this); - } - } - } - - /** - * Sets the transferHandler that this connector should be notifying - * when new data is available for reading. - * - * @param transferHandler the transferHandler that this connector - * should be notifying when new data is available for reading. - */ - public void setTransferHandler(SourceTransferHandler transferHandler) - { - if (!closed) - this.transferHandler = transferHandler; - } - - /** - * Changes current thread priority. - * @param priority the new priority. - */ - public void setPriority(int priority) - { - // currently no priority is set -// if (receiverThread != null) -// receiverThread.setPriority(priority); - } - - /** - * Gets the DatagramPacketFilters which allow dropping - * DatagramPackets before they are converted into - * RawPackets. - * - * @return the DatagramPacketFilters which allow dropping - * DatagramPackets before they are converted into - * RawPackets. - */ - public synchronized DatagramPacketFilter[] getDatagramPacketFilters() - { - return datagramPacketFilters; - } - - /** - * Adds a DatagramPacketFilter which allows dropping - * DatagramPackets before they are converted into - * RawPackets. - * - * @param datagramPacketFilter the DatagramPacketFilter which - * allows dropping DatagramPackets before they are converted into - * RawPackets - */ - public synchronized void addDatagramPacketFilter( - DatagramPacketFilter datagramPacketFilter) - { - if (datagramPacketFilter == null) - throw new NullPointerException("datagramPacketFilter"); - - if (datagramPacketFilters == null) - { - datagramPacketFilters - = new DatagramPacketFilter[] { datagramPacketFilter }; - } - else - { - final int length = datagramPacketFilters.length; - - for (int i = 0; i < length; i++) - if (datagramPacketFilter.equals(datagramPacketFilters[i])) - return; - - DatagramPacketFilter[] newDatagramPacketFilters - = new DatagramPacketFilter[length + 1]; - - System.arraycopy( - datagramPacketFilters, 0, - newDatagramPacketFilters, 0, - length); - newDatagramPacketFilters[length] = datagramPacketFilter; - datagramPacketFilters = newDatagramPacketFilters; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorOutputStream.java b/src/net/java/sip/communicator/impl/neomedia/RTPConnectorOutputStream.java deleted file mode 100755 index aca97ef5c..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorOutputStream.java +++ /dev/null @@ -1,559 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import net.java.sip.communicator.service.packetlogging.*; - -import java.io.*; -import java.net.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.locks.*; - -import javax.media.rtp.*; - -/** - * @author Bing SU (nova.su@gmail.com) - * @author Lyubomir Marinov - */ -public abstract class RTPConnectorOutputStream - implements OutputDataStream -{ - - /** - * The maximum number of packets to be sent to be kept in the queue of - * MaxPacketsPerMillisPolicy. When the maximum is reached, the next - * attempt to write a new packet in the queue will block until at least one - * packet from the queue is sent. Defined in order to prevent - * OutOfMemoryErrors which, technically, may arise if the capacity - * of the queue is unlimited. - */ - public static final int - MAX_PACKETS_PER_MILLIS_POLICY_PACKET_QUEUE_CAPACITY - = 256; - - /** - * The functionality which allows this OutputDataStream to control - * how many RTP packets it sends through its DatagramSocket per a - * specific number of milliseconds. - */ - private MaxPacketsPerMillisPolicy maxPacketsPerMillisPolicy; - - /** - * Stream targets' IP addresses and ports. - */ - protected final List targets - = new LinkedList(); - - /** - * The pool of RawPacket instances which reduces the number of - * allocations performed by {@link #createRawPacket(byte[], int, int)}. - */ - private final LinkedBlockingQueue rawPacketPool - = new LinkedBlockingQueue(); - - /** - * Used for debugging. As we don't log every packet - * we must count them and decide which to log. - */ - private long numberOfPackets = 0; - - /** - * Initializes a new RTPConnectorOutputStream which is to send - * packet data out through a specific socket. - */ - public RTPConnectorOutputStream() - { - } - - /** - * Add a target to stream targets list - * - * @param remoteAddr target ip address - * @param remotePort target port - */ - public void addTarget(InetAddress remoteAddr, int remotePort) - { - InetSocketAddress target - = new InetSocketAddress(remoteAddr, remotePort); - - if (!targets.contains(target)) - targets.add(target); - } - - /** - * Close this output stream. - */ - public void close() - { - if (maxPacketsPerMillisPolicy != null) - { - maxPacketsPerMillisPolicy.close(); - maxPacketsPerMillisPolicy = null; - } - removeTargets(); - } - - /** - * Creates a new RawPacket from a specific byte[] buffer - * in order to have this instance send its packet data through its - * {@link #write(byte[], int, int)} method. Allows extenders to intercept - * the packet data and possibly filter and/or modify it. - * - * @param buffer the packet data to be sent to the targets of this instance - * @param offset the offset of the packet data in buffer - * @param length the length of the packet data in buffer - * @return a new RawPacket containing the packet data of the - * specified byte[] buffer or possibly its modification; - * null to ignore the packet data of the specified byte[] - * buffer and not send it to the targets of this instance through its - * {@link #write(byte[], int, int)} method - */ - protected RawPacket createRawPacket(byte[] buffer, int offset, int length) - { - RawPacket pkt = rawPacketPool.poll(); - - if ((pkt == null) || (pkt.getBuffer().length < length)) - pkt = new RawPacket(new byte[length], 0, 0); - - System.arraycopy(buffer, offset, pkt.getBuffer(), 0, length); - pkt.setLength(length); - pkt.setOffset(0); - return pkt; - } - - /** - * Remove a target from stream targets list - * - * @param remoteAddr target ip address - * @param remotePort target port - * @return true if the target is in stream target list and can be - * removed; false, otherwise - */ - public boolean removeTarget(InetAddress remoteAddr, int remotePort) - { - for (Iterator targetIter = targets.iterator(); - targetIter.hasNext();) - { - InetSocketAddress target = targetIter.next(); - - if (target.getAddress().equals(remoteAddr) - && (target.getPort() == remotePort)) - { - targetIter.remove(); - return true; - } - } - return false; - } - - /** - * Remove all stream targets from this session. - */ - public void removeTargets() - { - targets.clear(); - } - - /** - * Determines whether a RawPacket which has a specific number in - * the total number of sent RawPackets is to be logged by - * {@link PacketLoggingService}. - * - * @param numOfPacket the number of the RawPacket in the total - * number of sent RawPackets - * @return true if the RawPacket with the specified - * numOfPacket is to be logged by PacketLoggingService; - * otherwise, false - */ - static boolean logPacket(long numOfPacket) - { - return - (numOfPacket == 1) - || (numOfPacket == 300) - || (numOfPacket == 500) - || (numOfPacket == 1000) - || ((numOfPacket % 5000) == 0); - } - - /** - * Sends a specific RawPacket through this - * OutputDataStream to a specific InetSocketAddress. - * - * @param packet the RawPacket to send through this - * OutputDataStream to the specified target - * @param target the InetSocketAddress to which the specified - * packet is to be sent through this OutputDataStream - * @throws IOException if anything goes wrong while sending the specified - * packet through this OutputDataStream to the specified - * target - */ - protected abstract void sendToTarget( - RawPacket packet, - InetSocketAddress target) - throws IOException; - - /** - * Logs a specific RawPacket associated with a specific remote - * address. - * - * @param packet packet to log - * @param target the remote address associated with the packet - */ - protected abstract void doLogPacket( - RawPacket packet, - InetSocketAddress target); - - /** - * Returns whether or not this RTPConnectorOutputStream has a valid - * socket. - * - * @return true if this RTPConnectorOutputStream has a - * valid socket; false, otherwise - */ - protected abstract boolean isSocketValid(); - - /** - * Sends a specific RTP packet through the DatagramSocket of this - * OutputDataSource. - * - * @param packet the RTP packet to be sent through the - * DatagramSocket of this OutputDataSource - * @return true if the specified packet was successfully - * sent; otherwise, false - */ - private boolean send(RawPacket packet) - { - if(!isSocketValid()) - return false; - - numberOfPackets++; - for (InetSocketAddress target : targets) - { - try - { - sendToTarget(packet, target); - - if(logPacket(numberOfPackets)) - { - PacketLoggingService packetLogging - = NeomediaActivator.getPacketLogging(); - - if ((packetLogging != null) - && packetLogging.isLoggingEnabled( - PacketLoggingService.ProtocolName.RTP)) - doLogPacket(packet, target); - } - } - catch (IOException ioe) - { - rawPacketPool.offer(packet); - // TODO error handling - return false; - } - } - rawPacketPool.offer(packet); - return true; - } - - /** - * Sets the maximum number of RTP packets to be sent by this - * OutputDataStream through its DatagramSocket per - * a specific number of milliseconds. - * - * @param maxPackets the maximum number of RTP packets to be sent by this - * OutputDataStream through its DatagramSocket per the - * specified number of milliseconds; -1 if no maximum is to be set - * @param perMillis the number of milliseconds per which maxPackets - * are to be sent by this OutputDataStream through its - * DatagramSocket - */ - public void setMaxPacketsPerMillis(int maxPackets, long perMillis) - { - if (maxPacketsPerMillisPolicy == null) - { - if (maxPackets > 0) - { - if (perMillis < 1) - throw new IllegalArgumentException("perMillis"); - - maxPacketsPerMillisPolicy - = new MaxPacketsPerMillisPolicy(maxPackets, perMillis); - } - } - else - { - maxPacketsPerMillisPolicy - .setMaxPacketsPerMillis(maxPackets, perMillis); - } - } - - /** - * Implements {@link OutputDataStream#write(byte[], int, int)}. - * - * @param buffer the byte[] that we'd like to copy the content - * of the packet to. - * @param offset the position where we are supposed to start writing in - * buffer. - * @param length the number of bytes available for writing in - * inBuffer. - * - * @return the number of bytes read - */ - public int write(byte[] buffer, int offset, int length) - { - RawPacket packet = createRawPacket(buffer, offset, length); - - /* - * If we got extended, the delivery of the packet may have been - * canceled. - */ - if (packet != null) - { - if (maxPacketsPerMillisPolicy == null) - { - if (!send(packet)) - return -1; - } - else - maxPacketsPerMillisPolicy.write(packet); - } - return length; - } - - /** - * Changes current thread priority. - * @param priority the new priority. - */ - public void setPriority(int priority) - { - // currently no priority is set -// if(maxPacketsPerMillisPolicy != null && -// maxPacketsPerMillisPolicy.sendThread != null) -// maxPacketsPerMillisPolicy.sendThread.setPriority(priority); - } - - /** - * Implements the functionality which allows this OutputDataStream - * to control how many RTP packets it sends through its - * DatagramSocket per a specific number of milliseconds. - */ - private class MaxPacketsPerMillisPolicy - { - - /** - * The maximum number of RTP packets to be sent by this - * OutputDataStream through its DatagramSocket per - * {@link #perNanos} nanoseconds. - */ - private int maxPackets = -1; - - /** - * The time stamp in nanoseconds of the start of the current - * perNanos interval. - */ - private long millisStartTime = 0; - - /** - * The list of RTP packets to be sent through the - * DatagramSocket of this OutputDataSource. - */ - private final ArrayBlockingQueue packetQueue - = new ArrayBlockingQueue( - MAX_PACKETS_PER_MILLIS_POLICY_PACKET_QUEUE_CAPACITY); - - /** - * The number of RTP packets already sent during the current - * perNanos interval. - */ - private long packetsSentInMillis = 0; - - /** - * The time interval in nanoseconds during which {@link #maxPackets} - * number of RTP packets are to be sent through the - * DatagramSocket of this OutputDataSource. - */ - private long perNanos = -1; - - /** - * The Thread which is to send the RTP packets in - * {@link #packetQueue} through the DatagramSocket of this - * OutputDataSource. - */ - private Thread sendThread; - - /** - * To signal run or stop condition to send thread. - */ - private boolean sendRun = true; - - /** - * Initializes a new MaxPacketsPerMillisPolicy instance which - * is to control how many RTP packets this OutputDataSource is - * to send through its DatagramSocket per a specific number of - * milliseconds. - * - * @param maxPackets the maximum number of RTP packets to be sent per - * perMillis milliseconds through the DatagramSocket - * of this OutputDataStream - * @param perMillis the number of milliseconds per which a maximum of - * maxPackets RTP packets are to be sent through the - * DatagramSocket of this OutputDataStream - */ - public MaxPacketsPerMillisPolicy(int maxPackets, long perMillis) - { - setMaxPacketsPerMillis(maxPackets, perMillis); - synchronized (this) { - if (sendThread == null) - { - sendThread - = new Thread(getClass().getName()) - { - @Override - public void run() - { - runInSendThread(); - } - }; - sendThread.setDaemon(true); - sendThread.start(); - } - } - } - - /** - * Closes the connector. - */ - synchronized void close() - { - if (!sendRun) - return; - sendRun = false; - // just offer a new packet to wakeup thread in case it waits for - // a packet. - packetQueue.offer(new RawPacket(null, 0, 0)); - } - - /** - * Sends the RTP packets in {@link #packetQueue} in accord with - * {@link #maxPackets} and {@link #perNanos}. - */ - private void runInSendThread() - { - try - { - while (sendRun) - { - RawPacket packet = null; - - while (true) - { - try - { - packet = packetQueue.take(); - break; - } - catch (InterruptedException iex) - { - continue; - } - } - if (!sendRun) - break; - - long time = System.nanoTime(); - long millisRemainingTime = time - millisStartTime; - - if ((perNanos < 1) - || (millisRemainingTime >= perNanos)) - { - millisStartTime = time; - packetsSentInMillis = 0; - } - else if ((maxPackets > 0) - && (packetsSentInMillis >= maxPackets)) - { - while (true) - { - millisRemainingTime = System.nanoTime() - - millisStartTime; - if (millisRemainingTime >= perNanos) - break; - LockSupport.parkNanos(millisRemainingTime); - } - millisStartTime = System.nanoTime(); - packetsSentInMillis = 0; - } - - send(packet); - packetsSentInMillis++; - } - } - finally - { - packetQueue.clear(); - synchronized (packetQueue) - { - if (Thread.currentThread().equals(sendThread)) - sendThread = null; - } - } - } - - /** - * Sets the maximum number of RTP packets to be sent by this - * OutputDataStream through its DatagramSocket per - * a specific number of milliseconds. - * - * @param maxPackets the maximum number of RTP packets to be sent by - * this OutputDataStream through its DatagramSocket - * per the specified number of milliseconds; -1 if no maximum - * is to be set - * @param perMillis the number of milliseconds per which - * maxPackets are to be sent by this OutputDataStream - * through its DatagramSocket - */ - public void setMaxPacketsPerMillis(int maxPackets, long perMillis) - { - if (maxPackets < 1) - { - this.maxPackets = -1; - this.perNanos = -1; - } - else - { - if (perMillis < 1) - throw new IllegalArgumentException("perMillis"); - - this.maxPackets = maxPackets; - this.perNanos = perMillis * 1000000; - } - } - - /** - * Queues a specific RTP packet to be sent through the - * DatagramSocket of this OutputDataStream. - * - * @param packet the RTP packet to be queued for sending through the - * DatagramSocket of this OutputDataStream - */ - public void write(RawPacket packet) - { - while (true) - { - try - { - packetQueue.put(packet); - break; - } - catch (InterruptedException iex) - { - } - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPImpl.java b/src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPImpl.java deleted file mode 100644 index fd2d56d76..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPImpl.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.io.*; -import java.net.*; - -import net.java.sip.communicator.service.neomedia.*; - -/** - * RTPConnector implementation for UDP. - * - * @author Sebastien Vincent - */ -public class RTPConnectorTCPImpl - extends AbstractRTPConnector -{ - /** - * The TCP socket this instance uses to send and receive RTP packets. - */ - private Socket dataSocket; - - /** - * The TCP socket this instance uses to send and receive RTCP packets. - */ - private Socket controlSocket; - - /** - * Initializes a new RTPConnectorTCPImpl which is to use a given - * pair of sockets for RTP and RTCP traffic specified in the form - * of a StreamConnector. - * - * @param connector the pair of sockets for RTP and RTCP traffic - * the new instance is to use - */ - public RTPConnectorTCPImpl(StreamConnector connector) - { - super(connector); - } - - /** - * Gets the TCP socket this instance uses to send and receive RTP packets. - * - * @return the TCP socket this instance uses to send and receive RTP packets - */ - public Socket getDataSocket() - { - if (dataSocket == null) - dataSocket = connector.getDataTCPSocket(); - return dataSocket; - } - - /** - * Gets the TCP Socket this instance uses to send and receive RTCP packets. - * - * @return the TCP Socket this instance uses to send and receive RTCP - * packets - */ - public Socket getControlSocket() - { - if (controlSocket == null) - controlSocket = connector.getControlTCPSocket(); - return controlSocket; - } - - /** - * Creates the RTCP packet input stream to be used by RTPManager. - * - * @return a new RTCP packet input stream to be used by RTPManager - * @throws IOException if an error occurs during the creation of the RTCP - * packet input stream - */ - protected RTPConnectorInputStream createControlInputStream() - throws IOException - { - return new RTPConnectorTCPInputStream(getControlSocket()); - } - - /** - * Creates the RTCP packet output stream to be used by RTPManager. - * - * @return a new RTCP packet output stream to be used by RTPManager - * @throws IOException if an error occurs during the creation of the RTCP - * packet output stream - */ - protected RTPConnectorOutputStream createControlOutputStream() - throws IOException - { - return new RTPConnectorTCPOutputStream(getControlSocket()); - } - - /** - * Creates the RTP packet input stream to be used by RTPManager. - * - * @return a new RTP packet input stream to be used by RTPManager - * @throws IOException if an error occurs during the creation of the RTP - * packet input stream - */ - protected RTPConnectorInputStream createDataInputStream() - throws IOException - { - return new RTPConnectorTCPInputStream(getDataSocket()); - } - - /** - * Creates the RTP packet output stream to be used by RTPManager. - * - * @return a new RTP packet output stream to be used by RTPManager - * @throws IOException if an error occurs during the creation of the RTP - * packet output stream - */ - protected RTPConnectorOutputStream createDataOutputStream() - throws IOException - { - return new RTPConnectorTCPOutputStream(getDataSocket()); - } -} \ No newline at end of file diff --git a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPInputStream.java b/src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPInputStream.java deleted file mode 100644 index 7b4750f3f..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPInputStream.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.io.*; -import java.net.*; - -import net.java.sip.communicator.service.packetlogging.*; -import net.java.sip.communicator.util.*; -import org.ice4j.socket.*; - -/** - * RTPConnectorInputStream implementation for TCP protocol. - * - * @author Sebastien Vincent - */ -public class RTPConnectorTCPInputStream - extends RTPConnectorInputStream -{ - /** - * The Logger used by instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(RTPConnectorTCPInputStream.class); - - /** - * TCP socket used to receive data. - */ - private final Socket socket; - - /** - * Initializes a new RTPConnectorInputStream which is to receive - * packet data from a specific TCP socket. - * - * @param socket the TCP socket the new instance is to receive data from - */ - public RTPConnectorTCPInputStream(Socket socket) - { - this.socket = socket; - - if(socket != null) - { - try - { - socket.setReceiveBufferSize(65535); - } - catch(Throwable t) - { - } - - closed = false; - receiverThread = new Thread(this); - receiverThread.start(); - } - } - - /** - * Close this stream, stops the worker thread. - */ - @Override - public synchronized void close() - { - closed = true; - if(socket != null) - { - try - { - socket.close(); - } - catch(IOException e) - { - } - } - } - - /** - * Log the packet. - * - * @param p packet to log - */ - protected void doLogPacket(DatagramPacket p) - { - if(socket.getLocalAddress() == null) - return; - - // Do not log the packet if this one has been processed (and already - // logged) by the ice4j stack. - if(socket instanceof MultiplexingSocket) - return; - - PacketLoggingService packetLogging - = NeomediaActivator.getPacketLogging(); - - if (packetLogging != null) - packetLogging.logPacket( - PacketLoggingService.ProtocolName.RTP, - (p.getAddress() != null) - ? p.getAddress().getAddress() - : new byte[] { 0,0,0,0 }, - p.getPort(), - socket.getLocalAddress().getAddress(), - socket.getLocalPort(), - PacketLoggingService.TransportName.TCP, - false, - p.getData(), - p.getOffset(), - p.getLength()); - } - - /** - * Receive packet. - * - * @param p packet for receiving - * @throws IOException if something goes wrong during receiving - */ - protected void receivePacket(DatagramPacket p) - throws IOException - { - int len = -1; - byte data[] = null; - - try - { - data = p.getData(); - len = socket.getInputStream().read(data); - } - catch(Exception e) - { - logger.info("problem read: " + e); - } - - if(len > 0) - { - p.setData(data); - p.setLength(len); - p.setAddress(socket.getInetAddress()); - p.setPort(socket.getPort()); - } - else - { - throw new IOException("Failed to read on TCP socket"); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPOutputStream.java b/src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPOutputStream.java deleted file mode 100644 index c4e2819dc..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorTCPOutputStream.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.io.*; -import java.net.*; - -import net.java.sip.communicator.service.packetlogging.*; -import org.ice4j.socket.*; - -/** - * RTPConnectorOutputStream implementation for TCP protocol. - * - * @author Sebastien Vincent - */ -public class RTPConnectorTCPOutputStream - extends RTPConnectorOutputStream -{ - /** - * UDP socket used to send packet data - */ - private final Socket socket; - - /** - * Initializes a new RTPConnectorTCPOutputStream. - * - * @param socket a Socket - */ - public RTPConnectorTCPOutputStream(Socket socket) - { - this.socket = socket; - } - - /** - * Sends a specific RawPacket through this - * OutputDataStream to a specific InetSocketAddress. - * - * @param packet the RawPacket to send through this - * OutputDataStream to the specified target - * @param target the InetSocketAddress to which the specified - * packet is to be sent through this OutputDataStream - * @throws IOException if anything goes wrong while sending the specified - * packet through this OutputDataStream to the specified - * target - */ - protected void sendToTarget(RawPacket packet, InetSocketAddress target) - throws IOException - { - socket.getOutputStream().write( - packet.getBuffer(), - packet.getOffset(), - packet.getLength()); - } - - /** - * Log the packet. - * - * @param packet packet to log - */ - protected void doLogPacket(RawPacket packet, InetSocketAddress target) - { - // Do not log the packet if this one has been processed (and already - // logged) by the ice4j stack. - if(socket instanceof MultiplexingSocket) - return; - - PacketLoggingService packetLogging - = NeomediaActivator.getPacketLogging(); - - if (packetLogging != null) - packetLogging.logPacket( - PacketLoggingService.ProtocolName.RTP, - socket.getLocalAddress().getAddress(), - socket.getLocalPort(), - target.getAddress().getAddress(), - target.getPort(), - PacketLoggingService.TransportName.TCP, - true, - packet.getBuffer(), - packet.getOffset(), - packet.getLength()); - } - - /** - * Returns whether or not this RTPConnectorOutputStream has a valid - * socket. - * - * @returns true if this RTPConnectorOutputStream has a valid - * socket, false otherwise - */ - @Override - protected boolean isSocketValid() - { - return (socket != null); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPImpl.java b/src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPImpl.java deleted file mode 100644 index 3f6e61180..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPImpl.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.io.*; -import java.net.*; - -import net.java.sip.communicator.service.neomedia.*; - -/** - * RTPConnector implementation for UDP. - * - * @author Sebastien Vincent - */ -public class RTPConnectorUDPImpl - extends AbstractRTPConnector -{ - /** - * The UDP socket this instance uses to send and receive RTP packets. - */ - private DatagramSocket dataSocket; - - /** - * The UDP socket this instance uses to send and receive RTCP packets. - */ - private DatagramSocket controlSocket; - - /** - * Initializes a new RTPConnectorUDPImpl which is to use a given - * pair of datagram sockets for RTP and RTCP traffic specified in the form - * of a StreamConnector. - * - * @param connector the pair of datagram sockets for RTP and RTCP traffic - * the new instance is to use - */ - public RTPConnectorUDPImpl(StreamConnector connector) - { - super(connector); - } - - /** - * Gets the UDP socket this instance uses to send and receive RTP packets. - * - * @return the UDP socket this instance uses to send and receive RTP packets - */ - public DatagramSocket getDataSocket() - { - if (dataSocket == null) - dataSocket = connector.getDataSocket(); - return dataSocket; - } - - /** - * Gets the UDP Socket this instance uses to send and receive RTCP packets. - * - * @return the UDP Socket this instance uses to send and receive RTCP - * packets - */ - public DatagramSocket getControlSocket() - { - if (controlSocket == null) - controlSocket = connector.getControlSocket(); - return controlSocket; - } - - /** - * Creates the RTCP packet input stream to be used by RTPManager. - * - * @return a new RTCP packet input stream to be used by RTPManager - * @throws IOException if an error occurs during the creation of the RTCP - * packet input stream - */ - protected RTPConnectorInputStream createControlInputStream() - throws IOException - { - return new RTCPConnectorInputStream(getControlSocket()); - } - - /** - * Creates the RTCP packet output stream to be used by RTPManager. - * - * @return a new RTCP packet output stream to be used by RTPManager - * @throws IOException if an error occurs during the creation of the RTCP - * packet output stream - */ - protected RTPConnectorOutputStream createControlOutputStream() - throws IOException - { - return new RTPConnectorUDPOutputStream(getControlSocket()); - } - - /** - * Creates the RTP packet input stream to be used by RTPManager. - * - * @return a new RTP packet input stream to be used by RTPManager - * @throws IOException if an error occurs during the creation of the RTP - * packet input stream - */ - protected RTPConnectorInputStream createDataInputStream() - throws IOException - { - return new RTPConnectorUDPInputStream(getDataSocket()); - } - - /** - * Creates the RTP packet output stream to be used by RTPManager. - * - * @return a new RTP packet output stream to be used by RTPManager - * @throws IOException if an error occurs during the creation of the RTP - * packet output stream - */ - protected RTPConnectorOutputStream createDataOutputStream() - throws IOException - { - return new RTPConnectorUDPOutputStream(getDataSocket()); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPInputStream.java b/src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPInputStream.java deleted file mode 100644 index 4cef9e3b0..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPInputStream.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.io.*; -import java.net.*; - -import net.java.sip.communicator.service.packetlogging.*; -import org.ice4j.socket.*; - -/** - * RTPConnectorInputStream implementation for UDP protocol. - * - * @author Sebastien Vincent - */ -public class RTPConnectorUDPInputStream - extends RTPConnectorInputStream -{ - /** - * UDP socket used to receive data. - */ - private final DatagramSocket socket; - - /** - * Receive size configured flag. - */ - private boolean receivedSizeFlag = false; - - /** - * Initializes a new RTPConnectorInputStream which is to receive - * packet data from a specific UDP socket. - * - * @param socket the UDP socket the new instance is to receive data from - */ - public RTPConnectorUDPInputStream(DatagramSocket socket) - { - this.socket = socket; - - if(socket != null) - { - closed = false; - receiverThread = new Thread(this); - receiverThread.start(); - } - } - - /** - * Close this stream, stops the worker thread. - */ - @Override - public synchronized void close() - { - closed = true; - if(socket != null) - { - socket.close(); - } - } - - /** - * Log the packet. - * - * @param p packet to log - */ - protected void doLogPacket(DatagramPacket p) - { - if(socket.getLocalAddress() == null) - return; - - // Do not log the packet if this one has been processed (and already - // logged) by the ice4j stack. - if(socket instanceof MultiplexingDatagramSocket) - return; - - PacketLoggingService packetLogging - = NeomediaActivator.getPacketLogging(); - - if (packetLogging != null) - packetLogging.logPacket( - PacketLoggingService.ProtocolName.RTP, - p.getAddress().getAddress(), - p.getPort(), - socket.getLocalAddress().getAddress(), - socket.getLocalPort(), - PacketLoggingService.TransportName.UDP, - false, - p.getData(), - p.getOffset(), - p.getLength()); - } - - /** - * Receive packet. - * - * @param p packet for receiving - * @throws IOException if something goes wrong during receiving - */ - protected void receivePacket(DatagramPacket p) - throws IOException - { - if(!receivedSizeFlag) - { - receivedSizeFlag = true; - - try - { - socket.setReceiveBufferSize(65535); - } - catch(Throwable t) - { - } - } - socket.receive(p); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPOutputStream.java b/src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPOutputStream.java deleted file mode 100644 index de2b00e2e..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/RTPConnectorUDPOutputStream.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.io.*; -import java.net.*; - -import net.java.sip.communicator.service.packetlogging.*; -import org.ice4j.socket.*; - -/** - * RTPConnectorOutputStream implementation for UDP protocol. - * - * @author Sebastien Vincent - */ -public class RTPConnectorUDPOutputStream - extends RTPConnectorOutputStream -{ - /** - * UDP socket used to send packet data - */ - private final DatagramSocket socket; - - /** - * Initializes a new RTPConnectorUDPOutputStream. - * - * @param socket a DatagramSocket - */ - public RTPConnectorUDPOutputStream(DatagramSocket socket) - { - this.socket = socket; - } - - /** - * Sends a specific RawPacket through this - * OutputDataStream to a specific InetSocketAddress. - * - * @param packet the RawPacket to send through this - * OutputDataStream to the specified target - * @param target the InetSocketAddress to which the specified - * packet is to be sent through this OutputDataStream - * @throws IOException if anything goes wrong while sending the specified - * packet through this OutputDataStream to the specified - * target - */ - protected void sendToTarget(RawPacket packet, InetSocketAddress target) - throws IOException - { - socket.send( - new DatagramPacket( - packet.getBuffer(), - packet.getOffset(), - packet.getLength(), - target.getAddress(), - target.getPort())); - } - - /** - * Log the packet. - * - * @param packet packet to log - */ - protected void doLogPacket(RawPacket packet, InetSocketAddress target) - { - // Do not log the packet if this one has been processed (and already - // logged) by the ice4j stack. - if(socket instanceof MultiplexingDatagramSocket) - return; - - PacketLoggingService packetLogging - = NeomediaActivator.getPacketLogging(); - - if (packetLogging != null) - packetLogging.logPacket( - PacketLoggingService.ProtocolName.RTP, - socket.getLocalAddress().getAddress(), - socket.getLocalPort(), - target.getAddress().getAddress(), - target.getPort(), - PacketLoggingService.TransportName.UDP, - true, - packet.getBuffer(), - packet.getOffset(), - packet.getLength()); - } - - /** - * Returns whether or not this RTPConnectorOutputStream has a valid - * socket. - * - * @returns true if this RTPConnectorOutputStream has a valid - * socket, false otherwise - */ - @Override - protected boolean isSocketValid() - { - return (socket != null); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/RTPTranslatorImpl.java b/src/net/java/sip/communicator/impl/neomedia/RTPTranslatorImpl.java deleted file mode 100644 index 9fb4a3646..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/RTPTranslatorImpl.java +++ /dev/null @@ -1,1545 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.io.*; -import java.lang.reflect.*; -import java.util.*; - -import javax.media.*; -import javax.media.format.*; -import javax.media.protocol.*; -import javax.media.rtp.*; -import javax.media.rtp.event.*; -import javax.media.rtp.rtcp.*; - -import com.sun.media.rtp.*; - -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.util.*; - -/** - * Implements RTPTranslator which represents an RTP translator which - * forwards RTP and RTCP traffic between multiple MediaStreams. - * - * @author Lyubomir Marinov - */ -public class RTPTranslatorImpl - implements ReceiveStreamListener, - RTPTranslator -{ - /** - * The Logger used by the RTPTranslatorImpl class and its - * instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(RTPTranslatorImpl.class); - - /** - * An array with long element type and no elements explicitly - * defined to reduce unnecessary allocations. - */ - private static final long[] EMPTY_LONG_ARRAY = new long[0]; - - /** - * The RTPConnector which is used by {@link #manager} and which - * delegates to the RTPConnectors of the StreamRTPManagers - * attached to this instance. - */ - private RTPConnectorImpl connector; - - /** - * The RTPManager which implements the actual RTP management of - * this instance. - */ - private final RTPManager manager = RTPManager.newInstance(); - - /** - * The SendStreams created by the RTPManager and the - * StreamRTPManager-specific views to them. - */ - private final List sendStreams - = new LinkedList(); - - /** - * The list of StreamRTPManagers i.e. MediaStreams which - * this instance forwards RTP and RTCP traffic between. - */ - private final List streamRTPManagers - = new ArrayList(); - - /** - * Initializes a new RTPTranslatorImpl instance. - */ - public RTPTranslatorImpl() - { - manager.addReceiveStreamListener(this); - } - - public synchronized void addFormat( - StreamRTPManager streamRTPManager, - Format format, int payloadType) - { - manager.addFormat(format, payloadType); - - getStreamRTPManagerDesc(streamRTPManager, true) - .addFormat(format, payloadType); - } - - public synchronized void addReceiveStreamListener( - StreamRTPManager streamRTPManager, - ReceiveStreamListener listener) - { - getStreamRTPManagerDesc(streamRTPManager, true) - .addReceiveStreamListener(listener); - } - - public void addRemoteListener( - StreamRTPManager streamRTPManager, - RemoteListener listener) - { - manager.addRemoteListener(listener); - } - - public void addSendStreamListener( - StreamRTPManager streamRTPManager, - SendStreamListener listener) - { - // TODO Auto-generated method stub - } - - public void addSessionListener( - StreamRTPManager streamRTPManager, - SessionListener listener) - { - // TODO Auto-generated method stub - } - - private synchronized void closeSendStream(SendStreamDesc sendStreamDesc) - { - if (sendStreams.contains(sendStreamDesc) - && (sendStreamDesc.getSendStreamCount() < 1)) - { - sendStreamDesc.sendStream.close(); - sendStreams.remove(sendStreamDesc); - } - } - - public synchronized SendStream createSendStream( - StreamRTPManager streamRTPManager, - DataSource dataSource, int streamIndex) - throws IOException, - UnsupportedFormatException - { - SendStreamDesc sendStreamDesc = null; - - for (SendStreamDesc s : sendStreams) - if ((s.dataSource == dataSource) && (s.streamIndex == streamIndex)) - { - sendStreamDesc = s; - break; - } - if (sendStreamDesc == null) - { - SendStream sendStream - = manager.createSendStream(dataSource, streamIndex); - - if (sendStream != null) - { - sendStreamDesc - = new SendStreamDesc(dataSource, streamIndex, sendStream); - sendStreams.add(sendStreamDesc); - } - } - return - (sendStreamDesc == null) - ? null - : sendStreamDesc.getSendStream(streamRTPManager, true); - } - - /** - * Releases the resources allocated by this instance in the course of its - * execution and prepares it to be garbage collected. - */ - public synchronized void dispose() - { - manager.removeReceiveStreamListener(this); - manager.dispose(); - } - - public synchronized void dispose(StreamRTPManager streamRTPManager) - { - Iterator streamRTPManagerIter - = streamRTPManagers.iterator(); - - while (streamRTPManagerIter.hasNext()) - { - StreamRTPManagerDesc streamRTPManagerDesc - = streamRTPManagerIter.next(); - - if (streamRTPManagerDesc.streamRTPManager == streamRTPManager) - { - RTPConnectorDesc connectorDesc - = streamRTPManagerDesc.connectorDesc; - - if (connectorDesc != null) - { - if (this.connector != null) - { - this.connector.removeConnector(connectorDesc); - connectorDesc.connector.close(); - } - streamRTPManagerDesc.connectorDesc = null; - } - - streamRTPManagerIter.remove(); - break; - } - } - } - - private synchronized StreamRTPManagerDesc - findStreamRTPManagerDescByReceiveSSRC( - long receiveSSRC, - StreamRTPManagerDesc exclusion) - { - for (int i = 0, count = streamRTPManagers.size(); i < count; i++) - { - StreamRTPManagerDesc s = streamRTPManagers.get(i); - - if ((s != exclusion) && s.containsReceiveSSRC(receiveSSRC)) - return s; - } - return null; - } - - public Object getControl( - StreamRTPManager streamRTPManager, - String controlType) - { - return manager.getControl(controlType); - } - - public GlobalReceptionStats getGlobalReceptionStats( - StreamRTPManager streamRTPManager) - { - return manager.getGlobalReceptionStats(); - } - - public GlobalTransmissionStats getGlobalTransmissionStats( - StreamRTPManager streamRTPManager) - { - return manager.getGlobalTransmissionStats(); - } - - public long getLocalSSRC(StreamRTPManager streamRTPManager) - { - return ((RTPSessionMgr) manager).getLocalSSRC(); - } - - public synchronized Vector getReceiveStreams( - StreamRTPManager streamRTPManager) - { - StreamRTPManagerDesc streamRTPManagerDesc - = getStreamRTPManagerDesc(streamRTPManager, false); - Vector receiveStreams = null; - - if (streamRTPManagerDesc != null) - { - Vector managerReceiveStreams = manager.getReceiveStreams(); - - if (managerReceiveStreams != null) - { - receiveStreams - = new Vector(managerReceiveStreams.size()); - for (Object s : managerReceiveStreams) - { - ReceiveStream receiveStream = (ReceiveStream) s; - - if (streamRTPManagerDesc.containsReceiveSSRC( - receiveStream.getSSRC())) - receiveStreams.add(receiveStream); - } - } - } - return receiveStreams; - } - - public synchronized Vector getSendStreams( - StreamRTPManager streamRTPManager) - { - Vector managerSendStreams = manager.getSendStreams(); - Vector sendStreams = null; - - if (managerSendStreams != null) - { - sendStreams = new Vector(managerSendStreams.size()); - for (SendStreamDesc sendStreamDesc : this.sendStreams) - if (managerSendStreams.contains(sendStreamDesc.sendStream)) - { - SendStream sendStream - = sendStreamDesc.getSendStream(streamRTPManager, false); - - if (sendStream != null) - sendStreams.add(sendStream); - } - } - return sendStreams; - } - - private synchronized StreamRTPManagerDesc getStreamRTPManagerDesc( - StreamRTPManager streamRTPManager, - boolean create) - { - for (StreamRTPManagerDesc s : streamRTPManagers) - if (s.streamRTPManager == streamRTPManager) - return s; - - StreamRTPManagerDesc s; - - if (create) - { - s = new StreamRTPManagerDesc(streamRTPManager); - streamRTPManagers.add(s); - } - else - s = null; - return s; - } - - public synchronized void initialize( - StreamRTPManager streamRTPManager, - RTPConnector connector) - { - if (this.connector == null) - { - this.connector = new RTPConnectorImpl(); - manager.initialize(this.connector); - } - - StreamRTPManagerDesc streamRTPManagerDesc - = getStreamRTPManagerDesc(streamRTPManager, true); - RTPConnectorDesc connectorDesc = streamRTPManagerDesc.connectorDesc; - - if ((connectorDesc == null) || (connectorDesc.connector != connector)) - { - if (connectorDesc != null) - this.connector.removeConnector(connectorDesc); - streamRTPManagerDesc.connectorDesc - = connectorDesc - = (connector == null) - ? null - : new RTPConnectorDesc(streamRTPManagerDesc, connector); - if (connectorDesc != null) - this.connector.addConnector(connectorDesc); - } - } - - private int read( - PushSourceStreamDesc streamDesc, - byte[] buffer, int offset, int length, - int read) - throws IOException - { - boolean data = streamDesc.data; - StreamRTPManagerDesc streamRTPManagerDesc - = streamDesc.connectorDesc.streamRTPManagerDesc; - Format format = null; - - if (data) - { - if (length >= 12) - { - long ssrc = readInt(buffer, offset + 8); - - if (!streamRTPManagerDesc.containsReceiveSSRC(ssrc)) - { - if (findStreamRTPManagerDescByReceiveSSRC( - ssrc, - streamRTPManagerDesc) - == null) - streamRTPManagerDesc.addReceiveSSRC(ssrc); - else - return 0; - } - - int payloadType = buffer[offset + 1] & 0x7f; - - format = streamRTPManagerDesc.getFormat(payloadType); - } - } - - OutputDataStreamImpl outputStream - = data - ? connector.getDataOutputStream() - : connector.getControlOutputStream(); - - if (outputStream != null) - { - outputStream.write( - buffer, offset, read, - format, - streamRTPManagerDesc); - } - - return read; - } - - /** - * Reads an int from a specific byte buffer starting at a - * specific offset. The implementation is the same as - * {@link DataInputStream#readInt()}. - * - * @param buffer the byte buffer to read an int from - * @param offset the zero-based offset in buffer to start reading - * an int from - * @return an int read from the specified buffer starting - * at the specified offset - */ - private static int readInt(byte[] buffer, int offset) - { - return - ((buffer[offset++] & 0xff) << 24) - | ((buffer[offset++] & 0xff) << 16) - | ((buffer[offset++] & 0xff) << 8) - | (buffer[offset] & 0xff); - } - - public synchronized void removeReceiveStreamListener( - StreamRTPManager streamRTPManager, - ReceiveStreamListener listener) - { - StreamRTPManagerDesc streamRTPManagerDesc - = getStreamRTPManagerDesc(streamRTPManager, false); - - if (streamRTPManagerDesc != null) - streamRTPManagerDesc.removeReceiveStreamListener(listener); - } - - public void removeRemoteListener( - StreamRTPManager streamRTPManager, - RemoteListener listener) - { - manager.removeRemoteListener(listener); - } - - public void removeSendStreamListener( - StreamRTPManager streamRTPManager, - SendStreamListener listener) - { - // TODO Auto-generated method stub - } - - public void removeSessionListener( - StreamRTPManager streamRTPManager, - SessionListener listener) - { - // TODO Auto-generated method stub - } - - /** - * Notifies this ReceiveStreamListener about a specific event - * related to a ReceiveStream. - * - * @param event a ReceiveStreamEvent which contains the specifics - * of the event this ReceiveStreamListener is being notified about - * @see ReceiveStreamListener#update(ReceiveStreamEvent) - */ - public void update(ReceiveStreamEvent event) - { - /* - * Because NullPointerException was seen during testing, be thorough - * with the null checks. - */ - if (event != null) - { - ReceiveStream receiveStream = event.getReceiveStream(); - - if (receiveStream != null) - { - StreamRTPManagerDesc streamRTPManagerDesc - = findStreamRTPManagerDescByReceiveSSRC( - receiveStream.getSSRC(), - null); - - if (streamRTPManagerDesc != null) - for (ReceiveStreamListener listener - : streamRTPManagerDesc.getReceiveStreamListeners()) - listener.update(event); - } - } - } - - private static class OutputDataStreamDesc - { - public RTPConnectorDesc connectorDesc; - - public OutputDataStream stream; - - public OutputDataStreamDesc( - RTPConnectorDesc connectorDesc, - OutputDataStream stream) - { - this.connectorDesc = connectorDesc; - this.stream = stream; - } - } - - private static class OutputDataStreamImpl - implements OutputDataStream, - Runnable - { - private static final int WRITE_QUEUE_CAPACITY - = RTPConnectorOutputStream - .MAX_PACKETS_PER_MILLIS_POLICY_PACKET_QUEUE_CAPACITY; - - private boolean closed; - - private final boolean data; - - private final List streams - = new ArrayList(); - - private final RTPTranslatorBuffer[] writeQueue - = new RTPTranslatorBuffer[WRITE_QUEUE_CAPACITY]; - - private int writeQueueHead; - - private int writeQueueLength; - - private Thread writeThread; - - public OutputDataStreamImpl(boolean data) - { - this.data = data; - } - - public synchronized void addStream( - RTPConnectorDesc connectorDesc, - OutputDataStream stream) - { - for (OutputDataStreamDesc streamDesc : streams) - if ((streamDesc.connectorDesc == connectorDesc) - && (streamDesc.stream == stream)) - return; - streams.add(new OutputDataStreamDesc(connectorDesc, stream)); - } - - public synchronized void close() - { - closed = true; - writeThread = null; - notify(); - } - - private synchronized void createWriteThread() - { - writeThread = new Thread(this, getClass().getName()); - writeThread.setDaemon(true); - writeThread.start(); - } - - private synchronized int doWrite( - byte[] buffer, int offset, int length, - Format format, - StreamRTPManagerDesc exclusion) - { - int write = 0; - - for (int streamIndex = 0, streamCount = streams.size(); - streamIndex < streamCount; - streamIndex++) - { - OutputDataStreamDesc streamDesc = streams.get(streamIndex); - StreamRTPManagerDesc streamRTPManagerDesc - = streamDesc.connectorDesc.streamRTPManagerDesc; - - if (streamRTPManagerDesc != exclusion) - { - if (data && (format != null) && (length > 0)) - { - Integer payloadType - = streamRTPManagerDesc.getPayloadType(format); - - if ((payloadType == null) && (exclusion != null)) - payloadType = exclusion.getPayloadType(format); - if (payloadType != null) - { - int payloadTypeByteIndex = offset + 1; - - buffer[payloadTypeByteIndex] - = (byte) - ((buffer[payloadTypeByteIndex] & 0x80) - | (payloadType & 0x7f)); - } - } - - int streamWrite - = streamDesc.stream.write(buffer, offset, length); - - if (write < streamWrite) - write = streamWrite; - } - } - return write; - } - - public synchronized void removeStreams(RTPConnectorDesc connectorDesc) - { - Iterator streamIter = streams.iterator(); - - while (streamIter.hasNext()) - { - OutputDataStreamDesc streamDesc = streamIter.next(); - - if (streamDesc.connectorDesc == connectorDesc) - streamIter.remove(); - } - } - - public void run() - { - try - { - while (true) - { - int writeIndex; - byte[] buffer; - StreamRTPManagerDesc exclusion; - Format format; - int length; - - synchronized (this) - { - if (closed - || !Thread.currentThread().equals(writeThread)) - break; - if (writeQueueLength < 1) - { - boolean interrupted = false; - - try - { - wait(); - } - catch (InterruptedException ie) - { - interrupted = true; - } - if (interrupted) - Thread.currentThread().interrupt(); - continue; - } - - writeIndex = writeQueueHead; - - RTPTranslatorBuffer write = writeQueue[writeIndex]; - - buffer = write.data; - write.data = null; - exclusion = write.exclusion; - write.exclusion = null; - format = write.format; - write.format = null; - length = write.length; - write.length = 0; - - writeQueueHead++; - if (writeQueueHead >= writeQueue.length) - writeQueueHead = 0; - writeQueueLength--; - } - - try - { - doWrite(buffer, 0, length, format, exclusion); - } - finally - { - synchronized (this) - { - RTPTranslatorBuffer write = writeQueue[writeIndex]; - - if ((write != null) && (write.data == null)) - write.data = buffer; - } - } - } - } - catch (Throwable t) - { - logger.error("Failed to translate RTP packet", t); - if (t instanceof ThreadDeath) - throw (ThreadDeath) t; - } - finally - { - synchronized (this) - { - if (Thread.currentThread().equals(writeThread)) - writeThread = null; - if (!closed - && (writeThread == null) - && (writeQueueLength > 0)) - createWriteThread(); - } - } - } - - public int write(byte[] buffer, int offset, int length) - { - return doWrite(buffer, offset, length, null, null); - } - - public synchronized void write( - byte[] buffer, int offset, int length, - Format format, - StreamRTPManagerDesc exclusion) - { - if (closed) - return; - - int writeIndex; - - if (writeQueueLength < writeQueue.length) - { - writeIndex - = (writeQueueHead + writeQueueLength) % writeQueue.length; - } - else - { - writeIndex = writeQueueHead; - writeQueueHead++; - if (writeQueueHead >= writeQueue.length) - writeQueueHead = 0; - writeQueueLength--; - logger.warn("Will not translate RTP packet."); - } - - RTPTranslatorBuffer write - = writeQueue[writeIndex]; - - if (write == null) - writeQueue[writeIndex] = write = new RTPTranslatorBuffer(); - - byte[] data = write.data; - - if ((data == null) || (data.length < length)) - write.data = data = new byte[length]; - System.arraycopy(buffer, offset, data, 0, length); - - write.exclusion = exclusion; - write.format = format; - write.length = length; - - writeQueueLength++; - - if (writeThread == null) - createWriteThread(); - else - notify(); - } - } - - private static class PushSourceStreamDesc - { - public final RTPConnectorDesc connectorDesc; - - public final boolean data; - - public final PushSourceStream stream; - - public PushSourceStreamDesc( - RTPConnectorDesc connectorDesc, - PushSourceStream stream, - boolean data) - { - this.connectorDesc = connectorDesc; - this.stream = stream; - this.data = data; - } - } - - private class PushSourceStreamImpl - implements PushSourceStream, - SourceTransferHandler - { - private final boolean data; - - private final List streams - = new LinkedList(); - - private PushSourceStreamDesc streamToReadFrom; - - private SourceTransferHandler transferHandler; - - public PushSourceStreamImpl(boolean data) - { - this.data = data; - } - - public synchronized void addStream( - RTPConnectorDesc connectorDesc, - PushSourceStream stream) - { - for (PushSourceStreamDesc streamDesc : streams) - if ((streamDesc.connectorDesc == connectorDesc) - && (streamDesc.stream == stream)) - return; - streams.add( - new PushSourceStreamDesc(connectorDesc, stream, this.data)); - stream.setTransferHandler(this); - } - - public void close() - { - // TODO Auto-generated method stub - } - - public boolean endOfStream() - { - // TODO Auto-generated method stub - return false; - } - - public ContentDescriptor getContentDescriptor() - { - // TODO Auto-generated method stub - return null; - } - - public long getContentLength() - { - return LENGTH_UNKNOWN; - } - - public Object getControl(String controlType) - { - // TODO Auto-generated method stub - return null; - } - - public Object[] getControls() - { - // TODO Auto-generated method stub - return null; - } - - public synchronized int getMinimumTransferSize() - { - int minimumTransferSize = 0; - - for (PushSourceStreamDesc streamDesc : streams) - { - int streamMinimumTransferSize - = streamDesc.stream.getMinimumTransferSize(); - - if (minimumTransferSize < streamMinimumTransferSize) - minimumTransferSize = streamMinimumTransferSize; - } - return minimumTransferSize; - } - - public int read(byte[] buffer, int offset, int length) - throws IOException - { - PushSourceStreamDesc streamDesc; - int read; - - synchronized (this) - { - streamDesc = streamToReadFrom; - read - = (streamDesc == null) - ? 0 - : streamDesc.stream.read(buffer, offset, length); - } - if (read > 0) - { - read - = RTPTranslatorImpl.this.read( - streamDesc, - buffer, offset, length, - read); - } - return read; - } - - public synchronized void removeStreams(RTPConnectorDesc connectorDesc) - { - Iterator streamIter = streams.iterator(); - - while (streamIter.hasNext()) - { - PushSourceStreamDesc streamDesc = streamIter.next(); - - if (streamDesc.connectorDesc == connectorDesc) - { - streamDesc.stream.setTransferHandler(null); - streamIter.remove(); - if (streamToReadFrom == streamDesc) - streamToReadFrom = null; - } - } - } - - public synchronized void setTransferHandler( - SourceTransferHandler transferHandler) - { - if (this.transferHandler != transferHandler) - { - this.transferHandler = transferHandler; - for (PushSourceStreamDesc streamDesc : streams) - streamDesc.stream.setTransferHandler(this); - } - } - - public synchronized void transferData(PushSourceStream stream) - { - SourceTransferHandler transferHandler = null; - - for (PushSourceStreamDesc streamDesc : streams) - if (streamDesc.stream == stream) - { - streamToReadFrom = streamDesc; - transferHandler = this.transferHandler; - break; - } - - if (transferHandler != null) - transferHandler.transferData(this); - } - } - - private static class RTPConnectorDesc - { - public final RTPConnector connector; - - public final StreamRTPManagerDesc streamRTPManagerDesc; - - public RTPConnectorDesc( - StreamRTPManagerDesc streamRTPManagerDesc, - RTPConnector connector) - { - this.streamRTPManagerDesc = streamRTPManagerDesc; - this.connector = connector; - } - } - - /** - * Implements the RTPConnector with which this instance initializes - * its RTPManager. It delegates to the RTPConnector of the - * various StreamRTPManagers. - */ - private class RTPConnectorImpl - implements RTPConnector - { - /** - * The RTPConnectors this instance delegates to. - */ - private final List connectors - = new LinkedList(); - - private PushSourceStreamImpl controlInputStream; - - private OutputDataStreamImpl controlOutputStream; - - private PushSourceStreamImpl dataInputStream; - - private OutputDataStreamImpl dataOutputStream; - - public synchronized void addConnector(RTPConnectorDesc connector) - { - if (!connectors.contains(connector)) - { - connectors.add(connector); - if (this.controlInputStream != null) - { - PushSourceStream controlInputStream = null; - - try - { - controlInputStream - = connector.connector.getControlInputStream(); - } - catch (IOException ioe) - { - throw new UndeclaredThrowableException(ioe); - } - if (controlInputStream != null) - { - this.controlInputStream.addStream( - connector, - controlInputStream); - } - } - if (this.controlOutputStream != null) - { - OutputDataStream controlOutputStream = null; - - try - { - controlOutputStream - = connector.connector.getControlOutputStream(); - } - catch (IOException ioe) - { - throw new UndeclaredThrowableException(ioe); - } - if (controlOutputStream != null) - { - this.controlOutputStream.addStream( - connector, - controlOutputStream); - } - } - if (this.dataInputStream != null) - { - PushSourceStream dataInputStream = null; - - try - { - dataInputStream - = connector.connector.getDataInputStream(); - } - catch (IOException ioe) - { - throw new UndeclaredThrowableException(ioe); - } - if (dataInputStream != null) - { - this.dataInputStream.addStream( - connector, - dataInputStream); - } - } - if (this.dataOutputStream != null) - { - OutputDataStream dataOutputStream = null; - - try - { - dataOutputStream - = connector.connector.getDataOutputStream(); - } - catch (IOException ioe) - { - throw new UndeclaredThrowableException(ioe); - } - if (dataOutputStream != null) - { - this.dataOutputStream.addStream( - connector, - dataOutputStream); - } - } - } - } - - public synchronized void close() - { - if (controlInputStream != null) - { - controlInputStream.close(); - controlInputStream = null; - } - if (controlOutputStream != null) - { - controlOutputStream.close(); - controlOutputStream = null; - } - if (dataInputStream != null) - { - dataInputStream.close(); - dataInputStream = null; - } - if (dataOutputStream != null) - { - dataOutputStream.close(); - dataOutputStream = null; - } - - for (RTPConnectorDesc connectorDesc : connectors) - connectorDesc.connector.close(); - } - - public synchronized PushSourceStream getControlInputStream() - throws IOException - { - if (this.controlInputStream == null) - { - this.controlInputStream = new PushSourceStreamImpl(false); - for (RTPConnectorDesc connectorDesc : connectors) - { - PushSourceStream controlInputStream - = connectorDesc.connector.getControlInputStream(); - - if (controlInputStream != null) - { - this.controlInputStream.addStream( - connectorDesc, - controlInputStream); - } - } - } - return this.controlInputStream; - } - - public synchronized OutputDataStreamImpl getControlOutputStream() - throws IOException - { - if (this.controlOutputStream == null) - { - this.controlOutputStream = new OutputDataStreamImpl(false); - for (RTPConnectorDesc connectorDesc : connectors) - { - OutputDataStream controlOutputStream - = connectorDesc.connector.getControlOutputStream(); - - if (controlOutputStream != null) - { - this.controlOutputStream.addStream( - connectorDesc, - controlOutputStream); - } - } - } - return this.controlOutputStream; - } - - public synchronized PushSourceStream getDataInputStream() - throws IOException - { - if (this.dataInputStream == null) - { - this.dataInputStream = new PushSourceStreamImpl(true); - for (RTPConnectorDesc connectorDesc : connectors) - { - PushSourceStream dataInputStream - = connectorDesc.connector.getDataInputStream(); - - if (dataInputStream != null) - { - this.dataInputStream.addStream( - connectorDesc, - dataInputStream); - } - } - } - return this.dataInputStream; - } - - public synchronized OutputDataStreamImpl getDataOutputStream() - throws IOException - { - if (this.dataOutputStream == null) - { - this.dataOutputStream = new OutputDataStreamImpl(true); - for (RTPConnectorDesc connectorDesc : connectors) - { - OutputDataStream dataOutputStream - = connectorDesc.connector.getDataOutputStream(); - - if (dataOutputStream != null) - { - this.dataOutputStream.addStream( - connectorDesc, - dataOutputStream); - } - } - } - return this.dataOutputStream; - } - - public int getReceiveBufferSize() - { - return -1; - } - - public double getRTCPBandwidthFraction() - { - return -1; - } - - public double getRTCPSenderBandwidthFraction() - { - return -1; - } - - public int getSendBufferSize() - { - return -1; - } - - public synchronized void removeConnector(RTPConnectorDesc connector) - { - if (connectors.contains(connector)) - { - if (controlInputStream != null) - controlInputStream.removeStreams(connector); - if (controlOutputStream != null) - controlOutputStream.removeStreams(connector); - if (dataInputStream != null) - dataInputStream.removeStreams(connector); - if (dataOutputStream != null) - dataOutputStream.removeStreams(connector); - connectors.remove(connector); - } - } - - public void setReceiveBufferSize(int receiveBufferSize) - throws IOException - { - // TODO Auto-generated method stub - } - - public void setSendBufferSize(int sendBufferSize) - throws IOException - { - // TODO Auto-generated method stub - } - } - - private static class RTPTranslatorBuffer - { - public byte[] data; - - public StreamRTPManagerDesc exclusion; - - public Format format; - - public int length; - } - - /** - * Describes a SendStream created by the RTPManager of - * this instance. Contains information about the DataSource and its - * stream index from which the SendStream has been created so that - * various StreamRTPManager receive different views of one and the - * same SendStream. - */ - private class SendStreamDesc - { - /** - * The DataSource from which {@link #sendStream} has been - * created. - */ - public final DataSource dataSource; - - /** - * The SendStream created from the stream of - * {@link #dataSource} at index {@link #streamIndex}. - */ - public final SendStream sendStream; - - /** - * The list of StreamRTPManager-specific views to - * {@link #sendStream}. - */ - private final List sendStreams - = new LinkedList(); - - /** - * The number of StreamRTPManagers which have started their - * views of {@link #sendStream}. - */ - private int started; - - /** - * The index of the stream of {@link #dataSource} from which - * {@link #sendStream} has been created. - */ - public final int streamIndex; - - public SendStreamDesc( - DataSource dataSource, int streamIndex, - SendStream sendStream) - { - this.dataSource = dataSource; - this.sendStream = sendStream; - this.streamIndex = streamIndex; - } - - void close(SendStreamImpl sendStream) - { - boolean close = false; - - synchronized (this) - { - if (sendStreams.contains(sendStream)) - { - sendStreams.remove(sendStream); - close = sendStreams.isEmpty(); - } - } - if (close) - RTPTranslatorImpl.this.closeSendStream(this); - } - - public synchronized SendStreamImpl getSendStream( - StreamRTPManager streamRTPManager, - boolean create) - { - for (SendStreamImpl sendStream : sendStreams) - if (sendStream.streamRTPManager == streamRTPManager) - return sendStream; - if (create) - { - SendStreamImpl sendStream - = new SendStreamImpl(streamRTPManager, this); - - sendStreams.add(sendStream); - return sendStream; - } - else - return null; - } - - public synchronized int getSendStreamCount() - { - return sendStreams.size(); - } - - synchronized void start(SendStreamImpl sendStream) - throws IOException - { - if (sendStreams.contains(sendStream)) - { - if (started < 1) - { - this.sendStream.start(); - started = 1; - } - else - started++; - } - } - - synchronized void stop(SendStreamImpl sendStream) - throws IOException - { - if (sendStreams.contains(sendStream)) - { - if (started == 1) - { - this.sendStream.stop(); - started = 0; - } - else if (started > 1) - started--; - } - } - } - - private static class SendStreamImpl - implements SendStream - { - private boolean closed; - - public final SendStreamDesc sendStreamDesc; - - private boolean started; - - public final StreamRTPManager streamRTPManager; - - public SendStreamImpl( - StreamRTPManager streamRTPManager, - SendStreamDesc sendStreamDesc) - { - this.sendStreamDesc = sendStreamDesc; - this.streamRTPManager = streamRTPManager; - } - - public void close() - { - if (!closed) - { - try - { - if (started) - stop(); - } - catch (IOException ioe) - { - throw new UndeclaredThrowableException(ioe); - } - finally - { - sendStreamDesc.close(this); - closed = true; - } - } - } - - public DataSource getDataSource() - { - return sendStreamDesc.sendStream.getDataSource(); - } - - public Participant getParticipant() - { - return sendStreamDesc.sendStream.getParticipant(); - } - - public SenderReport getSenderReport() - { - return sendStreamDesc.sendStream.getSenderReport(); - } - - public TransmissionStats getSourceTransmissionStats() - { - return sendStreamDesc.sendStream.getSourceTransmissionStats(); - } - - public long getSSRC() - { - return sendStreamDesc.sendStream.getSSRC(); - } - - public int setBitRate(int bitRate) - { - // TODO Auto-generated method stub - return 0; - } - - public void setSourceDescription(SourceDescription[] sourceDescription) - { - // TODO Auto-generated method stub - } - - public void start() - throws IOException - { - if (closed) - { - throw - new IOException( - "Cannot start SendStream" - + " after it has been closed."); - } - if (!started) - { - sendStreamDesc.start(this); - started = true; - } - } - - public void stop() - throws IOException - { - if (!closed && started) - { - sendStreamDesc.stop(this); - started = false; - } - } - } - - private static class StreamRTPManagerDesc - { - public RTPConnectorDesc connectorDesc; - - private final Map formats - = new HashMap(); - - private long[] receiveSSRCs = EMPTY_LONG_ARRAY; - - private final List receiveStreamListeners - = new LinkedList(); - - public final StreamRTPManager streamRTPManager; - - public StreamRTPManagerDesc(StreamRTPManager streamRTPManager) - { - this.streamRTPManager = streamRTPManager; - } - - public void addFormat(Format format, int payloadType) - { - synchronized (formats) - { - formats.put(payloadType, format); - } - } - - public synchronized void addReceiveSSRC(long receiveSSRC) - { - if (!containsReceiveSSRC(receiveSSRC)) - { - int receiveSSRCCount = receiveSSRCs.length; - long[] newReceiveSSRCs = new long[receiveSSRCCount + 1]; - - System.arraycopy( - receiveSSRCs, 0, - newReceiveSSRCs, 0, - receiveSSRCCount); - newReceiveSSRCs[receiveSSRCCount] = receiveSSRC; - receiveSSRCs = newReceiveSSRCs; - } - } - - public void addReceiveStreamListener(ReceiveStreamListener listener) - { - synchronized (receiveStreamListeners) - { - if (!receiveStreamListeners.contains(listener)) - receiveStreamListeners.add(listener); - } - } - - public Format getFormat(int payloadType) - { - synchronized (formats) - { - return formats.get(payloadType); - } - } - - public Integer getPayloadType(Format format) - { - synchronized (formats) - { - for (Map.Entry entry : formats.entrySet()) - { - Format entryFormat = entry.getValue(); - - if (entryFormat.matches(format) - || format.matches(entryFormat)) - return entry.getKey(); - } - } - return null; - } - - public ReceiveStreamListener[] getReceiveStreamListeners() - { - synchronized (receiveStreamListeners) - { - return - receiveStreamListeners.toArray( - new ReceiveStreamListener[ - receiveStreamListeners.size()]); - } - } - - public synchronized boolean containsReceiveSSRC(long receiveSSRC) - { - for (int i = 0; i < receiveSSRCs.length; i++) - if (receiveSSRCs[i] == receiveSSRC) - return true; - return false; - } - - public void removeReceiveStreamListener(ReceiveStreamListener listener) - { - synchronized (receiveStreamListeners) - { - receiveStreamListeners.remove(listener); - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/RawPacket.java b/src/net/java/sip/communicator/impl/neomedia/RawPacket.java deleted file mode 100644 index 6f90fa8eb..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/RawPacket.java +++ /dev/null @@ -1,962 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -/** - * When using TransformConnector, a RTP/RTCP packet is represented using - * RawPacket. RawPacket stores the buffer holding the RTP/RTCP packet, as well - * as the inner offset and length of RTP/RTCP packet data. - * - * After transformation, data is also store in RawPacket objects, either the - * original RawPacket (in place transformation), or a newly created RawPacket. - * - * Besides packet info storage, RawPacket also provides some other operations - * such as readInt() to ease the development process. - * - * @author Werner Dittmann (Werner.Dittmann@t-online.de) - * @author Bing SU (nova.su@gmail.com) - * @author Emil Ivov - * @author Damian Minkov - */ -public class RawPacket -{ - /** - * The size of the fixed part of the RTP header as defined by RFC 3550. - */ - public static final int FIXED_HEADER_SIZE = 12; - - /** - * The size of the extension header as defined by RFC 3550. - */ - public static final int EXT_HEADER_SIZE = 4; - - /** - * Byte array storing the content of this Packet - */ - private byte[] buffer; - - /** - * Start offset of the packet data inside buffer. - * Usually this value would be 0. But in order to be compatible with - * RTPManager we store this info. (Not assuming the offset is always zero) - */ - private int offset; - - /** - * Length of this packet's data - */ - private int length; - - /** - * Construct an empty RawPacket - * - */ - public RawPacket() - { - } - - /** - * Construct a RawPacket using specified value. - * - * @param buffer Byte array holding the content of this Packet - * @param offset Start offset of packet content inside buffer - * @param length Length of the packet's data - */ - public RawPacket(byte[] buffer, int offset, int length) - { - this.buffer = buffer; - this.offset = offset; - this.length = length; - } - - /** - * Get buffer containing the content of this packet - * - * @return buffer containing the content of this packet - */ - public byte[] getBuffer() - { - return this.buffer; - } - - /** - * Get the length of this packet's data - * - * @return length of this packet's data - */ - public int getLength() - { - return this.length; - } - - /** - * Get the start offset of this packet's data inside storing buffer - * - * @return start offset of this packet's data inside storing buffer - */ - public int getOffset() - { - return this.offset; - } - - /** - * @param buffer the buffer to set - */ - protected void setBuffer(byte[] buffer) { - this.buffer = buffer; - } - /** - * @param offset the offset to set - */ - protected void setOffset(int offset) { - this.offset = offset; - } - - /** - * @param length the length to set - */ - protected void setLength(int length) { - this.length = length; - } - - - /** - * Sets or resets the marker bit of this packet according to the - * marker parameter. - * @param marker true if we are to raise the marker bit and - * false otherwise. - */ - public void setMarker(boolean marker) - { - if(marker) - { - buffer[offset + 1] |= (byte) 0x80; - } - else - { - buffer[offset + 1] &= (byte) 0x7F; - } - } - - /** - * Sets the payload of this packet. - * - * @param payload the RTP payload type describing the content of this - * packet. - */ - public void setPayload(byte payload) - { - //this is supposed to be a 7bit payload so make sure that the leftmost - //bit is 0 so that we don't accidentally overwrite the marker. - payload &= (byte)0x7F; - - buffer[offset + 1] = (byte)((buffer[offset + 1] & 0x80) | payload); - } - - /** - * Returns the timestamp for this RTP RawPacket. - * - * @return the timestamp for this RTP RawPacket. - */ - public long getTimestamp() - { - return readInt(offset + 4); - } - - /** - * Set the timestamp value of the RTP Packet - * - * @param timestamp : the RTP Timestamp - */ - public void setTimestamp(long timestamp) - { - writeInt(offset + 4, (int)timestamp); - } - - /** - * Read a integer from this packet at specified offset - * - * @param off start offset of the integer to be read - * @return the integer to be read - */ - public int readInt(int off) - { - return (this.buffer[this.offset + off + 0] << 24) | - ((this.buffer[this.offset + off + 1] & 0xff) << 16) | - ((this.buffer[this.offset + off + 2] & 0xff) << 8) | - (this.buffer[this.offset + off + 3] & 0xff); - } - - /** - * Set an integer at specified offset in network order. - * - * @param off Offset into the buffer - * @param data The integer to store in the packet - */ - public void writeInt(int off, int data) - { - buffer[offset + off++] = (byte)(data>>24); - buffer[offset + off++] = (byte)(data>>16); - buffer[offset + off++] = (byte)(data>>8); - buffer[offset + off] = (byte)data; - } - - /** - * Read a short from this packet at specified offset - * - * @param off start offset of this short - * @return short value at offset - */ - public short readShort(int off) - { - return (short) ((this.buffer[this.offset + off + 0] << 8) | - (this.buffer[this.offset + off + 1] & 0xff)); - } - - /** - * Read an unsigned short at specified offset as a int - * - * @param off start offset of the unsigned short - * @return the int value of the unsigned short at offset - */ - public int readUnsignedShortAsInt(int off) - { - int b1 = (0x000000FF & (this.buffer[this.offset + off + 0])); - int b2 = (0x000000FF & (this.buffer[this.offset + off + 1])); - int val = b1 << 8 | b2; - return val; - } - - /** - * Read a byte from this packet at specified offset - * - * @param off start offset of the byte - * @return byte at offset - */ - public byte readByte(int off) - { - return buffer[offset + off]; - } - - /** - * Write a byte to this packet at specified offset - * - * @param off start offset of the byte - * @param b byte to write - */ - public void writeByte(int off, byte b) - { - buffer[offset + off] = b; - } - - /** - * Read an unsigned integer as long at specified offset - * - * @param off start offset of this unsigned integer - * @return unsigned integer as long at offset - */ - public long readUnsignedIntAsLong(int off) - { - int b0 = (0x000000FF & (this.buffer[this.offset + off + 0])); - int b1 = (0x000000FF & (this.buffer[this.offset + off + 1])); - int b2 = (0x000000FF & (this.buffer[this.offset + off + 2])); - int b3 = (0x000000FF & (this.buffer[this.offset + off + 3])); - - return ((b0 << 24 | b1 << 16 | b2 << 8 | b3)) & 0xFFFFFFFFL; - } - - /** - * Read a byte region from specified offset with specified length - * - * @param off start offset of the region to be read - * @param len length of the region to be read - * @return byte array of [offset, offset + length) - */ - public byte[] readRegion(int off, int len) - { - int startOffset = this.offset + off; - if (off < 0 || len <= 0 || startOffset + len > this.buffer.length) - return null; - - byte[] region = new byte[len]; - - System.arraycopy(this.buffer, startOffset, region, 0, len); - - return region; - } - - /** - * Read a byte region from specified offset with specified length in given - * buffer - * - * @param off start offset of the region to be read - * @param len length of the region to be read - * @param outBuff output buffer - */ - public void readRegionToBuff(int off, int len, byte[] outBuff) - { - int startOffset = this.offset + off; - if (off < 0 || len <= 0 || startOffset + len > this.buffer.length) - return; - - if (outBuff.length < len) - return; - - System.arraycopy(this.buffer, startOffset, outBuff, 0, len); - } - - /** - * Grow the internal packet buffer. - * - * This will change the data buffer of this packet but not the - * length of the valid data. Use this to grow the internal buffer - * to avoid buffer re-allocations when appending data. - * - * @param howMuch number of bytes to grow - */ - public void grow(int howMuch) { - if (howMuch == 0) { - return; - } - byte[] newBuffer = new byte[this.length + howMuch]; - System.arraycopy(this.buffer, this.offset, newBuffer, 0, this.length); - offset = 0; - buffer = newBuffer; - } - - /** - * Append a byte array to the end of the packet. This may change the data - * buffer of this packet. - * - * @param data byte array to append - * @param len the number of bytes to append - */ - public void append(byte[] data, int len) { - if (data == null || len == 0) { - return; - } - - // re-allocate internal buffer if it is too small - if ((this.length + len) > (buffer.length - this.offset)) { - byte[] newBuffer = new byte[this.length + len]; - System.arraycopy(this.buffer, this.offset, newBuffer, 0, this.length); - this.offset = 0; - this.buffer = newBuffer; - } - // append data - System.arraycopy(data, 0, this.buffer, this.length, len); - this.length = this.length + len; - - } - - /** - * Shrink the buffer of this packet by specified length - * - * @param len length to shrink - */ - public void shrink(int len) - { - if (len <= 0) - return; - - this.length -= len; - if (this.length < 0) - this.length = 0; - } - - /** - * Returns the number of CSRC identifiers currently included in this packet. - * - * @return the CSRC count for this RawPacket. - */ - public int getCsrcCount() - { - return (buffer[offset] & 0x0f); - } - - /** - * Replaces the existing CSRC list (even if empty) with newCsrcList - * and updates the CC (CSRC count) field of this RawPacket - * accordingly. - * - * @param newCsrcList the list of CSRC identifiers that we'd like to set for - * this RawPacket. - */ - public void setCsrcList(long[] newCsrcList) - { - int newCsrcCount = newCsrcList.length; - byte[] csrcBuff = new byte[newCsrcCount * 4]; - int csrcOffset = 0; - - for(long csrc : newCsrcList) - { - csrcBuff[csrcOffset] = (byte)(csrc >> 24); - csrcBuff[csrcOffset+1] = (byte)(csrc >> 16); - csrcBuff[csrcOffset+2] = (byte)(csrc >> 8); - csrcBuff[csrcOffset+3] = (byte)csrc; - - csrcOffset += 4; - } - - int oldCsrcCount = getCsrcCount(); - - byte[] oldBuffer = this.getBuffer(); - - //the new buffer needs to be bigger than the new one in order to - //accommodate the list of CSRC IDs (unless there were more of them - //previously than after setting the new list). - byte[] newBuffer - = new byte[length + offset + csrcBuff.length - oldCsrcCount*4]; - - //copy the part up to the CSRC list - System.arraycopy( - oldBuffer, 0, newBuffer, 0, offset + FIXED_HEADER_SIZE); - - //copy the new CSRC list - System.arraycopy( csrcBuff, 0, newBuffer, - offset + FIXED_HEADER_SIZE, csrcBuff.length); - - //now copy the payload from the old buff and make sure we don't copy - //the CSRC list if there was one in the old packet - int payloadOffsetForOldBuff - = offset + FIXED_HEADER_SIZE + oldCsrcCount*4; - - int payloadOffsetForNewBuff - = offset + FIXED_HEADER_SIZE + newCsrcCount*4; - - System.arraycopy( oldBuffer, payloadOffsetForOldBuff, - newBuffer, payloadOffsetForNewBuff, - length - payloadOffsetForOldBuff); - - //set the new CSRC count - newBuffer[offset] = (byte)((newBuffer[offset] & 0xF0) - | newCsrcCount); - - this.buffer = newBuffer; - this.length = payloadOffsetForNewBuff + length - - payloadOffsetForOldBuff - offset; - } - - /** - * Returns the list of CSRC IDs, currently encapsulated in this packet. - * - * @return an array containing the list of CSRC IDs, currently encapsulated - * in this packet. - */ - public long[] extractCsrcList() - { - int csrcCount = getCsrcCount(); - long[] csrcList = new long[csrcCount]; - int csrcStartIndex = offset + FIXED_HEADER_SIZE; - - for (int i = 0; i < csrcCount; i++) - { - csrcList[i] = readInt(csrcStartIndex); - - csrcStartIndex += 4; - } - - return csrcList; - } - - /** - * Get RTP padding size from a RTP packet - * - * @return RTP padding size from source RTP packet - */ - public int getPaddingSize() - { - if ((buffer[offset] & 0x4) == 0) - return 0; - else - return buffer[offset + length - 1]; - } - - /** - * Get RTP header length from a RTP packet - * - * @return RTP header length from source RTP packet - */ - public int getHeaderLength() - { - if(getExtensionBit()) - return FIXED_HEADER_SIZE + 4 * getCsrcCount() - + EXT_HEADER_SIZE + getExtensionLength(); - else - return FIXED_HEADER_SIZE + 4 * getCsrcCount(); - } - - /** - * Get RTP payload length from a RTP packet - * - * @return RTP payload length from source RTP packet - */ - public int getPayloadLength() - { - return length - getHeaderLength(); - } - - /** - * Get RTP SSRC from a RTP packet - * - * @return RTP SSRC from source RTP packet - */ - public int getSSRC() - { - return (int)(readUnsignedIntAsLong(8) & 0xffffffff); - } - - /** - * Get RTCP SSRC from a RTCP packet - * - * @return RTP SSRC from source RTP packet - */ - public long getRTCPSSRC() - { - return (int)(readUnsignedIntAsLong(4) & 0xffffffff); - } - - /** - * Get RTP sequence number from a RTP packet - * - * @return RTP sequence num from source packet - */ - public int getSequenceNumber() - { - return readUnsignedShortAsInt(2); - } - - /** - * Get SRTCP sequence number from a SRTCP packet - * - * @param authTagLen authentication tag length - * @return SRTCP sequence num from source packet - */ - public int getSRTCPIndex(int authTagLen) - { - int offset = getLength() - (4 + authTagLen); - return readInt(offset); - } - /** - * Test whether if a RTP packet is padded - * - * @return whether if source RTP packet is padded - */ - public boolean isPacketMarked() - { - return (buffer[offset + 1] & 0x80) != 0; - } - - /** - * Get RTP payload type from a RTP packet - * - * @return RTP payload type of source RTP packet - */ - public byte getPayloadType() - { - return (byte) (buffer[offset + 1] & (byte)0x7F); - } - - /** - * Get the RTP payload (bytes) of this RTP packet. - * - * @return an array of bytes which represents the RTP payload of - * this RTP packet - */ - public byte[] getPayload() - { - return readRegion(getHeaderLength(), getPayloadLength()); - } - - /** - * Get RTP timestamp from a RTP packet - * - * @return RTP timestamp of source RTP packet - */ - public byte[] readTimeStampIntoByteArray() - { - return readRegion(4, 4); - } - - /** - * Returns true if the extension bit of this packet has been set - * and false otherwise. - * - * @return true if the extension bit of this packet has been set - * and false otherwise. - */ - public boolean getExtensionBit() - { - return (buffer[offset] & 0x10) == 0x10; - } - - /** - * Raises the extension bit of this packet is extBit is - * true or set it to 0 if extBit is - * false. - * - * @param extBit the flag that indicates whether we are to set or clear - * the extension bit of this packet. - */ - private void setExtensionBit(boolean extBit) - { - if(extBit) - buffer[offset] |= 0x10; - else - buffer[offset] &= 0xEF; - } - - /** - * Returns the length of the extensions currently added to this packet. - * - * @return the length of the extensions currently added to this packet. - */ - public int getExtensionLength() - { - if (!getExtensionBit()) - return 0; - - //the extension length comes after the RTP header, the CSRC list, and - //after two bytes in the extension header called "defined by profile" - int extLenIndex = offset - + FIXED_HEADER_SIZE - + getCsrcCount()*4 + 2; - - return ((buffer[extLenIndex] << 8) | buffer[extLenIndex + 1]) * 4; - } - - /** - * Adds the extBuff buffer to as an extension of this packet - * according the rules specified in RFC 5285. Note that this method does - * not replace extensions so if you add the same buffer twice it would be - * added as to separate extensions. - * - * @param extBuff the buffer that we'd like to add as an extension in this - * packet. - * @param newExtensionLen the length of the data in extBuff. - */ - public void addExtension(byte[] extBuff, int newExtensionLen) - { - int newBuffLen = length + offset + newExtensionLen; - int bufferOffset = offset; - int newBufferOffset = offset; - int lengthToCopy = FIXED_HEADER_SIZE + getCsrcCount()*4; - boolean extensionBit = getExtensionBit(); - //if there was no extension previously, we also need to consider adding - //the extension header. - if (extensionBit) - { - // without copying the extension length value, will set it later - lengthToCopy += EXT_HEADER_SIZE - 2; - } - else - newBuffLen += EXT_HEADER_SIZE; - - byte[] newBuffer = new byte[ newBuffLen ]; - - /* - * Copy header, CSRC list and the leading two bytes of the extension - * header if any. - */ - System.arraycopy(buffer, bufferOffset, - newBuffer, newBufferOffset, lengthToCopy); - //raise the extension bit. - newBuffer[newBufferOffset] |= 0x10; - bufferOffset += lengthToCopy; - newBufferOffset += lengthToCopy; - - // Set the extension header or modify the existing one. - int totalExtensionLen = newExtensionLen + getExtensionLength(); - - //if there were no extensions previously, we need to add the hdr now - if(extensionBit) - bufferOffset += 4; - else - { - // we will now be adding the RFC 5285 ext header which looks like - // this: - // - // 0 1 2 3 - // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | 0xBE | 0xDE | length=3 | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - newBuffer[newBufferOffset++] = (byte)0xBE; - newBuffer[newBufferOffset++] = (byte)0xDE; - } - // length field counts the number of 32-bit words in the extension - int lengthInWords = (totalExtensionLen + 3)/4; - newBuffer[newBufferOffset++] = (byte)(lengthInWords >> 8); - newBuffer[newBufferOffset++] = (byte)lengthInWords; - - // Copy the existing extension content if any. - if (extensionBit) - { - lengthToCopy = getExtensionLength(); - System.arraycopy(buffer, bufferOffset, - newBuffer, newBufferOffset, lengthToCopy); - bufferOffset += lengthToCopy; - newBufferOffset += lengthToCopy; - } - - //copy the extension content from the new extension. - System.arraycopy(extBuff, 0, - newBuffer, newBufferOffset, newExtensionLen); - newBufferOffset += newExtensionLen; - - //now copy the payload - System.arraycopy(buffer, bufferOffset, - newBuffer, newBufferOffset, getPayloadLength()); - newBufferOffset += getPayloadLength(); - - buffer = newBuffer; - this.length = newBufferOffset - offset; - } - - /** - * Removes the extension from the packet and its header. - */ - public void removeExtension() - { - if(!getExtensionBit()) - return; - - int payloadOffset = offset + getHeaderLength(); - - int extHeaderLen = getExtensionLength() + EXT_HEADER_SIZE; - - System.arraycopy(buffer, payloadOffset, - buffer, payloadOffset - extHeaderLen, getPayloadLength()); - - this.length -= extHeaderLen; - - setExtensionBit(false); - } - - /** - * Returns a map binding CSRC IDs to audio levels as reported by the remote - * party that sent this packet. - * - * @param csrcExtID the ID of the extension that's transporting csrc audio - * levels in the session that this RawPacket belongs to. - * - * @return an array representing a map binding CSRC IDs to audio levels as - * reported by the remote party that sent this packet. The entries of the - * map are contained in consecutive elements of the returned array where - * elements at even indices stand for CSRC IDs and elements at odd indices - * stand for the associated audio levels - */ - public long[] extractCsrcLevels(byte csrcExtID) - { - if (!getExtensionBit() - || (getExtensionLength() == 0) - || (getCsrcCount() == 0)) - return null; - - int csrcCount = getCsrcCount(); - /* - * XXX The guideline which is also supported by Google and recommended - * for Android is that single-dimensional arrays should be preferred to - * multi-dimensional arrays in Java because the former take less space - * than the latter and are thus more efficient in terms of memory and - * garbage collection. - */ - long[] csrcLevels = new long[csrcCount * 2]; - - //first extract the csrc IDs - int csrcStartIndex = offset + FIXED_HEADER_SIZE; - for (int i = 0; i < csrcCount; i++) - { - int csrcLevelsIndex = 2 * i; - - csrcLevels[csrcLevelsIndex] = readInt(csrcStartIndex); - csrcLevels[csrcLevelsIndex + 1] = getCsrcLevel(i, csrcExtID); - - csrcStartIndex += 4; - } - - return csrcLevels; - } - - /** - * Returns the CSRC level at the specified index or 0 if there was - * no level at that index. - * - * @param index the sequence number of the CSRC audio level extension to - * return. - * @param csrcExtID the ID of the extension that's transporting csrc audio - * levels in the session that this RawPacket belongs to. - * - * @return the CSRC audio level at the specified index of the csrc audio - * level option or 0 if there was no level at that index. - */ - private int getCsrcLevel(int index, byte csrcExtID) - { - if( !getExtensionBit() || getExtensionLength() == 0) - return 0; - - int levelsStart = findExtension(csrcExtID); - - if(levelsStart == -1) - return 0; - - int levelsCount = getLengthForExtension(levelsStart); - - if(levelsCount < index) - { - //apparently the remote side sent more CSRCs than levels. - // ... yeah remote sides do that now and then ... - return 0; - } - - return buffer[levelsStart + index]; - } - - /** - * Returns the index of the element in this packet's buffer where the - * content of the header with the specified extensionID starts. - * - * @param extensionID the ID of the extension whose content we are looking - * for. - * - * @return the index of the first byte of the content of the extension - * with the specified extensionID or -1 if no such extension was - * found. - */ - private int findExtension(int extensionID) - { - if( !getExtensionBit() || getExtensionLength() == 0) - return 0; - - int extOffset = offset + FIXED_HEADER_SIZE - + getCsrcCount()*4 + EXT_HEADER_SIZE; - - int extensionEnd = extOffset + getExtensionLength(); - int extHdrLen = getExtensionHeaderLength(); - - if (extHdrLen != 1 && extHdrLen != 2) - { - return -1; - } - - while (extOffset < extensionEnd) - { - int currType = -1; - int currLen = -1; - - if(extHdrLen == 1) - { - //short header. type is in the lefter 4 bits and length is on - //the right; like this: - // 0 - // 0 1 2 3 4 5 6 7 - // +-+-+-+-+-+-+-+-+ - // | ID | len | - // +-+-+-+-+-+-+-+-+ - - currType = buffer[extOffset] >> 4; - currLen = (buffer[extOffset] & 0x0F) + 1; //add one as per 5285 - - //now skip the header - extOffset ++; - } - else - { - //long header. type is in the first byte and length is in the - //second - // 0 1 - // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | ID | length | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - currType = buffer[extOffset]; - currLen = buffer[extOffset + 1]; - - //now skip the header - extOffset += 2; - } - - if(currType == extensionID) - { - return extOffset; - } - - extOffset += currLen; - } - - return -1; - } - - /** - * Returns the length of the header extension that is carrying the content - * starting at contentStart. In other words this method checks the - * size of extension headers in this packet and then either returns the - * value of the byte right before contentStart or its lower 4 bits. - * This is a very basic method so if you are using it - make sure u know - * what you are doing. - * - * @param contentStart the index of the first element of the content of - * the extension whose size we are trying to obtain. - * - * @return the length of the extension carrying the content starting at - * contentStart. - */ - private int getLengthForExtension(int contentStart) - { - int hdrLen = getExtensionHeaderLength(); - - if( hdrLen == 1 ) - return ( buffer[contentStart - 1] & 0x0F ) + 1; - else - return buffer[contentStart - 1]; - } - - /** - * Returns the length of the extension header being used in this packet or - * -1 in case there were no extension headers here or we didn't - * understand the kind of extension being used. - * - * @return the length of the extension header being used in this packet or - * -1 in case there were no extension headers here or we didn't - * understand the kind of extension being used. - */ - private int getExtensionHeaderLength() - { - if (!getExtensionBit()) - return -1; - - //the type of the extension header comes right after the RTP header and - //the CSRC list. - int extLenIndex = offset + FIXED_HEADER_SIZE + getCsrcCount()*4; - - //0xBEDE means short extension header. - if (buffer[extLenIndex] == (byte)0xBE - && buffer[extLenIndex + 1] == (byte)0xDE) - return 1; - - //0x100 means a two-byte extension header. - if (buffer[extLenIndex]== (byte)0x10 - && (buffer[extLenIndex + 1] >> 4)== 0) - return 2; - - return -1; - } - - /** - * Return the define by profile part of the extension header. - * @return the starting two bytes of extension header. - */ - public int getHeaderExtensionType() - { - if (!getExtensionBit()) - return 0; - - return readUnsignedShortAsInt( - offset + FIXED_HEADER_SIZE + getCsrcCount()*4); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/RecorderImpl.java b/src/net/java/sip/communicator/impl/neomedia/RecorderImpl.java deleted file mode 100644 index 14ee2eae6..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/RecorderImpl.java +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.io.*; -import java.util.*; - -import javax.media.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.MediaException; // disambiguation -import net.java.sip.communicator.util.*; - -/** - * The call recording implementation. - * Provides the capability to start and stop call recording. - * - * @author Dmitri Melnikov - * @author Lubomir Marinov - */ -public class RecorderImpl - implements Recorder -{ - - /** - * The list of formats in which RecorderImpl instances support - * recording media. - */ - static final String[] SUPPORTED_FORMATS - = new String[] - { - SoundFileUtils.aif, - SoundFileUtils.au, - SoundFileUtils.gsm, - SoundFileUtils.mp3, - SoundFileUtils.wav - }; - - /** - * The AudioMixerMediaDevice which is to be or which is already - * being recorded by this Recorder. - */ - private final AudioMixerMediaDevice device; - - /** - * The MediaDeviceSession is used to create an output data source. - */ - private MediaDeviceSession deviceSession; - - /** - * The List of Recorder.Listeners interested in - * notifications from this Recorder. - */ - private final List listeners - = new ArrayList(); - - /** - * DataSink used to save the output data. - */ - private DataSink sink; - - /** - * The indicator which determines whether this Recorder - * is set to skip media from mic. - */ - private boolean mute = false; - - /** - * The filename we will use to record data, supplied - * when Recorder is started. - */ - private String filename = null; - - /** - * Constructs the RecorderImpl with the provided session. - * - * @param device device that can create a session that provides the output - * data source - */ - public RecorderImpl(AudioMixerMediaDevice device) - { - if (device == null) - throw new NullPointerException("device"); - - this.device = device; - } - - /** - * Adds a new Recorder.Listener to the list of listeners interested - * in notifications from this Recorder. - * - * @param listener the new Recorder.Listener to be added to the - * list of listeners interested in notifications from this Recorder - * @see Recorder#addListener(Recorder.Listener) - */ - public void addListener(Recorder.Listener listener) - { - if (listener == null) - throw new NullPointerException("listener"); - - synchronized (listeners) - { - if (!listeners.contains(listener)) - listeners.add(listener); - } - } - - /** - * Returns a content descriptor to create a recording session with. - * - * @param format the format that corresponding to the content descriptor - * @return content descriptor - * @throws IllegalArgumentException if the specified format is not - * a supported recording format - */ - private ContentDescriptor getContentDescriptor(String format) - throws IllegalArgumentException - { - String type; - - if (SoundFileUtils.wav.equalsIgnoreCase(format)) - type = FileTypeDescriptor.WAVE; - else if (SoundFileUtils.mp3.equalsIgnoreCase(format)) - type = FileTypeDescriptor.MPEG_AUDIO; - else if (SoundFileUtils.gsm.equalsIgnoreCase(format)) - type = FileTypeDescriptor.GSM; - else if (SoundFileUtils.au.equalsIgnoreCase(format)) - type = FileTypeDescriptor.BASIC_AUDIO; - else if (SoundFileUtils.aif.equalsIgnoreCase(format)) - type = FileTypeDescriptor.AIFF; - else - { - throw - new IllegalArgumentException( - format + " is not a supported recording format."); - } - - return new ContentDescriptor(type); - } - - /** - * Gets a list of the formats in which this Recorder supports - * recording media. - * - * @return a List of the formats in which this Recorder - * supports recording media - * @see Recorder#getSupportedFormats() - */ - public List getSupportedFormats() - { - return Arrays.asList(SUPPORTED_FORMATS); - } - - /** - * Removes a existing Recorder.Listener from the list of listeners - * interested in notifications from this Recorder. - * - * @param listener the existing Recorder.Listener to be removed - * from the list of listeners interested in notifications from this - * Recorder - * @see Recorder#removeListener(Recorder.Listener) - */ - public void removeListener(Recorder.Listener listener) - { - if (listener != null) - { - synchronized (listeners) - { - listeners.remove(listener); - } - } - } - - /** - * Starts the recording of the media associated with this Recorder - * (e.g. the media being sent and received in a Call) into a file - * with a specific name. - * - * @param format the format into which the media associated with this - * Recorder is to be recorded into the specified file - * @param filename the name of the file into which the media associated with - * this Recorder is to be recorded - * @throws IOException if anything goes wrong with the input and/or output - * performed by this Recorder - * @throws MediaException if anything else goes wrong while starting the - * recording of media performed by this Recorder - * @see Recorder#start(String, String) - */ - public void start(String format, String filename) - throws IOException, - MediaException - { - if (this.sink == null) - { - if (format == null) - throw new NullPointerException("format"); - if (filename == null) - throw new NullPointerException("filename"); - - this.filename = filename; - - /* - * A file without an extension may not only turn out to be a touch - * more difficult to play but is suspected to also cause an - * exception inside of JMF. - */ - int extensionBeginIndex = filename.lastIndexOf('.'); - - if (extensionBeginIndex < 0) - filename += '.' + format; - else if (extensionBeginIndex == filename.length() - 1) - filename += format; - - MediaDeviceSession deviceSession = device.createSession(); - - try - { - deviceSession.setContentDescriptor(getContentDescriptor(format)); - - // set initial mute state, if mute was set before starting - // the recorder - deviceSession.setMute(mute); - - /* - * This RecorderImpl will use deviceSession to get a hold of the - * media being set to the remote peers associated with the same - * AudioMixerMediaDevice i.e. this RecorderImpl needs - * deviceSession to only capture and not play back. - */ - deviceSession.start(MediaDirection.SENDONLY); - - this.deviceSession = deviceSession; - } - finally - { - if (this.deviceSession == null) - { - throw new MediaException( - "Failed to create MediaDeviceSession from" - + " AudioMixerMediaDevice for the purposes of" - + " recording"); - } - } - - Throwable exception = null; - - try - { - DataSource outputDataSource - = deviceSession.getOutputDataSource(); - DataSink sink - = Manager.createDataSink( - outputDataSource, - new MediaLocator("file:" + filename)); - - sink.open(); - sink.start(); - - this.sink = sink; - } - catch (NoDataSinkException ndsex) - { - exception = ndsex; - } - finally - { - if ((this.sink == null) || (exception != null)) - { - stop(); - - throw new MediaException( - "Failed to start recording into file " + filename, - exception); - } - } - } - } - - /** - * Stops the recording of the media associated with this Recorder - * (e.g. the media being sent and received in a Call) if it has - * been started and prepares this Recorder for garbage collection. - * - * @see Recorder#stop() - */ - public void stop() - { - if (deviceSession != null) - { - deviceSession.close(); - deviceSession = null; - } - - if (sink != null) - { - sink.close(); - sink = null; - - /* - * RecorderImpl creates the sink upon start() and it does it only if - * it is null so this RecorderImpl has really stopped only if it has - * managed to close() the (existing) sink. Notify the registered - * listeners. - */ - Recorder.Listener[] listeners; - - synchronized (this.listeners) - { - listeners - = this.listeners.toArray( - new Recorder.Listener[this.listeners.size()]); - } - for (Recorder.Listener listener : listeners) - listener.recorderStopped(this); - } - } - - /** - * Put the recorder in mute state. It won't record the local input. - * This is used when the local call is muted and we don't won't to record - * the local input. - * @param mute the new value of the mute property - */ - public void setMute(boolean mute) - { - this.mute = mute; - - if(deviceSession != null) - { - deviceSession.setMute(mute); - } - } - - /** - * Returns the filename we are last started or stopped recording to, - * null if not started. - * @return the filename we are last started or stopped recording to, - * null if not started. - */ - public String getFilename() - { - return filename; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/SecurityConfigForm.java b/src/net/java/sip/communicator/impl/neomedia/SecurityConfigForm.java index eea71677a..5bd8146ac 100644 --- a/src/net/java/sip/communicator/impl/neomedia/SecurityConfigForm.java +++ b/src/net/java/sip/communicator/impl/neomedia/SecurityConfigForm.java @@ -10,9 +10,10 @@ import javax.swing.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; + /** * The SecurityConfigForm allows the user to make all needed call * security configurations. It now wraps the ZRTP form in order to provide some @@ -86,4 +87,4 @@ protected void close(boolean escaped) {} mainPanel.add(buttonPanel, BorderLayout.SOUTH); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/neomedia/StreamRTPManager.java b/src/net/java/sip/communicator/impl/neomedia/StreamRTPManager.java deleted file mode 100644 index 812de9802..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/StreamRTPManager.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.io.*; -import java.util.*; - -import javax.media.*; -import javax.media.format.*; -import javax.media.protocol.*; -import javax.media.rtp.*; - -import com.sun.media.rtp.*; - -import net.java.sip.communicator.service.neomedia.*; - -/** - * Implements the RTPManager interface as used by a - * MediaStream. - * - * @author Lyubomir Marinov - */ -public class StreamRTPManager -{ - /** - * The RTPManager this instance is to delegate to when it is not - * attached to an RTPTranslator. - */ - private final RTPManager manager; - - /** - * The RTPTranslator which this instance is attached to and which - * forwards the RTP and RTCP flows of the MediaStream associated - * with this instance to other MediaStreams. - */ - private final RTPTranslatorImpl translator; - - /** - * Initializes a new StreamRTPManager instance which is, - * optionally, attached to a specific RTPTranslator which is to - * forward the RTP and RTCP flows of the associated MediaStream to - * other MediaStreams. - * - * @param translator the RTPTranslator to attach the new instance - * to or null if the new instance is to not be attached to any - * RTPTranslator - */ - public StreamRTPManager(RTPTranslator translator) - { - this.translator = (RTPTranslatorImpl) translator; - - manager = (this.translator == null) ? RTPManager.newInstance() : null; - } - - public void addFormat(Format format, int payloadType) - { - if (translator == null) - manager.addFormat(format, payloadType); - else - translator.addFormat(this, format, payloadType); - } - - public void addReceiveStreamListener(ReceiveStreamListener listener) - { - if (translator == null) - manager.addReceiveStreamListener(listener); - else - translator.addReceiveStreamListener(this, listener); - } - - public void addRemoteListener(RemoteListener listener) - { - if (translator == null) - manager.addRemoteListener(listener); - else - translator.addRemoteListener(this, listener); - } - - public void addSendStreamListener(SendStreamListener listener) - { - if (translator == null) - manager.addSendStreamListener(listener); - else - translator.addSendStreamListener(this, listener); - } - - public void addSessionListener(SessionListener listener) - { - if (translator == null) - manager.addSessionListener(listener); - else - translator.addSessionListener(this, listener); - } - - public SendStream createSendStream(DataSource dataSource, int streamIndex) - throws IOException, - UnsupportedFormatException - { - if (translator == null) - return manager.createSendStream(dataSource, streamIndex); - else - return translator.createSendStream(this, dataSource, streamIndex); - } - - public void dispose() - { - if (translator == null) - manager.dispose(); - else - translator.dispose(this); - } - - public Object getControl(String controlType) - { - if (translator == null) - return manager.getControl(controlType); - else - return translator.getControl(this, controlType); - } - - public GlobalReceptionStats getGlobalReceptionStats() - { - if (translator == null) - return manager.getGlobalReceptionStats(); - else - return translator.getGlobalReceptionStats(this); - } - - public GlobalTransmissionStats getGlobalTransmissionStats() - { - if (translator == null) - return manager.getGlobalTransmissionStats(); - else - return translator.getGlobalTransmissionStats(this); - } - - public long getLocalSSRC() - { - if (translator == null) - return ((RTPSessionMgr) manager).getLocalSSRC(); - else - return translator.getLocalSSRC(this); - } - - @SuppressWarnings("rawtypes") - public Vector getReceiveStreams() - { - if (translator == null) - return manager.getReceiveStreams(); - else - return translator.getReceiveStreams(this); - } - - @SuppressWarnings("rawtypes") - public Vector getSendStreams() - { - if (translator == null) - return manager.getSendStreams(); - else - return translator.getSendStreams(this); - } - - public void initialize(RTPConnector connector) - { - if (translator == null) - manager.initialize(connector); - else - translator.initialize(this, connector); - } - - public void removeReceiveStreamListener(ReceiveStreamListener listener) - { - if (translator == null) - manager.removeReceiveStreamListener(listener); - else - translator.removeReceiveStreamListener(this, listener); - } - - public void removeRemoteListener(RemoteListener listener) - { - if (translator == null) - manager.removeRemoteListener(listener); - else - translator.removeRemoteListener(this, listener); - } - - public void removeSendStreamListener(SendStreamListener listener) - { - if (translator == null) - manager.removeSendStreamListener(listener); - else - translator.removeSendStreamListener(this, listener); - } - - public void removeSessionListener(SessionListener listener) - { - if (translator == null) - manager.removeSessionListener(listener); - else - translator.removeSessionListener(this, listener); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/VideoMediaStreamImpl.java b/src/net/java/sip/communicator/impl/neomedia/VideoMediaStreamImpl.java deleted file mode 100644 index 193ee8404..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/VideoMediaStreamImpl.java +++ /dev/null @@ -1,1251 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.awt.*; -import java.util.*; -import java.util.List; -import java.util.regex.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.impl.neomedia.protocol.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.QualityControl; // disambiguation -import net.java.sip.communicator.service.neomedia.control.*; -import net.java.sip.communicator.service.neomedia.control.KeyFrameControl; // disambiguation -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.format.*; -import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.util.*; -import net.java.sip.communicator.util.event.*; - -/** - * Extends MediaStreamImpl in order to provide an implementation of - * VideoMediaStream. - * - * @author Lyubomir Marinov - * @author Sebastien Vincent - */ -public class VideoMediaStreamImpl - extends MediaStreamImpl - implements VideoMediaStream -{ - - /** - * The Logger used by the VideoMediaStreamImpl class and - * its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(VideoMediaStreamImpl.class); - - /** - * Negotiated output size of the video stream. - * It may need to scale original capture device stream. - */ - private Dimension outputSize; - - /** - * The indicator which determines whether RTCP feedback Picture Loss - * Indication messages are to be used. - */ - private boolean usePLI = true; - - /** - * The KeyFrameControl of this VideoMediaStream. - */ - private KeyFrameControl keyFrameControl; - - /** - * The QualityControl of this VideoMediaStream. - */ - private final QualityControlImpl qualityControl = new QualityControlImpl(); - - /** - * Selects the VideoFormat from the list of supported formats of a - * specific video DataSource which has a size as close as possible - * to a specific size and sets it as the format of the specified video - * DataSource. - * - * @param videoDS the video DataSource which is to have its - * supported formats examined and its format changed to the - * VideoFormat which is as close as possible to the specified - * preferredWidth and preferredHeight - * @param preferredWidth the width of the VideoFormat to be - * selected - * @param preferredHeight the height of the VideoFormat to be - * selected - * @return the size of the VideoFormat from the list of supported - * formats of videoDS which is as close as possible to - * preferredWidth and preferredHeight and which has been - * set as the format of videoDS - */ - public static Dimension selectVideoSize( - DataSource videoDS, - final int preferredWidth, final int preferredHeight) - { - if (videoDS == null) - return null; - - FormatControl formatControl - = (FormatControl) videoDS.getControl(FormatControl.class.getName()); - - if (formatControl == null) - return null; - - Format[] formats = formatControl.getSupportedFormats(); - final int count = formats.length; - - if (count < 1) - return null; - - VideoFormat selectedFormat = null; - - if (count == 1) - selectedFormat = (VideoFormat) formats[0]; - else - { - class FormatInfo - { - public final VideoFormat format; - - public final double difference; - - public final Dimension dimension; - - public FormatInfo(VideoFormat format) - { - this.format = format; - - this.dimension = format.getSize(); - - this.difference = getDifference(this.dimension); - } - - public FormatInfo(Dimension size) - { - this.format = null; - - this.dimension = size; - - this.difference = getDifference(this.dimension); - } - - private double getDifference(Dimension size) - { - int width = (size == null) ? 0 : size.width; - double xScale; - - if (width == 0) - xScale = Double.POSITIVE_INFINITY; - else if (width == preferredWidth) - xScale = 1; - else - xScale = (preferredWidth / (double) width); - - int height = (size == null) ? 0 : size.height; - double yScale; - - if (height == 0) - yScale = Double.POSITIVE_INFINITY; - else if (height == preferredHeight) - yScale = 1; - else - yScale = (preferredHeight / (double) height); - - return Math.abs(1 - Math.min(xScale, yScale)); - } - } - - FormatInfo[] infos = new FormatInfo[count]; - - for (int i = 0; i < count; i++) - { - FormatInfo info - = infos[i] - = new FormatInfo((VideoFormat) formats[i]); - - if (info.difference == 0) - { - selectedFormat = info.format; - break; - } - } - if (selectedFormat == null) - { - Arrays.sort(infos, new Comparator() - { - public int compare(FormatInfo info0, FormatInfo info1) - { - return - Double.compare(info0.difference, info1.difference); - } - }); - selectedFormat = infos[0].format; - } - - /* - * If videoDS states to support any size, use the sizes that we - * support which is closest(or smaller) to the preferred one. - */ - if ((selectedFormat != null) - && (selectedFormat.getSize() == null)) - { - VideoFormat currentFormat - = (VideoFormat) formatControl.getFormat(); - Dimension currentSize = null; - int width = preferredWidth; - int height = preferredHeight; - - // Try to preserve the aspect ratio - if (currentFormat != null) - currentSize = currentFormat.getSize(); - - // sort supported resolutions by aspect - FormatInfo[] supportedInfos - = new FormatInfo[ - DeviceConfiguration.SUPPORTED_RESOLUTIONS.length]; - for (int i = 0; i < supportedInfos.length; i++) - { - supportedInfos[i] - = new FormatInfo( - DeviceConfiguration.SUPPORTED_RESOLUTIONS[i]); - } - Arrays.sort(infos, new Comparator() - { - public int compare(FormatInfo info0, FormatInfo info1) - { - return - Double.compare(info0.difference, info1.difference); - } - }); - - FormatInfo preferredFormat = - new FormatInfo(new Dimension(preferredWidth, preferredHeight)); - - Dimension closestAspect = null; - // lets choose the closest size to the preferred one, - // finding the first sutable aspect - for(FormatInfo supported : supportedInfos) - { - // find the first matching aspect - if(preferredFormat.difference > supported.difference) - continue; - else if(closestAspect == null) - closestAspect = supported.dimension; - - if(supported.dimension.height <= preferredHeight - && supported.dimension.width <= preferredWidth) - { - currentSize = supported.dimension; - } - } - - if(currentSize == null) - currentSize = closestAspect; - - if ((currentSize.width > 0) && (currentSize.height > 0)) - { - width = currentSize.width; - height = currentSize.height; - } - selectedFormat - = (VideoFormat)new VideoFormat( - null, - new Dimension(width, height), - Format.NOT_SPECIFIED, - null, - Format.NOT_SPECIFIED) - .intersects(selectedFormat); - } - } - - Format setFormat = formatControl.setFormat(selectedFormat); - - return - (setFormat instanceof VideoFormat) - ? ((VideoFormat) setFormat).getSize() - : null; - } - - /** - * The VideoListener which handles VideoEvents from the - * MediaDeviceSession of this instance and fires respective - * VideoEvents from this VideoMediaStream to its - * VideoListeners. - */ - private VideoListener deviceSessionVideoListener; - - /** - * The facility which aids this instance in managing a list of - * VideoListeners and firing VideoEvents to them. - *

- * Since the videoNotifierSupport of this - * VideoMediaStreamImpl just forwards the VideoEvents of - * the associated VideoMediaDeviceSession at the time of this - * writing, it does not make sense to have videoNotifierSupport - * executing asynchronously because it does not know whether it has to wait - * for the delivery of the VideoEvents and thus it has to default - * to waiting anyway. - *

- */ - private final VideoNotifierSupport videoNotifierSupport - = new VideoNotifierSupport(this, true); - - /** - * Initializes a new VideoMediaStreamImpl instance which will use - * the specified MediaDevice for both capture and playback of video - * exchanged via the specified StreamConnector. - * - * @param connector the StreamConnector the new instance is to use - * for sending and receiving video - * @param device the MediaDevice the new instance is to use for - * both capture and playback of video exchanged via the specified - * StreamConnector - * @param srtpControl a control which is already created, used to control - * the srtp operations. - */ - public VideoMediaStreamImpl(StreamConnector connector, MediaDevice device, - SrtpControl srtpControl) - { - super(connector, device, srtpControl); - - if(logger.isTraceEnabled()) - logger.trace("Created Video Stream with hashCode " + hashCode()); - } - - /** - * Adds a specific VideoListener to this VideoMediaStream - * in order to receive notifications when visual/video Components - * are being added and removed. - *

- * Adding a listener which has already been added does nothing i.e. it is - * not added more than once and thus does not receive one and the same - * VideoEvent multiple times. - *

- * - * @param listener the VideoListener to be notified when - * visual/video Components are being added or removed in this - * VideoMediaStream - */ - public void addVideoListener(VideoListener listener) - { - videoNotifierSupport.addVideoListener(listener); - } - - /** - * Performs any optional configuration on a specific - * RTPConnectorOuputStream of an RTPManager to be used by - * this MediaStreamImpl. - * - * @param dataOutputStream the RTPConnectorOutputStream to be used - * by an RTPManager of this MediaStreamImpl and to be - * configured - */ - @Override - protected void configureDataOutputStream( - RTPConnectorOutputStream dataOutputStream) - { - super.configureDataOutputStream(dataOutputStream); - - /* - * XXX Android's current video CaptureDevice is based on MediaRecorder - * which gives no control over the number and the size of the packets, - * frame dropping is not implemented because it is hard since - * MediaRecorder generates encoded video. - */ - if (!OSUtils.IS_ANDROID) - { - int maxBandwidth - = NeomediaActivator - .getMediaServiceImpl() - .getDeviceConfiguration() - .getVideoMaxBandwidth(); - - // maximum one packet for X milliseconds(the settings are for one - // second) - dataOutputStream.setMaxPacketsPerMillis(1, 1000 / maxBandwidth); - } - } - - /** - * Performs any optional configuration on the BufferControl of the - * specified RTPManager which is to be used as the - * RTPManager of this MediaStreamImpl. - * - * @param rtpManager the RTPManager which is to be used by this - * MediaStreamImpl - * @param bufferControl the BufferControl of rtpManager on - * which any optional configuration is to be performed - */ - @Override - protected void configureRTPManagerBufferControl( - StreamRTPManager rtpManager, - BufferControl bufferControl) - { - super.configureRTPManagerBufferControl(rtpManager, bufferControl); - - bufferControl.setBufferLength(BufferControl.MAX_VALUE); - } - - /** - * Creates the visual Component depicting the video being streamed - * from the local peer to the remote peer. - * - * @param flipLocalVideoDisplay Tells to flip the local video display (true, - * in case of diplaying the webcam as a mirror), or not (false, for desktop - * streaming). - * - * @return the visual Component depicting the video being streamed - * from the local peer to the remote peer if it was immediately created or - * null if it was not immediately created and it is to be delivered - * to the currently registered VideoListeners in a - * VideoEvent with type {@link VideoEvent#VIDEO_ADDED} and origin - * {@link VideoEvent#LOCAL} - */ - public Component createLocalVisualComponent(boolean flipLocalVideoDisplay) - { - MediaDeviceSession deviceSession = getDeviceSession(); - - return - (deviceSession instanceof VideoMediaDeviceSession) - ? ((VideoMediaDeviceSession) deviceSession) - .createLocalVisualComponent(flipLocalVideoDisplay) - : null; - } - - /** - * Notifies this MediaStream that the MediaDevice (and - * respectively the MediaDeviceSession with it) which this instance - * uses for capture and playback of media has been changed. Makes sure that - * the VideoListeners of this instance get VideoEvents for - * the new/current VideoMediaDeviceSession and not for the old one. - * - * @param oldValue the MediaDeviceSession with the - * MediaDevice this instance used work with - * @param newValue the MediaDeviceSession with the - * MediaDevice this instance is to work with - * @see MediaStreamImpl#deviceSessionChanged(MediaDeviceSession, - * MediaDeviceSession) - */ - @Override - protected void deviceSessionChanged( - MediaDeviceSession oldValue, - MediaDeviceSession newValue) - { - super.deviceSessionChanged(oldValue, newValue); - - if (oldValue instanceof VideoMediaDeviceSession) - { - VideoMediaDeviceSession oldVideoMediaDeviceSession - = (VideoMediaDeviceSession) oldValue; - - if (deviceSessionVideoListener != null) - oldVideoMediaDeviceSession.removeVideoListener( - deviceSessionVideoListener); - - /* - * The oldVideoMediaDeviceSession is being disconnected from this - * VideoMediaStreamImpl so do not let it continue using its - * keyFrameControl. - */ - oldVideoMediaDeviceSession.setKeyFrameControl(null); - } - if (newValue instanceof VideoMediaDeviceSession) - { - VideoMediaDeviceSession newVideoMediaDeviceSession - = (VideoMediaDeviceSession) newValue; - - if (deviceSessionVideoListener == null) - { - deviceSessionVideoListener = new VideoListener() - { - - /** - * Notifies that a visual Component representing - * video has been added to the provider this listener has - * been added to. - * - * @param e a VideoEvent describing the added - * visual Component representing video and the - * provider it was added into - * @see VideoListener#videoAdded(VideoEvent) - */ - public void videoAdded(VideoEvent e) - { - if (fireVideoEvent( - e.getType(), - e.getVisualComponent(), - e.getOrigin(), - true)) - e.consume(); - } - - /** - * Notifies that a visual Component representing - * video has been removed from the provider this listener - * has been added to. - * - * @param e a VideoEvent describing the removed - * visual Component representing video and the - * provider it was removed from - * @see VideoListener#videoRemoved(VideoEvent) - */ - public void videoRemoved(VideoEvent e) - { - videoAdded(e); - } - - public void videoUpdate(VideoEvent e) - { - fireVideoEvent(e, true); - } - }; - } - newVideoMediaDeviceSession.addVideoListener( - deviceSessionVideoListener); - - newVideoMediaDeviceSession.setOutputSize(outputSize); - - AbstractRTPConnector rtpConnector = getRTPConnector(); - - if (rtpConnector != null) - newVideoMediaDeviceSession.setConnector(rtpConnector); - newVideoMediaDeviceSession.setRtcpFeedbackPLI(usePLI); - - /* - * The newVideoMediaDeviceSession is being connected to this - * VideoMediaStreamImpl so the key frame-related logic will be - * controlled by the keyFrameControl of this VideoMediaStreamImpl. - */ - newVideoMediaDeviceSession.setKeyFrameControl(getKeyFrameControl()); - } - } - - /** - * Disposes of the visual Component of the local peer. - * - * @param component the visual Component of the local peer to - * dispose of - */ - public void disposeLocalVisualComponent(Component component) - { - MediaDeviceSession deviceSession = getDeviceSession(); - - if(deviceSession instanceof VideoMediaDeviceSession) - ((VideoMediaDeviceSession) deviceSession) - .disposeLocalVisualComponent(component); - } - - /** - * Notifies the VideoListeners registered with this - * VideoMediaStream about a specific type of change in the - * availability of a specific visual Component depicting video. - * - * @param type the type of change as defined by VideoEvent in the - * availability of the specified visual Component depicting video - * @param visualComponent the visual Component depicting video - * which has been added or removed in this VideoMediaStream - * @param origin {@link VideoEvent#LOCAL} if the origin of the video is - * local (e.g. it is being locally captured); {@link VideoEvent#REMOTE} if - * the origin of the video is remote (e.g. a remote peer is streaming it) - * @param wait true if the call is to wait till the specified - * VideoEvent has been delivered to the VideoListeners; - * otherwise, false - * @return true if this event and, more specifically, the visual - * Component it describes have been consumed and should be - * considered owned, referenced (which is important because - * Components belong to a single Container at a time); - * otherwise, false - */ - protected boolean fireVideoEvent( - int type, Component visualComponent, int origin, - boolean wait) - { - if (logger.isTraceEnabled()) - logger - .trace( - "Firing VideoEvent with type " - + VideoEvent.typeToString(type) - + " and origin " - + VideoEvent.originToString(origin)); - - return - videoNotifierSupport.fireVideoEvent( - type, visualComponent, origin, - wait); - } - - /** - * Notifies the VideoListeners registered with this instance about - * a specific VideoEvent. - * - * @param event the VideoEvent to be fired to the - * VideoListeners registered with this instance - * @param wait true if the call is to wait till the specified - * VideoEvent has been delivered to the VideoListeners; - * otherwise, false - */ - protected void fireVideoEvent(VideoEvent event, boolean wait) - { - videoNotifierSupport.fireVideoEvent(event, wait); - } - - /** - * Gets the visual Component where video from the remote peer is - * being rendered or null if no video is currently being rendered. - * - * @return the visual Component where video from the remote peer is - * being rendered or null if no video is currently being rendered - * @see VideoMediaStream#getVisualComponent() - */ - @Deprecated - public Component getVisualComponent() - { - List visualComponents = getVisualComponents(); - - return visualComponents.isEmpty() ? null : visualComponents.get(0); - } - - /** - * Gets a list of the visual Components where video from the remote - * peer is being rendered. - * - * @return a list of the visual Components where video from the - * remote peer is being rendered - * @see VideoMediaStream#getVisualComponents() - */ - public List getVisualComponents() - { - MediaDeviceSession deviceSession = getDeviceSession(); - List visualComponents; - - if (deviceSession instanceof VideoMediaDeviceSession) - { - visualComponents - = ((VideoMediaDeviceSession) deviceSession) - .getVisualComponents(); - } - else - visualComponents = Collections.emptyList(); - return visualComponents; - } - - /** - * Gets the visual Components rendering the ReceiveStream - * corresponding to the given ssrc. - * - * @param ssrc the src-id of the receive stream, which visual - * Component we're looking for - * @return the visual Component rendering the - * ReceiveStream corresponding to the given ssrc - */ - public Component getVisualComponent(long ssrc) - { - MediaDeviceSession deviceSession = getDeviceSession(); - - if (deviceSession instanceof VideoMediaDeviceSession) - { - return ((VideoMediaDeviceSession) deviceSession) - .getVisualComponent(ssrc); - } - - return null; - } - - /** - * Removes a specific VideoListener from this - * VideoMediaStream in order to have to no longer receive - * notifications when visual/video Components are being added and - * removed. - * - * @param listener the VideoListener to no longer be notified when - * visual/video Components are being added or removed in this - * VideoMediaStream - */ - public void removeVideoListener(VideoListener listener) - { - videoNotifierSupport.removeVideoListener(listener); - } - - /** - * Notifies this MediaStream implementation that its - * RTPConnector instance has changed from a specific old value to a - * specific new value. Allows extenders to override and perform additional - * processing after this MediaStream has changed its - * RTPConnector instance. - * - * @param oldValue the RTPConnector of this MediaStream - * implementation before it got changed to newValue - * @param newValue the current RTPConnector of this - * MediaStream which replaced oldValue - * @see MediaStreamImpl#rtpConnectorChanged(AbstractRTPConnector, - * AbstractRTPConnector) - */ - @Override - protected void rtpConnectorChanged( - AbstractRTPConnector oldValue, - AbstractRTPConnector newValue) - { - super.rtpConnectorChanged(oldValue, newValue); - - if (newValue != null) - { - MediaDeviceSession deviceSession = getDeviceSession(); - - if (deviceSession instanceof VideoMediaDeviceSession) - { - ((VideoMediaDeviceSession) deviceSession) - .setConnector(newValue); - } - } - } - - /** - * Handles attributes contained in MediaFormat. - * - * @param format the MediaFormat to handle the attributes of - * @param attrs the attributes Map to handle - */ - @Override - protected void handleAttributes( - MediaFormat format, - Map attrs) - { - /* walk through attributes and see if we recognized something - * we support - */ - if(attrs != null) - { - String width = null; - String height = null; - - for(Map.Entry mapEntry : attrs.entrySet()) - { - String key = mapEntry.getKey(); - String value = mapEntry.getValue(); - - if(key.equals("rtcp-fb")) - { - if (value.equals("nack pli")) - usePLI = true; - } - else if(key.equals("imageattr")) - { - Dimension res[] = parseSendRecvResolution(value); - - if(res != null) - { - // if we have width or height attributes - // don't override any previous output size - if((attrs.containsKey("width") - || attrs.containsKey("height")) - && outputSize != null) - continue; - - outputSize = res[1]; - - qualityControl.setRemoteSendMaxPreset( - new QualityPreset(res[0])); - qualityControl.setRemoteReceiveResolution(outputSize); - ((VideoMediaDeviceSession)getDeviceSession()). - setOutputSize(outputSize); - } - } - else if(key.equals("CIF")) - { - Dimension dim = new Dimension(352, 288); - - if(outputSize == null || (outputSize.width < dim.width && - outputSize.height < dim.height)) - { - outputSize = dim; - ((VideoMediaDeviceSession)getDeviceSession()). - setOutputSize(outputSize); - } - } - else if(key.equals("QCIF")) - { - Dimension dim = new Dimension(176, 144); - - if(outputSize == null || (outputSize.width < dim.width && - outputSize.height < dim.height)) - { - outputSize = dim; - ((VideoMediaDeviceSession)getDeviceSession()). - setOutputSize(outputSize); - } - } - else if(key.equals("VGA")) // X-lite send it - { - Dimension dim = new Dimension(640, 480); - - if(outputSize == null || (outputSize.width < dim.width && - outputSize.height < dim.height)) - { - /* X-lite does not display anything if we send 640x480 - * video - */ - outputSize = dim; - ((VideoMediaDeviceSession)getDeviceSession()). - setOutputSize(outputSize); - } - } - else if(key.equals("CUSTOM")) - { - String args[] = value.split(","); - - if(args.length < 3) - continue; - - try - { - Dimension dim = new Dimension(Integer.parseInt(args[0]), - Integer.parseInt(args[1])); - - if(outputSize == null || (outputSize.width < dim.width - && outputSize.height < dim.height)) - { - outputSize = dim; - ((VideoMediaDeviceSession)getDeviceSession()). - setOutputSize(outputSize); - } - } - catch(Exception e) - { - } - } - else if (key.equals("width")) - { - width = value; - - if(height != null) - { - outputSize = new Dimension( - Integer.parseInt(width), - Integer.parseInt(height)); - - ((VideoMediaDeviceSession)getDeviceSession()). - setOutputSize(outputSize); - } - } - else if (key.equals("height")) - { - height = value; - - if(width != null) - { - outputSize = new Dimension( - Integer.parseInt(width), - Integer.parseInt(height)); - ((VideoMediaDeviceSession)getDeviceSession()). - setOutputSize(outputSize); - } - } - } - } - } - - /** - * Extracts and returns maximum resolution can receive from the image - * attribute. - * - * @param imgattr send/recv resolution string - * @return maximum resolution array (first element is send, second one is - * recv). Elements could be null if image attribute is not present or if - * resolution is a wildcard. - */ - public static java.awt.Dimension[] parseSendRecvResolution(String imgattr) - { - java.awt.Dimension res[] = new java.awt.Dimension[2]; - String token = null; - Pattern pSendSingle = Pattern.compile("send \\[x=[0-9]+,y=[0-9]+\\]"); - Pattern pRecvSingle = Pattern.compile("recv \\[x=[0-9]+,y=[0-9]+\\]"); - Pattern pSendRange = Pattern.compile( - "send \\[x=\\[[0-9]+-[0-9]+\\],y=\\[[0-9]+-[0-9]+\\]\\]"); - Pattern pRecvRange = Pattern.compile( - "recv \\[x=\\[[0-9]+-[0-9]+\\],y=\\[[0-9]+-[0-9]+\\]\\]"); - Pattern pNumeric = Pattern.compile("[0-9]+"); - Matcher mSingle = null; - Matcher mRange = null; - Matcher m = null; - - /* resolution (width and height) can be on four forms - * - * - single value [x=1920,y=1200] - * - range of values [x=[800-1024],y=[600-768]] - * - fixed range of values [x=[800,1024],y=[600,768]] - * - range of values with step [x=[800:32:1024],y=[600:32:768]] - * - * For the moment we only support the first two forms. - */ - - /* send part */ - mSingle = pSendSingle.matcher(imgattr); - mRange = pSendRange.matcher(imgattr); - - if(mSingle.find()) - { - int val[] = new int[2]; - int i = 0; - token = imgattr.substring(mSingle.start(), mSingle.end()); - m = pNumeric.matcher(token); - - while(m.find() && i < 2) - { - val[i] = Integer.parseInt(token.substring(m.start(), m.end())); - } - - res[0] = new java.awt.Dimension(val[0], val[1]); - } - else if(mRange.find()) /* try with range */ - { - /* have two value for width and two for height (min-max) */ - int val[] = new int[4]; - int i = 0; - token = imgattr.substring(mRange.start(), mRange.end()); - m = pNumeric.matcher(token); - - while(m.find() && i < 4) - { - val[i] = Integer.parseInt(token.substring(m.start(), m.end())); - i++; - } - - res[0] = new java.awt.Dimension(val[1], val[3]); - } - - /* recv part */ - mSingle = pRecvSingle.matcher(imgattr); - mRange = pRecvRange.matcher(imgattr); - - if(mSingle.find()) - { - int val[] = new int[2]; - int i = 0; - token = imgattr.substring(mSingle.start(), mSingle.end()); - m = pNumeric.matcher(token); - - while(m.find() && i < 2) - { - val[i] = Integer.parseInt(token.substring(m.start(), m.end())); - } - - res[1] = new java.awt.Dimension(val[0], val[1]); - } - else if(mRange.find()) /* try with range */ - { - /* have two value for width and two for height (min-max) */ - int val[] = new int[4]; - int i = 0; - token = imgattr.substring(mRange.start(), mRange.end()); - m = pNumeric.matcher(token); - - while(m.find() && i < 4) - { - val[i] = Integer.parseInt(token.substring(m.start(), m.end())); - i++; - } - - res[1] = new java.awt.Dimension(val[1], val[3]); - } - - token = null; - mSingle = null; - mRange = null; - m = null; - pRecvRange = null; - pSendSingle = null; - pRecvSingle = null; - pSendRange = null; - - return res; - } - - /** - * Set local SSRC. - * - * @param localSourceID source ID - */ - @Override - protected void setLocalSourceID(long localSourceID) - { - super.setLocalSourceID(localSourceID); - - ((VideoMediaDeviceSession) getDeviceSession()).setLocalSSRC( - localSourceID); - } - - /** - * Set remote SSRC. - * - * @param ssrc remote SSRC - */ - @Override - protected void addRemoteSourceID(long ssrc) - { - super.addRemoteSourceID(ssrc); - - ((VideoMediaDeviceSession) getDeviceSession()).setRemoteSSRC(ssrc); - } - - /** - * The priority of the video is 5, which is meant to be higher than - * other threads and lower than the audio one. - * @return video priority. - */ - @Override - protected int getPriority() - { - return 5; - } - - /** - * Implements {@link VideoMediaStream#getKeyFrameControl()}. - * - * {@inheritDoc} - * @see VideoMediaStream#getKeyFrameControl() - */ - public KeyFrameControl getKeyFrameControl() - { - if (keyFrameControl == null) - keyFrameControl = new KeyFrameControlAdapter(); - return keyFrameControl; - } - - /** - * Gets the QualityControl of this VideoMediaStream. - * - * @return the QualityControl of this VideoMediaStream - */ - public QualityControl getQualityControl() - { - return qualityControl; - } - - /** - * Updates the QualityControl of this VideoMediaStream. - * - * @param advancedParams parameters of advanced attributes that may affect - * quality control - */ - public void updateQualityControl( - Map advancedParams) - { - for(Map.Entry entry : advancedParams.entrySet()) - { - if(entry.getKey().equals("imageattr")) - { - Dimension res[] = parseSendRecvResolution(entry.getValue()); - - if(res != null) - { - qualityControl.setRemoteSendMaxPreset( - new QualityPreset(res[0])); - qualityControl.setRemoteReceiveResolution( - res[1]); - outputSize = res[1]; - ((VideoMediaDeviceSession)getDeviceSession()). - setOutputSize(outputSize); - } - } - } - } - - /** - * Move origin of a partial desktop streaming MediaDevice. - * - * @param x new x coordinate origin - * @param y new y coordinate origin - */ - public void movePartialDesktopStreaming(int x, int y) - { - MediaDeviceImpl dev = (MediaDeviceImpl)getDevice(); - - if(!dev.getCaptureDeviceInfo().getLocator().getProtocol().equals( - DeviceSystem.LOCATOR_PROTOCOL_IMGSTREAMING)) - return; - - /* To move origin of the desktop capture, we need to access the - * JMF DataSource of imgstreaming - */ - VideoMediaDeviceSession session = - (VideoMediaDeviceSession)getDeviceSession(); - - DataSource ds = session.getCaptureDevice(); - if(ds instanceof RewritablePullBufferDataSource) - { - RewritablePullBufferDataSource ds2 = - (RewritablePullBufferDataSource)ds; - ds = ds2.getWrappedDataSource(); - } - - // Makes the screen detection with a point inside a real screen: - // (x and y > 0). - int tmpX = (x < 0)? 0: x; - int tmpY = (y < 0)? 0: y; - ScreenDevice screen = - NeomediaActivator.getMediaServiceImpl().getScreenForPoint( - new Point(tmpX, tmpY)); - ScreenDevice currentScreen = screen; - - if(screen == null) - return; - - Rectangle bounds = ((ScreenDeviceImpl)screen).getBounds(); - - x -= bounds.x; - y -= bounds.y; - /*((net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.imgstreaming.DataSource) - ds)*/ - Object imgStreamingDataSource = ds.getControl( - net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.imgstreaming.DataSource.class.getName()); - if(imgStreamingDataSource != null) - { - ((net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.imgstreaming.DataSource) - imgStreamingDataSource) - .setOrigin(0, currentScreen.getIndex(), x, y); - } - } - - /** - * Implements the QualityControl of this VideoMediaStream. - * - * @author Damian Minkov - */ - private class QualityControlImpl - implements QualityControl - { - /** - * The current used preset. - */ - private QualityPreset preset; - - /** - * The minimum values for resolution, framerate ... - */ - private QualityPreset minPreset; - - /** - * The maximum values for resolution, framerate ... - */ - private QualityPreset maxPreset; - - /** - * This is the local settings from the config panel. - */ - private QualityPreset localSettingsPreset; - - /** - * Sets the preset. - * @param preset the desired video settings - * @throws OperationFailedException - */ - private void setRemoteReceivePreset(QualityPreset preset) - throws OperationFailedException - { - if(preset.compareTo(getPreferredSendPreset()) > 0) - this.preset = getPreferredSendPreset(); - else - { - this.preset = preset; - - if(logger.isInfoEnabled() - && preset != null && preset.getResolution() != null) - { - logger.info("video send resolution: " - + preset.getResolution().width + "x" - + preset.getResolution().height); - } - } - } - - /** - * The current preset. - * @return the current preset - */ - public QualityPreset getRemoteReceivePreset() - { - return preset; - } - - /** - * The minimum resolution values for remote part. - * @return minimum resolution values for remote part. - */ - public QualityPreset getRemoteSendMinPreset() - { - return minPreset; - } - - /** - * The max resolution values for remote part. - * @return max resolution values for remote part. - */ - public QualityPreset getRemoteSendMaxPreset() - { - return maxPreset; - } - - /** - * Does nothing specific locally. - * - * @param preset the max preset - * @throws OperationFailedException not thrown. - */ - public void setPreferredRemoteSendMaxPreset(QualityPreset preset) - throws OperationFailedException - { - setRemoteSendMaxPreset(preset); - } - - /** - * Changes remote send preset, the one we will receive. - * @param preset - */ - public void setRemoteSendMaxPreset(QualityPreset preset) - { - this.maxPreset = preset; - } - - /** - * Gets the local setting of capture. - * @return the local setting of capture - */ - private QualityPreset getPreferredSendPreset() - { - if(localSettingsPreset == null) - { - DeviceConfiguration deviceConfiguration = - NeomediaActivator.getMediaServiceImpl() - .getDeviceConfiguration(); - - localSettingsPreset = new QualityPreset( - deviceConfiguration.getVideoSize(), - deviceConfiguration.getFrameRate()); - } - return localSettingsPreset; - } - - /** - * Sets maximum resolution. - * @param res - */ - public void setRemoteReceiveResolution(Dimension res) - { - try - { - this.setRemoteReceivePreset(new QualityPreset(res)); - } - catch(OperationFailedException ofe){} - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/ZrtpConfigurePanel.java b/src/net/java/sip/communicator/impl/neomedia/ZrtpConfigurePanel.java index 2ae45d725..eef4d7ab6 100644 --- a/src/net/java/sip/communicator/impl/neomedia/ZrtpConfigurePanel.java +++ b/src/net/java/sip/communicator/impl/neomedia/ZrtpConfigurePanel.java @@ -14,10 +14,11 @@ import javax.swing.event.*; import javax.swing.table.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; + /** * @author Werner Dittmann * @author Lubomir Marinov diff --git a/src/net/java/sip/communicator/impl/neomedia/ZrtpConfigureUtils.java b/src/net/java/sip/communicator/impl/neomedia/ZrtpConfigureUtils.java deleted file mode 100644 index dffea771c..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/ZrtpConfigureUtils.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import net.java.sip.communicator.service.configuration.*; -import gnu.java.zrtp.ZrtpConfigure; -import gnu.java.zrtp.ZrtpConstants; - -public class ZrtpConfigureUtils -{ - public static >String getPropertyID(T algo) - { - Class clazz = algo.getDeclaringClass(); - return "net.java.sip.communicator." + clazz.getName().replace('$', '_'); - } - - public static ZrtpConfigure getZrtpConfiguration() - { - ZrtpConfigure active = new ZrtpConfigure(); - setupConfigure(ZrtpConstants.SupportedPubKeys.DH2K, active); - setupConfigure(ZrtpConstants.SupportedHashes.S256, active); - setupConfigure(ZrtpConstants.SupportedSymCiphers.AES1, active); - setupConfigure(ZrtpConstants.SupportedSASTypes.B32, active); - setupConfigure(ZrtpConstants.SupportedAuthLengths.HS32, active); - - return active; - } - - private static > void - setupConfigure(T algo, ZrtpConfigure active) - { - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - String savedConf = null; - - if (cfg != null) - { - String id = ZrtpConfigureUtils.getPropertyID(algo); - - savedConf = cfg.getString(id); - } - if (savedConf == null) - savedConf = ""; - - Class clazz = algo.getDeclaringClass(); - String savedAlgos[] = savedConf.split(";"); - - // Configure saved algorithms as active - for (String str : savedAlgos) - { - try - { - T algoEnum = Enum.valueOf(clazz, str); - - if (algoEnum != null) - active.addAlgo(algoEnum); - } - catch (IllegalArgumentException iae) - { - // Ignore it and continue the loop. - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/ZrtpControlImpl.java b/src/net/java/sip/communicator/impl/neomedia/ZrtpControlImpl.java deleted file mode 100644 index 279af2311..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/ZrtpControlImpl.java +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import gnu.java.zrtp.*; -import gnu.java.zrtp.utils.*; - -import java.util.*; - -import net.java.sip.communicator.impl.neomedia.transform.zrtp.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.event.*; - -/** - * Controls zrtp in the MediaStream. - * - * @author Damian Minkov - */ -public class ZrtpControlImpl - implements ZrtpControl -{ - /** - * The listener interested in security events about zrtp. - */ - private SrtpListener zrtpListener = null; - - /** - * Additional info codes for and data to support ZRTP4J. - * These could be added to the library. However they are specific for this - * implementation, needing them for various GUI changes. - */ - public static enum ZRTPCustomInfoCodes - { - ZRTPNotEnabledByUser, - ZRTPDisabledByCallEnd, - ZRTPEngineInitFailure, - ZRTPEnabledByDefault - } - - /** - * The zrtp engine control by this ZrtpControl. - */ - private ZRTPTransformEngine zrtpEngine = null; - - /** - * This is the connector, required to send ZRTP packets - * via the DatagramSocket. - */ - private AbstractRTPConnector zrtpConnector = null; - - /** - * Whether current is master session. - */ - private boolean masterSession = false; - - /** - * Creates the control. - */ - ZrtpControlImpl() - { - } - - /** - * Cleans up the current zrtp control and its engine. - */ - public void cleanup() - { - if(zrtpEngine != null) - { - zrtpEngine.stopZrtp(); - zrtpEngine.cleanup(); - } - - zrtpEngine = null; - zrtpConnector = null; - } - - /** - * Sets a ZrtpListener that will listen for zrtp security events. - * - * @param zrtpListener the ZrtpListener to set - */ - public void setSrtpListener(SrtpListener zrtpListener) - { - this.zrtpListener = zrtpListener; - } - - /** - * Returns the ZrtpListener which listens for security events. - * - * @return the ZrtpListener which listens for security events - */ - public SrtpListener getSrtpListener() - { - return this.zrtpListener; - } - - /** - * Method for getting the default secure status value for communication - * - * @return the default enabled/disabled status value for secure - * communication - */ - public boolean getSecureCommunicationStatus() - { - return - (zrtpEngine != null) && zrtpEngine.getSecureCommunicationStatus(); - } - - /** - * Sets the SAS verification - * - * @param verified the new SAS verification status - */ - public void setSASVerification(boolean verified) - { - ZRTPTransformEngine engine = getTransformEngine(); - - if (verified) - engine.SASVerified(); - else - engine.resetSASVerified(); - } - - /** - * Returns the zrtp engine currently used by this stream. - * @return the zrtp engine - */ - public ZRTPTransformEngine getTransformEngine() - { - if(zrtpEngine == null) - { - zrtpEngine = new ZRTPTransformEngine(); - - // NOTE: set paranoid mode before initializing - // zrtpEngine.setParanoidMode(paranoidMode); - zrtpEngine.initialize( - "GNUZRTP4J.zid", - false, - ZrtpConfigureUtils.getZrtpConfiguration()); - zrtpEngine.setUserCallback(new SecurityEventManager(this)); - } - return zrtpEngine; - } - - /** - * When in multistream mode, enables the master session. - * @param masterSession whether current control, controls the master session. - */ - public void setMasterSession(boolean masterSession) - { - // by default its not master, change only if set to be master - // sometimes (jingle) streams are re-initing and - // we must reuse old value (true) event that false is submitted - if(masterSession) - this.masterSession = masterSession; - } - - /** - * Starts and enables zrtp in the stream holding this control. - * @param mediaType the media type of the stream this control controls. - */ - public void start(MediaType mediaType) - { - boolean zrtpAutoStart; - - // ZRTP engine initialization - ZRTPTransformEngine engine = getTransformEngine(); - // Create security user callback for each peer. - SecurityEventManager securityEventManager = engine.getUserCallback(); - - // Decide if this will become the ZRTP Master session: - // - Statement: audio media session will be started before video - // media session - // - if no other audio session was started before then this will - // become - // ZRTP Master session - // - only the ZRTP master sessions start in "auto-sensing" mode - // to immediately catch ZRTP communication from other client - // - after the master session has completed its key negotiation - // it will start other media sessions (see SCCallback) - if (masterSession) - { - zrtpAutoStart = true; - securityEventManager.setDHSession(true); - - // we know that audio is considered as master for zrtp - securityEventManager.setSessionType( - mediaType.equals(MediaType.AUDIO) ? - SecurityEventManager.AUDIO_SESSION - : SecurityEventManager.VIDEO_SESSION - ); - } - else - { - // check whether video was not already started - // it may happen when using multistreams, audio has inited - // and started video - // initially engine has value enableZrtp = false - zrtpAutoStart = zrtpEngine.isEnableZrtp(); - securityEventManager.setSessionType( - mediaType.equals(MediaType.AUDIO) ? - SecurityEventManager.AUDIO_SESSION - : SecurityEventManager.VIDEO_SESSION); - } - engine.setConnector(zrtpConnector); - - securityEventManager.setSrtpListener(zrtpListener); - - // tells the engine whether to autostart(enable) - // zrtp communication, if false it just passes packets without - // transformation - engine.setEnableZrtp(zrtpAutoStart); - - engine.sendInfo( - ZrtpCodes.MessageSeverity.Info, - EnumSet.of( - ZRTPCustomInfoCodes.ZRTPEnabledByDefault)); - } - - /** - * Start multi-stream ZRTP sessions. - * - * After the ZRTP Master (DH) session reached secure state the SCCallback - * calls this method to start the multi-stream ZRTP sessions. - * - * enable auto-start mode (auto-sensing) to the engine. - * @param master master SRTP data - */ - public void setMultistream(SrtpControl master) - { - if(master == null || master == this) - return; - - if(!(master instanceof ZrtpControlImpl)) - throw new IllegalArgumentException("master is no ZRTP control"); - - ZRTPTransformEngine engine = getTransformEngine(); - - engine.setMultiStrParams(((ZrtpControlImpl) master) - .getTransformEngine().getMultiStrParams()); - engine.setEnableZrtp(true); - } - - /** - * Return the zrtp hello hash String. - * - * @return String the zrtp hello hash. - */ - public String getHelloHash() - { - return getTransformEngine().getHelloHash(); - } - - /** - * Get the ZRTP Hello Hash data - separate strings. - * - * @return String array containing the version string at offset 0, the Hello - * hash value as hex-digits at offset 1. Hello hash is available - * immediately after class instantiation. Returns null - * if ZRTP is not available. - */ - public String[] getHelloHashSep() - { - return getTransformEngine().getHelloHashSep(); - } - - /** - * Sets the RTPConnector which is to use or uses this ZRTP engine. - * - * @param connector the RTPConnector which is to use or uses this - * ZRTP engine - */ - public void setConnector(AbstractRTPConnector connector) - { - zrtpConnector = connector; - } - - /* - * (non-Javadoc) - * - * @see - * net.java.sip.communicator.service.neomedia.ZrtpControl#getSecurityString - * () - */ - public String getSecurityString() - { - return getTransformEngine().getUserCallback().getSecurityString(); - } - - /* - * (non-Javadoc) - * - * @see - * net.java.sip.communicator.service.neomedia.ZrtpControl#getCiperString - * () - */ - public String getCipherString() - { - return getTransformEngine().getUserCallback().getCipherString(); - } - - /* - * (non-Javadoc) - * - * @see - * net.java.sip.communicator.service.neomedia.ZrtpControl#isSecurityVerified - * () - */ - public boolean isSecurityVerified() - { - return getTransformEngine().getUserCallback().isSecurityVerified(); - } - - /* - * (non-Javadoc) - * - * @see - * net.java.sip.communicator.service.neomedia.ZrtpControl#getPeerZid - * () - */ - public byte[] getPeerZid() - { - return getTransformEngine().getPeerZid(); - } - - /* - * (non-Javadoc) - * - * @see - * net.java.sip.communicator.service.neomedia.ZrtpControl#getPeerZidString - * () - */ - public String getPeerZidString() - { - byte[] zid = getPeerZid(); - String s = new String(ZrtpUtils.bytesToHexString(zid, zid.length)); - return s; - } - - /** - * Returns false, ZRTP exchanges is keys over the media path. - * - * @return false - */ - public boolean requiresSecureSignalingTransport() - { - return false; - } - - /** - * Returns the timeout value that will we will wait - * and fire timeout secure event if call is not secured. - * The value is in milliseconds. - * @return the timeout value that will we will wait - * and fire timeout secure event if call is not secured. - */ - public long getTimeoutValue() - { - // this is the default value as mentioned in rfc6189 - // we will later grab this setting from zrtp - return 3750; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/ZrtpFortunaEntropyGatherer.java b/src/net/java/sip/communicator/impl/neomedia/ZrtpFortunaEntropyGatherer.java deleted file mode 100644 index 608963e18..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/ZrtpFortunaEntropyGatherer.java +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia; - -import java.io.*; - -import javax.media.*; -import javax.media.control.FormatControl; -import javax.media.format.*; -import javax.media.protocol.*; - -import gnu.java.zrtp.utils.*; - -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.util.*; - -/** - * ZrtpFortunaEntropyGatherer initializes the Fortuna PRNG with entropy - * data. - * - * ZrtpFortunaEntropyGatherer gets the media device configuration and - * checks which media systems are available. It then reads some data from media - * input (capture) devices and uses this data to seed the Fortuna PRNG. The - * ZrtpFortuna PRNG is a singleton and all other methods that require - * random data shall use this singleton. - * - * Use ZrtpFortunaEntropyGatherer during startup and initialization - * phase of Jitsi but after initialization of the media devices to get entropy - * data at the earliest point. Also make sure that entropy data is read from - * local sources only and that entropy data is never send out (via networks - * for example). - * - * @author Werner Dittmann - * @author Lyubomir Marinov - */ -public class ZrtpFortunaEntropyGatherer -{ - /** - * The Logger used by GatherEntropy - * class for logging output. - */ - private static final Logger logger - = Logger.getLogger(ZrtpFortunaEntropyGatherer.class); - - /** - * Device config to look for capture devices. - */ - private final DeviceConfiguration deviceConfiguration; - - /** - * Other methods shall/may check this to see if Fortuna was seeded with - * entropy. - */ - private static boolean entropyOk = false; - - /** - * Number of gathered entropy bytes. - */ - private int gatheredEntropy = 0; - - /** - * How many bytes to gather. This number depends on sample rate, sample - * size, number of channels and number of audio seconds to use for random - * data. - */ - private int bytesToGather = 0; - - /** - * Bytes per 20ms time slice. - */ - private int bytes20ms = 0; - - /** - * How many seconds of audio to read. - * - */ - private static final int NUM_OF_SECONDS = 2; - - /** - * Constructor. - * - * @param deviceConfiguration DeviceConfiguration needed to - * initialize GatherEntropy - */ - public ZrtpFortunaEntropyGatherer(DeviceConfiguration deviceConfiguration) - { - this.deviceConfiguration = deviceConfiguration; - } - - /** - * Get status of entropy flag. - * - * @return Status if entropy was gathered and set in Fortuna PRNG. - */ - public static boolean isEntropyOk() - { - return entropyOk; - } - - /** - * @return the number of gathered entropy bytes. - */ - protected int getGatheredEntropy() - { - return gatheredEntropy; - } - /** - * Set entropy to ZrtpFortuna singleton. - * - * The methods reads entropy data and seeds the ZrtpFortuna singleton. - * The methods seeds the first pool (0) of Fortuna to make sure that - * this entropy is always used. - * - * @return true if entropy data was available, false otherwise. - */ - public boolean setEntropy() - { - boolean retValue = false; - GatherAudio gatherer = new GatherAudio(); - retValue = gatherer.prepareAudioEntropy(); - if (retValue) - gatherer.start(); - return retValue; - } - - private class GatherAudio - extends Thread - implements BufferTransferHandler - { - /** - * The PortAudio DataSource which provides - * {@link #audioStream}. - */ - private DataSource dataSource = null; - - /** - * The PortAudioStream from which audio data is captured. - */ - private SourceStream audioStream = null; - - /** - * The next three elements control the push buffer that Javasound - * uses. - */ - private final Buffer firstBuf = new Buffer(); - private boolean bufferAvailable = false; - private final Object bufferSync = new Object(); - - /** - * Prepares to read entropy data from portaudio capture device. - * - * The method gets an PortAudio instance with a set of capture - * parameters. - * - * @return True if the PortAudio input stream is available. - */ - private boolean prepareAudioEntropy() - { - CaptureDeviceInfo audioCaptureDevice = - deviceConfiguration.getAudioCaptureDevice(); - if (audioCaptureDevice == null) - return false; - - MediaLocator audioCaptureDeviceLocator - = audioCaptureDevice.getLocator(); - - if (audioCaptureDeviceLocator == null) - return false; - - try - { - dataSource = Manager.createDataSource(audioCaptureDeviceLocator); - } - catch (NoDataSourceException e) - { - logger.warn("No data source during entropy preparation", e); - return false; - } - catch (IOException e) - { - logger.warn("Got an IO Exception during entropy preparation", e); - return false; - } - FormatControl fc = ((CaptureDevice)dataSource).getFormatControls()[0]; - AudioFormat af = (AudioFormat)fc.getFormat(); - int framesToRead = (int)(af.getSampleRate() * NUM_OF_SECONDS); - int frameSize = (af.getSampleSizeInBits() / 8) * af.getChannels(); - bytesToGather = framesToRead * frameSize; - bytes20ms = frameSize * (int)(af.getSampleRate() /50); - - if (dataSource instanceof PullBufferDataSource) - { - audioStream = ((PullBufferDataSource) dataSource).getStreams()[0]; - } - else - { - audioStream = ((PushBufferDataSource) dataSource).getStreams()[0]; - ((PushBufferStream)audioStream).setTransferHandler(this); - } - return (audioStream != null); - } - - public void transferData(PushBufferStream stream) - { - try - { - stream.read(firstBuf); - } - catch (IOException e) - { - logger.warn("Got IOException during transfer data", e); - } - synchronized (bufferSync) - { - bufferAvailable = true; - bufferSync.notifyAll(); - } - } - /** - * Gather entropy from portaudio capture device and seed Fortuna PRNG. - * - * The method gathers a number of samples and seeds the Fortuna PRNG. - */ - @Override - public void run() - { - ZrtpFortuna fortuna = ZrtpFortuna.getInstance(); - - if ((dataSource == null) || (audioStream == null)) - return; - - try - { - dataSource.start(); - - int i = 0; - while (gatheredEntropy < bytesToGather) - { - if (audioStream instanceof PushBufferStream) - { - synchronized (bufferSync) - { - while (!bufferAvailable) - { - try - { - bufferSync.wait(); - } - catch (InterruptedException e) - { - // ignore - } - } - bufferAvailable = false; - } - } - else - ((PullBufferStream)audioStream).read(firstBuf); - byte[] entropy = (byte[])firstBuf.getData(); - gatheredEntropy += entropy.length; - - // distribute first buffers evenly over the pools, put - // others on the first pools. This method is adapted to - // SC requirements to get random data - if (i < 32) - fortuna.addSeedMaterial(entropy); - else - { - fortuna - .addSeedMaterial((i%3), entropy, 0, entropy.length); - } - i = gatheredEntropy / bytes20ms; - } - entropyOk = true; - if (logger.isInfoEnabled()) - logger.info("GatherEntropy got: " + gatheredEntropy + " bytes"); - } - catch (IOException ioex) - { - // ignore exception - } - finally - { - audioStream = null; - dataSource.disconnect(); - } - // this forces a Fortuna to use the new seed (entropy) data. - byte[] random = new byte[300]; - fortuna.nextBytes(random); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelCalculator.java b/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelCalculator.java deleted file mode 100644 index f28399517..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelCalculator.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.audiolevel; - -import net.java.sip.communicator.impl.neomedia.*; - -/** - * @author Damian Minkov - * @author Lyubomir Marinov - */ -public class AudioLevelCalculator -{ - - /** - * The decrease percentage. The decrease cannot be done with more than this - * value in percents. - */ - private static final double DEC_LEVEL = 0.2; - - /** - * The increase percentage. The increase cannot be done with more than this - * value in percents. - */ - private static final double INC_LEVEL = 0.4; - - /** - * The maximum level we can get as a result after compute. - */ - private static final int MAX_AUDIO_LEVEL = Short.MAX_VALUE; - - /** - * The maximum sound pressure level which matches the maximum of the sound - * meter. - */ - private static final double MAX_SOUND_PRESSURE_LEVEL - = 127 /* HUMAN TINNITUS (RINGING IN THE EARS) BEGINS */; - - /** - * The minimum level we can get as a result after compute. - */ - private static final int MIN_AUDIO_LEVEL = Short.MIN_VALUE; - - /** - * Modifies a specific level value so that its multiple uses for - * the purposes of a sound meter will result in a smoother, animation-like - * display of its changes. - * - * @param level the level to animate - * @param minLevel the minimum value of the range to which level - * belongs - * @param maxLevel the maximum value of the range to which level - * belongs - * @param lastLevel the last level which has been previously calculated - * @return the value which represents level with animation taken - * into account - */ - private static int animateLevel( - int level, - int minLevel, int maxLevel, int lastLevel) - { - // we don't allow to quick level changes - // the speed ot fthe change is controlled by - int diff = lastLevel - level; - - if(diff >= 0) - { - int maxDiff = (int)(maxLevel*DEC_LEVEL); - - if(diff > maxDiff) - level = lastLevel - maxDiff; - } - else - { - int maxDiff = (int)(maxLevel*INC_LEVEL); - - if(diff > maxDiff) - level = lastLevel + maxDiff; - } - return level; - } - - /** - * Estimates the signal power and use the levelRatio to scale it to the - * needed levels. - * - * @param samples the samples of the signal to calculate the signal power - * level of - * @param offset the offset that data starts. - * @param length the length of the data - * @param minLevel the minimum value of the result - * @param maxLevel the maximum value of the result - * @param lastLevel the last level we calculated. - * @return the power of the signal in dB SWL. - */ - public static int calculateSignalPowerLevel( - byte[] samples, int offset, int length, - int minLevel, int maxLevel, int lastLevel) - { - if(length == 0) - return 0; - - int samplesNumber = length/2; - int absoluteMeanSoundLevel = 0; - // magic ratio which scales good visually our levels - double levelRatio = MAX_AUDIO_LEVEL/(maxLevel - minLevel)/16; - - // Do the processing - for (int i = 0; i < samplesNumber; i++) - { - int tempL = samples[offset++]; - int tempH = samples[offset++]; - int soundLevel = tempH << 8 | (tempL & 255); - - if (soundLevel > MAX_AUDIO_LEVEL) - soundLevel = MAX_AUDIO_LEVEL; - else if (soundLevel < MIN_AUDIO_LEVEL) - soundLevel = MIN_AUDIO_LEVEL; - - absoluteMeanSoundLevel += Math.abs(soundLevel); - } - - int result - = (int)(absoluteMeanSoundLevel/samplesNumber/levelRatio); - - result = ensureLevelRange(result, minLevel, maxLevel); - result = animateLevel(result, minLevel, maxLevel, lastLevel); - return result; - } - - /** - * Calculates the sound pressure level of a signal with specific - * samples and makes sure that it is expressed as a value in the - * range between minLevel and maxLevel. - * - * @param samples the samples of the signal to calculate the sound pressure - * level of - * @param offset the offset in samples in which the samples start - * @param length the length in bytes of the samples in samples - * starting at offset - * @param minLevel the minimum value of the level to be returned - * @param maxLevel the maximum value of the level to be returned - * @param lastLevel the last level which has been previously calculated - * @return the sound pressure level of the specified signal as a value in - * the range between minLevel and maxLevel - */ - public static int calculateSoundPressureLevel( - byte[] samples, int offset, int length, - int minLevel, int maxLevel, int lastLevel) - { - double rms = 0; - int sampleCount = 0; - - while (offset < length) - { - double sample = ArrayIOUtils.readShort(samples, offset); - - sample /= Short.MAX_VALUE; - rms += sample * sample; - sampleCount++; - - offset += 2; - } - rms = (sampleCount == 0) ? 0 : Math.sqrt(rms / sampleCount); - - double db; - - if (rms > 0) - db = 20 * Math.log10(rms / 0.00002); - else - db = -MAX_SOUND_PRESSURE_LEVEL; - - return ensureLevelRange((int) db, minLevel, maxLevel); - } - - /** - * Ensures that a specific level value is in a specific range - * between minLevel and maxLevel. - * - * @param level the level to check - * @param minLevel the minimum value of the specified range - * @param maxLevel the maximum value of the specified range - * @return level if its value is between minLevel and - * maxLevel, minLevel if level has a value which - * is less than minLevel, or maxLevel if level - * has a value which is greater than maxLevel - */ - private static int ensureLevelRange(int level, int minLevel, int maxLevel) - { - if (level < minLevel) - return minLevel; - else if(level > maxLevel) - return maxLevel; - else - return level; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelEffect.java b/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelEffect.java deleted file mode 100644 index 0c5119b5f..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelEffect.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.audiolevel; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.control.*; -import net.java.sip.communicator.service.neomedia.event.*; - -/** - * An effect that would pass data to the AudioLevelEventDispatcher - * so that it would calculate levels and dispatch changes to interested parties. - * - * @author Damian Minkov - * @author Emil Ivov - * @author Lyubomir Marinov - */ -public class AudioLevelEffect - extends ControlsAdapter - implements Effect -{ - /** - * The indicator which determines whether AudioLevelEffect - * instances are to perform the copying of the data from input - * Buffers to output Buffers themselves (e.g. using - * {@link System#arraycopy(Object, int, Object, int, int)}). - */ - private static final boolean COPY_DATA_FROM_INPUT_TO_OUTPUT = true; - - /** - * The SimpleAudioLevelListener which this instance associates with - * its {@link #eventDispatcher}. - */ - private SimpleAudioLevelListener audioLevelListener = null; - - /** - * The dispatcher of the events which handles the calculation and the event - * firing in different thread in order to now slow down the JMF codec chain. - */ - private final AudioLevelEventDispatcher eventDispatcher - = new AudioLevelEventDispatcher("AudioLevelEffect Dispatcher"); - - /** - * The indicator which determines whether {@link #open()} has been called on - * this instance without an intervening {@link #close()}. - */ - private boolean open = false; - - /** - * The supported audio formats by this effect. - */ - private Format[] supportedAudioFormats; - - /** - * The minimum and maximum values of the scale - */ - public AudioLevelEffect() - { - supportedAudioFormats - = new Format[] - { - new AudioFormat( - AudioFormat.LINEAR, - Format.NOT_SPECIFIED, - 16, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - 16, - Format.NOT_SPECIFIED, - Format.byteArray) - }; - } - - /** - * Sets (or unsets if listener is null), the listener that - * is going to be notified of audio level changes detected by this effect. - * Given the semantics of the {@link AudioLevelEventDispatcher} this effect - * would do no real work if no listener is set or if it is set to - * null. - * - * @param listener the SimplAudioLevelListener that we'd like to - * receive level changes or null if we'd like level measurements - * to stop. - */ - public void setAudioLevelListener(SimpleAudioLevelListener listener) - { - synchronized (eventDispatcher) - { - audioLevelListener = listener; - if (open) - eventDispatcher.setAudioLevelListener(audioLevelListener); - } - } - - /** - * Returns audio level listener. - * - * @return audio level listener or null if not exist - */ - public SimpleAudioLevelListener getAudioLevelListener() - { - synchronized (eventDispatcher) - { - return audioLevelListener; - } - } - - /** - * Lists all of the input formats that this codec accepts. - * - * @return An array that contains the supported input Formats. - */ - public Format[] getSupportedInputFormats() - { - return supportedAudioFormats; - } - - /** - * Lists the output formats that this codec can generate. - * - * @param input The Format of the data to be used as input to the - * plug-in. - * @return An array that contains the supported output Formats. - */ - public Format[] getSupportedOutputFormats(Format input) - { - return - new Format[] - { - new AudioFormat( - AudioFormat.LINEAR, - ((AudioFormat)input).getSampleRate(), - 16, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - 16, - Format.NOT_SPECIFIED, - Format.byteArray) - }; - } - - /** - * Sets the format of the data to be input to this codec. - * - * @param format The Format to be set. - * @return The Format that was set. - */ - public Format setInputFormat(Format format) - { - return (format instanceof AudioFormat) ? (AudioFormat) format : null; - } - - /** - * Sets the format for the data this codec outputs. - * - * @param format The Format to be set. - * @return The Format that was set. - */ - public Format setOutputFormat(Format format) - { - return (format instanceof AudioFormat) ? (AudioFormat) format : null; - } - - /** - * Performs the media processing defined by this codec. - * - * @param inputBuffer The Buffer that contains the media data to be - * processed. - * @param outputBuffer The Buffer in which to store the processed - * media data. - * @return BUFFER_PROCESSED_OK if the processing is successful. - * @see PlugIn - */ - public int process(Buffer inputBuffer, Buffer outputBuffer) - { - /* - * In accord with what an Effect is generally supposed to do, copy the - * data from the inputBuffer into outputBuffer. - */ - if (COPY_DATA_FROM_INPUT_TO_OUTPUT) - { - // Copy the actual data from the input to the output. - Object data = outputBuffer.getData(); - int inputBufferLength = inputBuffer.getLength(); - byte[] bufferData; - - if ((data instanceof byte[]) && - (((byte[])data).length >= inputBufferLength)) - { - bufferData = (byte[])data; - } - else - { - bufferData = new byte[inputBufferLength]; - outputBuffer.setData(bufferData); - } - outputBuffer.setLength(inputBufferLength); - outputBuffer.setOffset(0); - - System.arraycopy( - inputBuffer.getData(), inputBuffer.getOffset(), - bufferData, 0, - inputBufferLength); - - // Now copy the remaining attributes. - outputBuffer.setFormat(inputBuffer.getFormat()); - outputBuffer.setHeader(inputBuffer.getHeader()); - outputBuffer.setSequenceNumber(inputBuffer.getSequenceNumber()); - outputBuffer.setTimeStamp(inputBuffer.getTimeStamp()); - outputBuffer.setFlags(inputBuffer.getFlags()); - outputBuffer.setDiscard(inputBuffer.isDiscard()); - outputBuffer.setEOM(inputBuffer.isEOM()); - outputBuffer.setDuration(inputBuffer.getDuration()); - } - else - { - outputBuffer.copy(inputBuffer); - } - - /* - * At long last, do the job which this AudioLevelEffect exists for i.e. - * deliver the data to eventDispatcher so that its audio level gets - * calculated and delivered to audioEventListener. - */ - eventDispatcher.addData(outputBuffer); - - return BUFFER_PROCESSED_OK; - } - - /** - * Gets the name of this plug-in as a human-readable string. - * - * @return A String that contains the descriptive name of the - * plug-in. - */ - public String getName() - { - return "Audio Level Effect"; - } - - /** - * Opens this effect. - * - * @throws ResourceUnavailableException If all of the required resources - * cannot be acquired. - */ - public void open() - throws ResourceUnavailableException - { - synchronized (eventDispatcher) - { - if (!open) - { - open = true; - eventDispatcher.setAudioLevelListener(audioLevelListener); - } - } - } - - /** - * Closes this effect. - */ - public void close() - { - synchronized (eventDispatcher) - { - if (open) - { - open = false; - eventDispatcher.setAudioLevelListener(null); - } - } - } - - /** - * Resets its state. - */ - public void reset() - { - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelEventDispatcher.java b/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelEventDispatcher.java deleted file mode 100644 index 81b6de491..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelEventDispatcher.java +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.audiolevel; - -import javax.media.*; - -import net.java.sip.communicator.service.neomedia.event.*; - -/** - * The class implements an audio level measurement thread. The thread will - * measure new data every time it is added through the addData() method - * and would then deliver it to a registered listener if any. (No measurement - * would be performed until we have a levelListener). We use a - * separate thread so that we could compute and deliver audio levels in a way - * that won't delay the media processing thread. - *

- * Note that, for performance reasons this class is not 100% thread safe and you - * should not modify add or remove audio listeners in this dispatcher in the - * notification thread (i.e. in the thread where you were notified of an audio - * level change). - * - * @author Damian Minkov - * @author Emil Ivov - * @author Lyubomir Marinov - */ -public class AudioLevelEventDispatcher -{ - /** - * The interval of time in milliseconds which the Thread of - * AudioLevelEventDispatcher is to idly wait for data to be provided for - * audio level calculation before it exits. - */ - private static final long IDLE_TIMEOUT = 30 * 1000; - - /** - * The AudioLevelMap in which the audio calculations run by this - * AudioLevelEventDispatcher are to be cached in addition to - * dispatching them to {@link #listener}. - */ - private AudioLevelMap cache = null; - - /** - * The data to process. - */ - private byte[] data = null; - - /** - * The length of the data last recorded in the data array. - */ - private int dataLength = 0; - - /** - * This is the last level we fired. - */ - private int lastLevel = 0; - - /** - * The listener which is interested in audio level changes. - */ - private SimpleAudioLevelListener listener; - - /** - * The SSRC of the stream we are measuring that we should use as a key for - * entries of the levelMap level cache. - */ - private long ssrc = -1; - - /** - * The Thread which runs the actual audio level calculations and - * dispatches to {@link #listener}. - */ - private Thread thread; - - /** - * The name of the Thread which is to run the actual audio level - * calculations and to dispatch to {@link #listener}. - */ - private final String threadName; - - /** - * Initializes a new AudioLevelEventDispatcher instance which is to - * use a specific name for its Thread which is to run the actual - * audio level calculations and to dispatch to its - * SimpleAudioLevelListener - * - * @param threadName - */ - public AudioLevelEventDispatcher(String threadName) - { - this.threadName = threadName; - } - - /** - * Runs the actual audio level calculations and dispatches to the - * {@link #listener}. - */ - private void run() - { - long idleTimeoutStart = -1; - - while (true) - { - SimpleAudioLevelListener listener; - AudioLevelMap cache; - long ssrc; - - byte[] data; - int dataLength; - - synchronized(this) - { - if (!Thread.currentThread().equals(thread)) - break; - - listener = this.listener; - cache = this.cache; - ssrc = this.ssrc; - /* - * If no one is interested in the audio level, do not even keep - * the Thread waiting. - */ - if ((listener == null) && ((cache == null) || (ssrc == -1))) - break; - - data = this.data; - dataLength = this.dataLength; - /* - * If there is no data to calculate the audio level of, wait for - * such data to be provided. - */ - if ((data == null) || (dataLength < 1)) - { - // The current thread is idle. - if (idleTimeoutStart == -1) - idleTimeoutStart = System.currentTimeMillis(); - else if ((System.currentTimeMillis() - idleTimeoutStart) - >= IDLE_TIMEOUT) - break; - - boolean interrupted = false; - - try - { - wait(IDLE_TIMEOUT); - } - catch (InterruptedException ie) - { - interrupted = true; - } - if (interrupted) - Thread.currentThread().interrupt(); - - continue; - } - // The values of data and dataLength seem valid so consume them. - this.data = null; - this.dataLength = 0; - // The current thread is no longer idle. - idleTimeoutStart = -1; - } - - int newLevel - = AudioLevelCalculator.calculateSoundPressureLevel( - data, 0, dataLength, - SimpleAudioLevelListener.MIN_LEVEL, - SimpleAudioLevelListener.MAX_LEVEL, - lastLevel); - - /* - * In order to try to mitigate the issue with allocating data, try - * to return the one which we have just calculated the audio level - * of. - */ - synchronized (this) - { - if ((this.data == null) - && (this.listener == null) - && ((this.cache == null) || (this.ssrc == -1))) - this.data = data; - } - - try - { - // Cache the newLevel if requested. - if ((cache != null) && (ssrc != -1)) - cache.putLevel(ssrc, newLevel); - // Notify the listener about the newLevel if requested. - if (listener != null) - listener.audioLevelChanged(newLevel); - } - finally - { - lastLevel = newLevel; - } - } - } - - /** - * Adds data to be processed. - * - * @param buffer the data that we'd like to queue for processing. - */ - public synchronized void addData(Buffer buffer) - { - /* - * If no one is interested in the audio level, do not even add the - * Buffer data. - */ - if ((listener == null) && ((cache == null) || (ssrc == -1))) - return; - - dataLength = buffer.getLength(); - if (dataLength > 0) - { - if((data == null) || (data.length < dataLength)) - data = new byte[dataLength]; - - Object bufferData = buffer.getData(); - - if (bufferData != null) - { - System.arraycopy( - bufferData, buffer.getOffset(), - data, 0, - dataLength); - } - - if (thread == null) - startThread(); - else - notify(); - } - } - - /** - * Sets the new listener that will be gathering all events from this - * dispatcher. - * - * @param listener the listener that we will be notifying or null - * if we are to remove it. - */ - public synchronized void setAudioLevelListener( - SimpleAudioLevelListener listener) - { - if (this.listener != listener) - { - this.listener = listener; - startOrNotifyThread(); - } - } - - /** - * Sets an AudioLevelMap that this dispatcher could use to cache - * levels it's measuring in addition to simply delivering them to a - * listener. - * - * @param cache the AudioLevelMap where this dispatcher should - * cache measured results. - * @param ssrc the SSRC key where entries should be logged - */ - public synchronized void setAudioLevelCache(AudioLevelMap cache, long ssrc) - { - if ((this.cache != cache) || (this.ssrc != ssrc)) - { - this.cache = cache; - this.ssrc = ssrc; - startOrNotifyThread(); - } - } - - /** - * Starts the Thread which is to run the audio level calculations - * and to dispatch to {@link #listener} if necessary or notifies it about a - * change it the state on which it depends. - */ - private synchronized void startOrNotifyThread() - { - if ((this.listener == null) && ((cache == null) || (ssrc == -1))) - { - thread = null; - notify(); - } - else if ((data != null) && (dataLength > 0)) - { - if (thread == null) - startThread(); - else - notify(); - } - } - - /** - * Starts the Thread which is to run the audio level calculations - * and to dispatch to {@link #listener}. - */ - private synchronized void startThread() - { - thread - = new Thread() - { - @Override - public void run() - { - try - { - AudioLevelEventDispatcher.this.run(); - } - finally - { - synchronized (AudioLevelEventDispatcher.this) - { - if (Thread.currentThread().equals(thread)) - thread = null; - /* - * If the thread of this AudioLevelEventDispatcher - * is dying yet the state suggests that it should be - * running, restart it. - */ - if ((thread == null) - && ((listener != null) - || ((cache != null) - && (ssrc != -1))) - && (data != null) - && (dataLength > 0)) - startThread(); - } - } - } - }; - thread.setDaemon(true); - if (threadName != null) - thread.setName(threadName); - - thread.start(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelMap.java b/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelMap.java deleted file mode 100644 index a382ea608..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelMap.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.audiolevel; - -/** - * The class implements a basic mapping utility that allows binding - * long CSRC ID-s to int audio levels. The class does not - * implement any synchronization for neither read nor write operations but it - * is still intended to handle concurrent access in a manner that can be - * considered graceful for the audio level use case. The class uses a - * bi-dimensional long[][] matrix that is recreated every time a - * new CSRC is added or an existing one is removed. Iterating through the - * matrix is only possible after obtaining a direct reference to it. It is - * possible for this reference to become invalid shortly after someone has - * obtained it (e.g. because someone added a new CSRC) but this should not - * cause problems for the CSRC audio level delivery case. - * - * @author Emil Ivov - */ -public class AudioLevelMap -{ - /** - * The matrix containing a CSRC-to-level mappings. - */ - private long[][] levels = null; - - /** - * If this map already contains csrc this method updates its level, - * otherwise we add a new entry mapping csrc to level. - * - * @param csrc the CSRC key that we'd like to add/update. - * @param level the new audio level for the specified csrc. - */ - public void putLevel(long csrc, int level) - { - //copy the levels matrix so that no one pulls it from under our feet. - long[][] levelsRef = levels; - int csrcIndex = findCSRC(levelsRef, csrc); - - if (csrcIndex == -1) - { - //we don't have the csrc in there yet so we need a new row. - levels = appendCSRCToMatrix(levelsRef, csrc, level); - } - else - { - levelsRef[csrcIndex][1] = level; - } - } - - /** - * Removes csrc and its mapped level from this map. - * - * @param csrc the CSRC ID that we'd like to remove from this map. - * - * @return true if csrc was present in the Map - * and false otherwise. - */ - public boolean removeLevel(long csrc) - { - //copy the levels matrix so that no one pulls it from under our feet. - long[][] levelsRef = levels; - int index = findCSRC(levelsRef, csrc); - - if (index == -1) - return false; - - if (levelsRef.length == 1) - { - levels = null; - return true; - } - - //copy levelsRef into newLevels ref making sure we skip the entry - //containing the CSRC ID that we are trying to remove; - long[][] newLevelsRef = new long[levelsRef.length - 1][]; - - System.arraycopy(levelsRef, 0, newLevelsRef, 0, index); - System.arraycopy( - levelsRef, index + 1, - newLevelsRef, index, newLevelsRef.length - index); - - levels = newLevelsRef; - return true; - } - - /** - * Returns the audio level of the specified csrc id or -1 - * if csrc is not currently registered in this map. - * - * @param csrc the CSRC ID whose level we'd like to obtain. - * - * @return the audio level of the specified csrc id or -1 - * if csrc is not currently registered in this map. - */ - public int getLevel(long csrc) - { - long[][] levelsRef = levels; - int index = findCSRC(levelsRef, csrc); - - return (index == -1) ? -1 : ((int) levelsRef[index][1]); - } - - /** - * Returns the index of the specified csrc level in the - * levels matrix or -1 if levels is null - * or does not contain csrc. - * - * @param levels the bi-dimensional array that we'd like to search for - * the specified csrc. - * @param csrc the CSRC identifier that we are looking for. - * - * @return the the index of the specified csrc level in the - * levels matrix or -1 if levels is null - * or does not contain csrc. - */ - private int findCSRC(long[][] levels, long csrc) - { - if (levels != null) - { - for (int i = 0; i < levels.length; i++) - { - if (levels[i][0] == csrc) - return i; - } - } - return -1; - } - - /** - * Creates a new bi-dimensional array containing all entries (if any) from - * the levels matrix and an extra entry for the specified - * csrc and level. - * - * @param levels the bi-dimensional levels array that we'd like to add a - * mapping to. - * @param csrc the CSRC identifier that we'd like to add to the - * levels bi-dimensional array. - * @param level the level corresponding to the csrc identifier. - * - * @return a new matrix containing all entries from levels and a new one - * mapping csrc to level - */ - private long[][] appendCSRCToMatrix(long[][] levels, long csrc, int level) - { - int newLength = 1 + ((levels == null) ? 0 : levels.length); - long[][] newLevels = new long[newLength][]; - - //put the new level. - newLevels[0] = new long[] { csrc, level }; - - if (newLength == 1) - return newLevels; - - System.arraycopy(levels, 0, newLevels, 1, levels.length); - - return newLevels; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/AbstractCodecExt.java b/src/net/java/sip/communicator/impl/neomedia/codec/AbstractCodecExt.java deleted file mode 100644 index f0287fd44..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/AbstractCodecExt.java +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec; - -import javax.media.*; - -import net.sf.fmj.media.*; - -/** - * Extends FMJ's AbstractCodec to make it even easier to implement a - * Codec. - * - * @author Lyubomir Marinov - */ -public abstract class AbstractCodecExt - extends AbstractCodec -{ - private final Class formatClass; - - /** - * The name of this PlugIn. - */ - private final String name; - - private final Format[] supportedOutputFormats; - - /** - * Initializes a new AbstractCodecExt instance with a specific - * PlugIn name, a specific Class of input and output - * Formats and a specific list of Formats supported as - * output. - * - * @param name the PlugIn name of the new instance - * @param formatClass the Class of input and output - * Formats supported by the new instance - * @param supportedOutputFormats the list of Formats supported by - * the new instance as output - */ - protected AbstractCodecExt( - String name, - Class formatClass, - Format[] supportedOutputFormats) - { - this.formatClass = formatClass; - this.name = name; - this.supportedOutputFormats = supportedOutputFormats; - - /* - * An Effect is a Codec that does not modify the Format of the data, it - * modifies the contents. - */ - if (this instanceof Effect) - inputFormats = this.supportedOutputFormats; - } - - @Override - public void close() - { - if (!opened) - return; - - doClose(); - - opened = false; - super.close(); - } - - protected void discardOutputBuffer(Buffer outputBuffer) - { - outputBuffer.setDiscard(true); - } - - protected abstract void doClose(); - - /** - * Opens this Codec and acquires the resources that it needs to - * operate. A call to {@link PlugIn#open()} on this instance will result in - * a call to doOpen only if {@link AbstractCodec#opened} is - * false. All required input and/or output formats are assumed to - * have been set on this Codec before doOpen is called. - * - * @throws ResourceUnavailableException if any of the resources that this - * Codec needs to operate cannot be acquired - */ - protected abstract void doOpen() - throws ResourceUnavailableException; - - protected abstract int doProcess(Buffer inputBuffer, Buffer outputBuffer); - - /** - * Get the output formats matching a specific input format. - * - * @param inputFormat the input format to get the matching output formats of - * @return the output formats matching the specified input format - */ - protected Format[] getMatchingOutputFormats(Format inputFormat) - { - /* - * An Effect is a Codec that does not modify the Format of the data, it - * modifies the contents. - */ - if (this instanceof Effect) - return new Format[] { inputFormat }; - - if (supportedOutputFormats != null) - return supportedOutputFormats.clone(); - return new Format[0]; - } - - @Override - public String getName() - { - return (name == null) ? super.getName() : name; - } - - /** - * Implements {@link AbstractCodec#getSupportedOutputFormats(Format)}. - * - * @param inputFormat input format - * @return array of supported output format - * @see AbstractCodec#getSupportedOutputFormats(Format) - */ - public Format[] getSupportedOutputFormats(Format inputFormat) - { - if (inputFormat == null) - return supportedOutputFormats; - - if (!formatClass.isInstance(inputFormat) - || (matches(inputFormat, inputFormats) == null)) - return new Format[0]; - - return getMatchingOutputFormats(inputFormat); - } - - /** - * Utility to perform format matching. - * - * @param in input format - * @param outs array of output formats - * @return the first output format that is supported - */ - public static Format matches(Format in, Format outs[]) - { - for (Format out : outs) - if (in.matches(out)) - return out; - return null; - } - - /** - * Opens this PlugIn software or hardware component and acquires - * the resources that it needs to operate. All required input and/or output - * formats have to be set on this PlugIn before open is - * called. Buffers should not be passed into this PlugIn without - * first calling open. - * - * @throws ResourceUnavailableException if any of the resources that this - * PlugIn needs to operate cannot be acquired - * @see AbstractPlugIn#open() - */ - @Override - public void open() - throws ResourceUnavailableException - { - if (opened) - return; - - doOpen(); - - opened = true; - super.open(); - } - - /** - * Implements AbstractCodec#process(Buffer, Buffer). - * - * @param inputBuffer - * @param outputBuffer - * @return BUFFER_PROCESSED_OK if all go OK or BUFFER_PROCESSED_FAILED if - * problems occurred - * @see AbstractCodec#process(Buffer, Buffer) - */ - public int process(Buffer inputBuffer, Buffer outputBuffer) - { - if (!checkInputBuffer(inputBuffer)) - return BUFFER_PROCESSED_FAILED; - if (isEOM(inputBuffer)) - { - propagateEOM(outputBuffer); - return BUFFER_PROCESSED_OK; - } - if (inputBuffer.isDiscard()) - { - discardOutputBuffer(outputBuffer); - return BUFFER_PROCESSED_OK; - } - - return doProcess(inputBuffer, outputBuffer); - } - - @Override - public Format setInputFormat(Format format) - { - if (!formatClass.isInstance(format) - || (matches(format, inputFormats) == null)) - return null; - - return super.setInputFormat(format); - } - - @Override - public Format setOutputFormat(Format format) - { - if (!formatClass.isInstance(format) - || (matches(format, getMatchingOutputFormats(inputFormat)) - == null)) - return null; - - return super.setOutputFormat(format); - } - - /** - * Updates the format, length and offset of a - * specific output Buffer to specific values. - * - * @param outputBuffer the output Buffer to update the properties - * of - * @param format the Format to set on outputBuffer - * @param length the length to set on outputBuffer - * @param offset the offset to set on outputBuffer - */ - protected void updateOutput( - Buffer outputBuffer, - Format format, int length, int offset) - { - outputBuffer.setFormat(format); - outputBuffer.setLength(length); - outputBuffer.setOffset(offset); - } - - protected byte[] validateByteArraySize(Buffer buffer, int newSize) - { - Object data = buffer.getData(); - byte[] newBytes; - - if (data instanceof byte[]) - { - byte[] bytes = (byte[]) data; - - if (bytes.length >= newSize) - return bytes; - - newBytes = new byte[newSize]; - System.arraycopy(bytes, 0, newBytes, 0, bytes.length); - } - else - { - newBytes = new byte[newSize]; - buffer.setLength(0); - buffer.setOffset(0); - } - - buffer.setData(newBytes); - return newBytes; - } - - protected short[] validateShortArraySize(Buffer buffer, int newSize) - { - Object data = buffer.getData(); - short[] newShorts; - - if (data instanceof short[]) - { - short[] shorts = (short[]) data; - - if (shorts.length >= newSize) - return shorts; - - newShorts = new short[newSize]; - System.arraycopy(shorts, 0, newShorts, 0, shorts.length); - } - else - { - newShorts = new short[newSize]; - buffer.setLength(0); - buffer.setOffset(0); - } - - buffer.setData(newShorts); - return newShorts; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/Constants.java b/src/net/java/sip/communicator/impl/neomedia/codec/Constants.java deleted file mode 100644 index 803c329eb..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/Constants.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec; - -import net.java.sip.communicator.util.*; - -/** - * Allows start import of net.java.sip.communicator.impl.neomedia.codec - * in order to get the constants define in - * net.java.sip.communicator.impl.neomedia.codec.Constants without star - * import of net.java.sip.communicator.impl.neomedia.codec. - * - * @author Lubomir Marinov - */ -public class Constants -{ - /** - * The ALAW/RTP constant. - */ - public static final String ALAW_RTP = "ALAW/rtp"; - - /** - * The G722 constant. - */ - public static final String G722 = "g722"; - - /** - * The G722/RTP constant. - */ - public static final String G722_RTP = "g722/rtp"; - - /** - * The iLBC constant. - */ - public static final String ILBC = "ilbc"; - - /** - * The iLBC/RTP constant. - */ - public static final String ILBC_RTP = "ilbc/rtp"; - - /** - * The SILK constant. - */ - public static final String SILK = "SILK"; - - /** - * The SILK/RTP constant. - */ - public static final String SILK_RTP = "SILK/rtp"; - - /** - * The SPEEX constant. - */ - public static final String SPEEX = "speex"; - - /** - * The SPEEX/RTP constant. - */ - public static final String SPEEX_RTP = "speex/rtp"; - - /** - * The H264 constant. - */ - public static final String H264 = "h264"; - - /** - * The H264/RTP constant. - */ - public static final String H264_RTP = "h264/rtp"; - - /** - * The H263+ constant. - */ - public static final String H263P = "H263-1998"; - - /** - * The H263+/RTP constant. - */ - public static final String H263P_RTP = "h263-1998/rtp"; - - /** - * Pseudo format representing DTMF tones sent over RTP. - */ - public static final String TELEPHONE_EVENT = "telephone-event"; - - /** - * mode : Frame size for the encoding/decoding - * 20 - 20 ms - * 30 - 30 ms - */ - public static int ILBC_MODE = 30; - - /** - * Default video width. - */ - public static final int VIDEO_WIDTH; - - /** - * Default video height. - */ - public static final int VIDEO_HEIGHT; - - static - { - - /* - * On Mac OS X, the Apple iSight camera reports two sizes 640x480 and - * 320x240 if we use the default size 352x288 we must use source format - * 640x480 in this situation we suffer from high cpu usage as every - * frame is scaled, so we use the non-standard format 320x240. - */ - if (OSUtils.IS_MAC) - { - VIDEO_WIDTH = 320; - VIDEO_HEIGHT = 240; - } - else - { - VIDEO_WIDTH = 352; - VIDEO_HEIGHT = 288; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/EncodingConfiguration.java b/src/net/java/sip/communicator/impl/neomedia/codec/EncodingConfiguration.java deleted file mode 100644 index d50b12943..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/EncodingConfiguration.java +++ /dev/null @@ -1,752 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec; - -import java.io.*; -import java.util.*; - -import javax.media.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.format.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.format.*; -import net.java.sip.communicator.util.*; - -/** - * Simple configuration of encoding priorities. - * - * @author Damian Minkov - * @author Lyubomir Marinov - */ -public class EncodingConfiguration -{ - - /** - * The Logger used by this EncodingConfiguration instance - * for logging output. - */ - private final Logger logger = Logger.getLogger(EncodingConfiguration.class); - - /** - * The SDP preference property. - */ - private static final String PROP_SDP_PREFERENCE - = "net.java.sip.communicator.impl.neomedia.codec.EncodingConfiguration"; - - /** - * The indicator which determines whether the G.729 codec is enabled. - * - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ - public static final boolean G729 = false; - - /** - * The additional custom JMF codecs. - */ - private static final String[] CUSTOM_CODECS = - { - "net.java.sip.communicator.impl.neomedia.codec.audio.alaw.DePacketizer", - "net.java.sip.communicator.impl.neomedia.codec.audio.alaw.JavaEncoder", - "net.java.sip.communicator.impl.neomedia.codec.audio.alaw.Packetizer", - "net.java.sip.communicator.impl.neomedia.codec.audio.ulaw.JavaDecoder", - "net.java.sip.communicator.impl.neomedia.codec.audio.ulaw.JavaEncoder", - "net.java.sip.communicator.impl.neomedia.codec.audio.ulaw.Packetizer", - "net.java.sip.communicator.impl.neomedia.codec.audio.speex.JNIDecoder", - "net.java.sip.communicator.impl.neomedia.codec.audio.speex.JNIEncoder", - "net.java.sip.communicator.impl.neomedia.codec.audio.speex.SpeexResampler", - "net.java.sip.communicator.impl.neomedia.codec.audio.speex.JavaDecoder", - "net.java.sip.communicator.impl.neomedia.codec.audio.speex.JavaEncoder", - "net.java.sip.communicator.impl.neomedia.codec.audio.mp3.JNIEncoder", - "net.java.sip.communicator.impl.neomedia.codec.audio.ilbc.JavaDecoder", - "net.java.sip.communicator.impl.neomedia.codec.audio.ilbc.JavaEncoder", - G729 - ? "net.java.sip.communicator.impl.neomedia.codec.audio.g729.JavaDecoder" - : null, - G729 - ? "net.java.sip.communicator.impl.neomedia.codec.audio.g729.JavaEncoder" - : null, - "net.java.sip.communicator.impl.neomedia.codec.audio.g722.JNIDecoder", - "net.java.sip.communicator.impl.neomedia.codec.audio.g722.JNIEncoder", - "net.java.sip.communicator.impl.neomedia.codec.audio.gsm.Decoder", - "net.java.sip.communicator.impl.neomedia.codec.audio.gsm.Encoder", - "net.java.sip.communicator.impl.neomedia.codec.audio.gsm.DePacketizer", - "net.java.sip.communicator.impl.neomedia.codec.audio.gsm.Packetizer", - "net.java.sip.communicator.impl.neomedia.codec.audio.silk.JavaDecoder", - "net.java.sip.communicator.impl.neomedia.codec.audio.silk.JavaEncoder", - "net.java.sip.communicator.impl.neomedia.codec.video.h263p.DePacketizer", - "net.java.sip.communicator.impl.neomedia.codec.video.h263p.JNIDecoder", - "net.java.sip.communicator.impl.neomedia.codec.video.h263p.JNIEncoder", - "net.java.sip.communicator.impl.neomedia.codec.video.h263p.Packetizer", - "net.java.sip.communicator.impl.neomedia.codec.video.h264.DePacketizer", - "net.java.sip.communicator.impl.neomedia.codec.video.h264.JNIDecoder", - "net.java.sip.communicator.impl.neomedia.codec.video.h264.JNIEncoder", - "net.java.sip.communicator.impl.neomedia.codec.video.h264.Packetizer", - "net.java.sip.communicator.impl.neomedia.codec.video.SwScaler" - }; - - /** - * The package prefixes of the additional JMF DataSources (e.g. low - * latency PortAudio and ALSA CaptureDevices). - */ - private static final String[] CUSTOM_PACKAGES - = new String[] - { - "net.java.sip.communicator.impl.neomedia.jmfext", - "net.sf.fmj" - }; - - /** - * The Comparator which sorts the sets according to the settings in - * encodingPreferences. - */ - private final Comparator encodingComparator - = new Comparator() - { - public int compare(MediaFormat s1, MediaFormat s2) - { - return compareEncodingPreferences(s1, s2); - } - }; - - /** - * That's where we keep format preferences matching SDP formats to integers. - * We keep preferences for both audio and video formats here in case we'd - * ever need to compare them to one another. In most cases however both - * would be decorelated and other components (such as the UI) should present - * them separately. - */ - private final Map encodingPreferences - = new HashMap(); - - /** - * The cache of supported AudioMediaFormats ordered by decreasing - * priority. - */ - private Set supportedAudioEncodings; - - /** - * The cache of supported VideoMediaFormats ordered by decreasing - * priority. - */ - private Set supportedVideoEncodings; - - /** - * Initializes a new EncodingConfiguration instance. - */ - public EncodingConfiguration() - { - initializeFormatPreferences(); - registerCustomPackages(); - registerCustomCodecs(); - } - - /** - * Retrieves (from the configuration service) preferences specified for - * various formats and assigns default ones to those that haven't been - * mentioned. - */ - private void initializeFormatPreferences() - { - // first init default preferences - // video - setEncodingPreference( - "H264", - VideoMediaFormatImpl.DEFAULT_CLOCK_RATE, - 1100); - - setEncodingPreference( - "H263-1998", - VideoMediaFormatImpl.DEFAULT_CLOCK_RATE, - 0); - /* - setEncodingPreference( - "H263", - VideoMediaFormatImpl.DEFAULT_CLOCK_RATE, - 1000); - */ - setEncodingPreference( - "JPEG", - VideoMediaFormatImpl.DEFAULT_CLOCK_RATE, - 950); - setEncodingPreference( - "H261", - VideoMediaFormatImpl.DEFAULT_CLOCK_RATE, - 800); - - // audio - setEncodingPreference("G722", 8000 /* actually, 16 kHz */, 705); - setEncodingPreference("SILK", 24000, 704); - setEncodingPreference("SILK", 16000, 703); - setEncodingPreference("speex", 32000, 701); - setEncodingPreference("speex", 16000, 700); - setEncodingPreference("PCMU", 8000, 650); - setEncodingPreference("PCMA", 8000, 600); - setEncodingPreference("iLBC", 8000, 500); - setEncodingPreference("GSM", 8000, 450); - setEncodingPreference("speex", 8000, 352); - setEncodingPreference("DVI4", 8000, 300); - setEncodingPreference("DVI4", 16000, 250); - setEncodingPreference("G723", 8000, 150); - - setEncodingPreference("SILK", 12000, 0); - setEncodingPreference("SILK", 8000, 0); - setEncodingPreference("G729", 8000, 0 /* proprietary */); - - // enables by default telephone event(DTMF rfc4733), with lowest - // priority as it is not needed to order it with audio codecs - setEncodingPreference(Constants.TELEPHONE_EVENT, 8000, 1); - - // now override with those that are specified by the user. - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - - if (cfg != null) - { - for (String pName - : cfg.getPropertyNamesByPrefix(PROP_SDP_PREFERENCE, false)) - { - String prefStr = cfg.getString(pName); - String fmtName = pName.substring(pName.lastIndexOf('.') + 1); - - // legacy - if (fmtName.contains("sdp")) - { - fmtName = fmtName.replaceAll("sdp", ""); - /* - * If the current version of the property name is also - * associated with a value, ignore the value for the legacy - * one. - */ - if (cfg.getString(PROP_SDP_PREFERENCE + "." + fmtName) - != null) - continue; - } - - int preference = -1; - String encoding; - double clockRate; - - try - { - preference = Integer.parseInt(prefStr); - - int encodingClockRateSeparator = fmtName.lastIndexOf('/'); - - if (encodingClockRateSeparator > -1) - { - encoding - = fmtName.substring(0, encodingClockRateSeparator); - clockRate - = Double.parseDouble( - fmtName.substring( - encodingClockRateSeparator + 1)); - } - else - { - encoding = fmtName; - clockRate = MediaFormatFactory.CLOCK_RATE_NOT_SPECIFIED; - } - } - catch (NumberFormatException nfe) - { - logger.warn( - "Failed to parse format (" - + fmtName - + ") or preference (" - + prefStr - + ").", - nfe); - continue; - } - - setEncodingPreference(encoding, clockRate, preference); - } - } - - // now update the arrays so that they are returned by order of - // preference. - updateSupportedEncodings(); - } - - /** - * Updates the codecs in the supported sets according to the preferences in - * encodingPreferences. If the preference value is 0, the codec is - * disabled. - */ - private void updateSupportedEncodings() - { - /* - * If they need updating, their caches are invalid and need rebuilding - * next time they are requested. - */ - supportedAudioEncodings = null; - supportedVideoEncodings = null; - } - - /** - * Gets the Set of enabled available MediaFormats with the - * specified MediaType sorted in decreasing priority. - * - * @param type the MediaType of the MediaFormats to get - * @return a Set of enabled available MediaFormats with - * the specified MediaType sorted in decreasing priority - */ - private Set updateSupportedEncodings(MediaType type) - { - Set supported - = new TreeSet(encodingComparator); - - for (MediaFormat format : getAvailableEncodings(type)) - if (getPriority(format) > 0) - supported.add(format); - return supported; - } - - /** - * Sets pref as the preference associated with encoding. - * Use this method for both audio and video encodings and don't worry if - * preferences are equal since we rarely need to compare prefs of video - * encodings to those of audio encodings. - * - * @param encoding the SDP int of the encoding whose pref we're setting. - * @param clockRate clock rate - * @param pref a positive int indicating the preference for that encoding. - */ - private void setEncodingPreference( - String encoding, double clockRate, - int pref) - { - MediaFormat mediaFormat = null; - - /* - * The key in encodingPreferences associated with a MediaFormat is - * currently composed of the encoding and the clockRate only so it makes - * sense to ignore the format parameters. - */ - for (MediaFormat mf : MediaUtils.getMediaFormats(encoding)) - if (mf.getClockRate() == clockRate) - { - mediaFormat = mf; - break; - } - if (mediaFormat != null) - { - encodingPreferences.put( - getEncodingPreferenceKey(mediaFormat), - pref); - } - } - - /** - * Sets priority as the preference associated with - * encoding. Use this method for both audio and video encodings and - * don't worry if the preferences are equal since we rarely need to compare - * the preferences of video encodings to those of audio encodings. - * - * @param encoding the MediaFormat specifying the encoding to set - * the priority of - * @param priority a positive int indicating the priority of - * encoding to set - */ - public void setPriority(MediaFormat encoding, int priority) - { - String encodingEncoding = encoding.getEncoding(); - - /* - * Since we'll be remembering the priority in the ConfigurationService - * by associating it with a property name/key based on encoding and - * clock rate only, it does not make sense to store the MediaFormat in - * encodingPreferences because MediaFormat is much more specific than - * just encoding and clock rate. - */ - setEncodingPreference( - encodingEncoding, encoding.getClockRate(), - priority); - - updateSupportedEncodings(); - } - - /** - * Sets the priority of the given encoding in the configuration service. - * - * @param encoding the MediaFormat specifying the encoding to set - * the priority of - * @param priority a positive int indicating the priority of - * encoding to set - */ - public void setPriorityConfig(MediaFormat encoding, int priority) - { - String encodingEncoding = encoding.getEncoding(); - - // save the settings - NeomediaActivator.getConfigurationService() - .setProperty( - PROP_SDP_PREFERENCE - + "." - + encodingEncoding - + "/" - + encoding.getClockRateString(), - priority); - } - - /** - * Set the priority for a MediaFormat. - * @param encoding the MediaFormat - * @return the priority - */ - public int getPriority(MediaFormat encoding) - { - - /* - * Directly returning encodingPreference.get(encoding) will throw a - * NullPointerException if encodingPreferences does not contain a - * mapping for encoding. - */ - Integer priority - = encodingPreferences.get(getEncodingPreferenceKey(encoding)); - - return (priority == null) ? 0 : priority; - } - - /** - * Register in JMF the custom codecs we provide - */ - private void registerCustomCodecs() - { - // Register the custom codec which haven't already been registered. - @SuppressWarnings("unchecked") - Collection registeredPlugins - = new HashSet( - PlugInManager.getPlugInList( - null, - null, - PlugInManager.CODEC)); - boolean commit = false; - - // Remove JavaRGBToYUV. - PlugInManager.removePlugIn( - "com.sun.media.codec.video.colorspace.JavaRGBToYUV", - PlugInManager.CODEC); - PlugInManager.removePlugIn( - "com.sun.media.codec.video.colorspace.JavaRGBConverter", - PlugInManager.CODEC); - PlugInManager.removePlugIn( - "com.sun.media.codec.video.colorspace.RGBScaler", - PlugInManager.CODEC); - - // Remove JMF's H263 codec. - PlugInManager.removePlugIn( - "com.sun.media.codec.video.vh263.NativeDecoder", - PlugInManager.CODEC); - PlugInManager.removePlugIn( - "com.ibm.media.codec.video.h263.NativeEncoder", - PlugInManager.CODEC); - - // Remove JMF's GSM codec. As working only on some OS. - String gsmCodecPackage = "com.ibm.media.codec.audio.gsm."; - String[] gsmCodecClasses - = new String[] - { - "JavaDecoder", - "JavaDecoder_ms", - "JavaEncoder", - "JavaEncoder_ms", - "NativeDecoder", - "NativeDecoder_ms", - "NativeEncoder", - "NativeEncoder_ms", - "Packetizer" - }; - for(String gsmCodecClass : gsmCodecClasses) - { - PlugInManager.removePlugIn( - gsmCodecPackage + gsmCodecClass, - PlugInManager.CODEC); - } - - /* - * Remove FMJ's JavaSoundCodec because it seems to slow down the - * building of the filter graph and we do not currently seem to need it. - */ - PlugInManager.removePlugIn( - "net.sf.fmj.media.codec.JavaSoundCodec", - PlugInManager.CODEC); - - for (String className : CUSTOM_CODECS) - { - - /* - * A codec with a className of null is configured at compile time to - * not be registered. - */ - if (className == null) - continue; - - if (registeredPlugins.contains(className)) - { - if (logger.isDebugEnabled()) - logger.debug( - "Codec " + className + " is already registered"); - } - else - { - commit = true; - - boolean registered; - Throwable exception = null; - - try - { - Codec codec = (Codec) - Class.forName(className).newInstance(); - - registered = - PlugInManager.addPlugIn( - className, - codec.getSupportedInputFormats(), - codec.getSupportedOutputFormats(null), - PlugInManager.CODEC); - } - catch (Throwable ex) - { - registered = false; - exception = ex; - } - if (registered) - { - if (logger.isDebugEnabled()) - logger.debug( - "Codec " - + className - + " is successfully registered"); - } - else - { - if (logger.isDebugEnabled()) - logger.debug( - "Codec " - + className - + " is NOT succsefully registered", exception); - } - } - } - - /* - * If Jitsi provides a codec which is also provided by FMJ and/or JMF, - * use Jitsi's version. - */ - @SuppressWarnings("unchecked") - Vector codecs - = PlugInManager.getPlugInList(null, null, PlugInManager.CODEC); - - if (codecs != null) - { - boolean setPlugInList = false; - - for (int i = CUSTOM_CODECS.length - 1; i >= 0; i--) - { - String className = CUSTOM_CODECS[i]; - - if (className != null) - { - int classNameIndex = codecs.indexOf(className); - - if (classNameIndex != -1) - { - codecs.remove(classNameIndex); - codecs.add(0, className); - setPlugInList = true; - } - } - } - - if (setPlugInList) - PlugInManager.setPlugInList(codecs, PlugInManager.CODEC); - } - - if (commit && !MediaServiceImpl.isJmfRegistryDisableLoad()) - { - try - { - PlugInManager.commit(); - } - catch (IOException ex) - { - logger.error("Cannot commit to PlugInManager", ex); - } - } - } - - /** - * Register in JMF the custom packages we provide - */ - private void registerCustomPackages() - { - @SuppressWarnings("unchecked") - Vector packages = PackageManager.getProtocolPrefixList(); - boolean loggerIsDebugEnabled = logger.isDebugEnabled(); - - for (String customPackage : CUSTOM_PACKAGES) - { - /* - * Linear search in a loop but it doesn't have to scale since the - * list is always short. - */ - if (!packages.contains(customPackage)) - { - packages.add(customPackage); - if (loggerIsDebugEnabled) - if (logger.isDebugEnabled()) - logger.debug("Adding package : " + customPackage); - } - } - - PackageManager.setProtocolPrefixList(packages); - PackageManager.commitProtocolPrefixList(); - if (loggerIsDebugEnabled) - { - if (logger.isDebugEnabled()) - logger.debug( - "Registering new protocol prefix list: " + packages); - } - } - - /** - * Get the available encodings for a specific MediaType. - * - * @param type the MediaType we would like to know its available - * encodings - * @return array of MediaFormat supported for the - * MediaType - */ - public MediaFormat[] getAvailableEncodings(MediaType type) - { - return MediaUtils.getMediaFormats(type); - } - - /** - * Gets the supported MediaFormats i.e. the enabled available - * MediaFormats sorted in decreasing priority. - * - * @param type the MediaType of the supported MediaFormats - * to get - * @return an array of the supported MediaFormats i.e. the enabled - * available MediaFormats sorted in decreasing priority - */ - public MediaFormat[] getSupportedEncodings(MediaType type) - { - Set supportedEncodings; - - switch (type) - { - case AUDIO: - if (supportedAudioEncodings == null) - supportedAudioEncodings = updateSupportedEncodings(type); - supportedEncodings = supportedAudioEncodings; - break; - case VIDEO: - if (supportedVideoEncodings == null) - supportedVideoEncodings = updateSupportedEncodings(type); - supportedEncodings = supportedVideoEncodings; - break; - default: - return MediaUtils.EMPTY_MEDIA_FORMATS; - } - return - supportedEncodings.toArray( - new MediaFormat[supportedEncodings.size()]); - } - - /** - * Compares the two formats for order. Returns a negative integer, zero, or - * a positive integer as the first format has been assigned a preference - * higher, equal to, or greater than the one of the second. - * - * @param enc1 the first format to compare for preference. - * @param enc2 the second format to compare for preference - * @return a negative integer, zero, or a positive integer as the first - * format has been assigned a preference higher, equal to, or greater than - * the one of the second - */ - private int compareEncodingPreferences(MediaFormat enc1, MediaFormat enc2) - { - int res = getPriority(enc2) - getPriority(enc1); - - /* - * If the encodings are with same priority, compare them by name. If we - * return equals, TreeSet will not add equal encodings. - */ - if (res == 0) - { - res = enc1.getEncoding().compareToIgnoreCase(enc2.getEncoding()); - /* - * There are formats with one and the same encoding (name) but - * different clock rates. - */ - if (res == 0) - { - res = Double.compare(enc2.getClockRate(), enc1.getClockRate()); - /* - * And then again, there are formats (e.g. H.264) with one and - * the same encoding (name) and clock rate but different format - * parameters (e.g. packetization-mode). - */ - if (res == 0) - { - // Try to preserve the order specified by MediaUtils. - int index1; - int index2; - - if (((index1 = MediaUtils.getMediaFormatIndex(enc1)) != -1) - && ((index2 = MediaUtils.getMediaFormatIndex(enc2)) - != -1)) - { - res = (index1 - index2); - } - - if (res == 0) - { - /* - * The format with more parameters will be considered - * here to be the format with higher priority. - */ - Map fmtps1 = enc1.getFormatParameters(); - Map fmtps2 = enc2.getFormatParameters(); - int fmtpCount1 = (fmtps1 == null) ? 0 : fmtps1.size(); - int fmtpCount2 = (fmtps2 == null) ? 0 : fmtps2.size(); - - /* - * TODO Even if the number of format parameters is - * equal, the two formats may still be different. - * Consider ordering by the values of the format - * parameters as well. - */ - res = (fmtpCount2 - fmtpCount1); - } - } - } - } - return res; - } - - /** - * Gets the key in {@link #encodingPreferences} which is associated with the - * priority of a specific MediaFormat. - * - * @param encoding the MediaFormat to get the key in - * {@link #encodingPreferences} of - * @return the key in {@link #encodingPreferences} which is associated with - * the priority of the specified encoding - */ - private String getEncodingPreferenceKey(MediaFormat encoding) - { - return encoding.getEncoding() + "/" + encoding.getClockRateString(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/FFmpeg.java b/src/net/java/sip/communicator/impl/neomedia/codec/FFmpeg.java deleted file mode 100644 index 07788f59f..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/FFmpeg.java +++ /dev/null @@ -1,802 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec; - -/** - * Provides the interface to the native FFmpeg library. - * - * @author Lyubomir Marinov - * @author Sebastien Vincent - */ -public class FFmpeg -{ - /** - * No pts value. - */ - public static final long AV_NOPTS_VALUE = 0x8000000000000000L; - - /** - * The AV sample format for signed 16. - */ - public static final int AV_SAMPLE_FMT_S16 = 1; - - /** - * Loop filter flag. - */ - public static final int CODEC_FLAG_LOOP_FILTER = 0x00000800; - - /** - * H263+ UMV flag. - */ - public static final int CODEC_FLAG_H263P_UMV = 0x01000000 ; - - /** - * AC pred flag. - */ - public static final int CODEC_FLAG_AC_PRED = 0x02000000; - - /** - * H263+ slice struct flag. - */ - public static final int CODEC_FLAG_H263P_SLICE_STRUCT = 0x10000000; - - /** - * Intra refresh flag2. - */ - public static final int CODEC_FLAG2_INTRA_REFRESH = 0x00200000; - - /** - * Allow to pass incomplete frame to decoder. - */ - public static final int CODEC_FLAG2_CHUNKS = 0x00008000; - - /** - * H264 codec ID. - */ - public static final int CODEC_ID_H264 = 28; - - /** - * H263 codec ID. - */ - public static final int CODEC_ID_H263 = 5; - - /** - * H263+ codec ID. - */ - public static final int CODEC_ID_H263P = 20; - - /** - * MJPEG codec ID. - */ - public static final int CODEC_ID_MJPEG = 8; - - /** - * MP3 codec ID. - */ - public static final int CODEC_ID_MP3 = 0x15000 + 1; - - /** - * Work around bugs in encoders which sometimes cannot be detected - * automatically. - */ - public static final int FF_BUG_AUTODETECT = 1; - - public static final int FF_CMP_CHROMA = 256; - - /** - * Padding size for FFmpeg input buffer. - */ - public static final int FF_INPUT_BUFFER_PADDING_SIZE = 8; - - public static final int FF_MB_DECISION_SIMPLE = 0; - - /** - * The minimum encoding buffer size defined by libavcodec. - */ - public static final int FF_MIN_BUFFER_SIZE = 16384; - - /** - * The H264 baseline profile. - */ - public static final int FF_PROFILE_H264_BASELINE = 66; - - /** - * The H264 main profile. - */ - public static final int FF_PROFILE_H264_MAIN = 77; - - /** - * ARGB format. - */ - public static final int PIX_FMT_ARGB = 27; - - /** - * BGR32 format handled in endian specific manner. - * It is stored as ABGR on big-endian and RGBA on little-endian. - */ - public static final int PIX_FMT_BGR32; - - /** - * BGR32_1 format handled in endian specific manner. - * It is stored as BGRA on big-endian and ARGB on little-endian. - */ - public static final int PIX_FMT_BGR32_1; - - /** - * "NONE" format. - */ - public static final int PIX_FMT_NONE = -1; - - /** - * NV12 format. - */ - public static final int PIX_FMT_NV12 = 25; - - /** - * RGB24 format as of FFmpeg. - */ - public static final int PIX_FMT_RGB24_1 = 2; - - /** - * BGR24 format as of FFmpeg. - */ - public static final int PIX_FMT_BGR24_1 = 3; - - /** - * RGB24 format handled in endian specific manner. - * It is stored as RGB on big-endian and BGR on little-endian. - */ - public static final int PIX_FMT_RGB24; - - /** - * RGB32 format handled in endian specific manner. - * It is stored as ARGB on big-endian and BGRA on little-endian. - */ - public static final int PIX_FMT_RGB32; - - /** - * RGB32_1 format handled in endian specific manner. - * It is stored as RGBA on big-endian and ABGR on little-endian. - */ - public static final int PIX_FMT_RGB32_1; - - /** - * UYVY422 format. - */ - public static final int PIX_FMT_UYVY422 = 17; - - /** - * UYYVYY411 format. - */ - public static final int PIX_FMT_UYYVYY411 = 18; - - /** - * YUV420P format. - */ - public static final int PIX_FMT_YUV420P = 0; - - /** - * YUYV422 format. - */ - public static final int PIX_FMT_YUYV422 = 1; - - /** - * YUVJ422P format. - */ - public static final int PIX_FMT_YUVJ422P = 13; - - /** - * BICUBIC type for libswscale conversion. - */ - public static final int SWS_BICUBIC = 4; - - //public static final int X264_RC_ABR = 2; - - /** - * Free a native pointer allocated by av_malloc. - * - * @param ptr native pointer to free - */ - public static native void av_free(long ptr); - - /** - * Allocate memory. - * - * @param size size to allocate - * @return native pointer or 0 if av_malloc failed - */ - public static native long av_malloc(int size); - - /** - * Initialize libavformat and register all the muxers, demuxers and - * protocols. - */ - public static native void av_register_all(); - - /** - * Allocate a AVContext. - * - * @return native pointer to AVContext - */ - public static native long avcodec_alloc_context(); - - /** - * Allocate a AVFrame. - * - * @return native pointer to AVFrame - */ - public static native long avcodec_alloc_frame(); - - /** - * Close an AVCodecContext - * - * @param avctx pointer to AVCodecContex - * @return 0 if success, -1 otherwise - */ - public static native int avcodec_close(long avctx); - - /** - * Decode a video frame. - * - * @param avctx codec context - * @param frame frame decoded - * @param got_picture if the decoding has produced a valid picture - * @param buf the input buffer - * @param buf_size input buffer size - * @return number of bytes written to buff if success - */ - public static native int avcodec_decode_video(long avctx, long frame, - boolean[] got_picture, byte[] buf, int buf_size); - - /** - * Decode a video frame. - * - * @param avctx codec context - * @param avframe frame decoded - * @param src input buffer - * @param src_length input buffer size - * @return number of bytes written to buff if success - */ - public static native int avcodec_decode_video(long avctx, - long avframe, long src, int src_length); - - /** - * Encodes an audio frame from samples into buf. - * - * @param avctx the codec context - * @param buf the output buffer - * @param buf_offset the output buffer offset - * @param buf_size the output buffer size - * @param samples the input buffer containing the samples. The number of - * samples read from this buffer is frame_size*channels, - * both of which are defined in avctx. For PCM audio the number of - * samples read from samples is equal to - * buf_size*input_sample_size/output_sample_size. - * @param samples_offset the offset in the input buffer containing the - * samples - * @return on error a negative value is returned, on success zero or the - * number of bytes used to encode the data read from the input buffer - */ - public static native int avcodec_encode_audio( - long avctx, - byte[] buf, int buf_offset, int buf_size, - byte[] samples, int samples_offset); - - /** - * Encode a video frame. - * - * @param avctx codec context - * @param buff the output buffer - * @param buf_size output buffer size - * @param frame frame to encode - * @return number of bytes written to buff if success - */ - public static native int avcodec_encode_video(long avctx, byte[] buff, - int buf_size, long frame); - - /** - * Find a registered decoder with a matching ID. - * - * @param id CodecID of the requested encoder - * @return an AVCodec encoder if one was found; 0, - * otherwise - */ - public static native long avcodec_find_decoder(int id); - - /** - * Finds a registered encoder with a matching codec ID. - * - * @param id CodecID of the requested encoder - * @return an AVCodec encoder if one was found; 0, - * otherwise - */ - public static native long avcodec_find_encoder(int id); - - /** - * Initializes FFmpeg's avcodec. - */ - public static native void avcodec_init(); - - /** - * Initializes the specified AVCodecContext to use the specified - * AVCodec. - * - * @param avctx the AVCodecContext which will be set up to use the - * specified AVCodec - * @param codec the AVCodec to use within the - * AVCodecContext - * @return zero on success, a negative value on error - */ - public static native int avcodec_open(long avctx, long codec); - - /** - * Add specific flags to AVCodecContext's flags member. - * - * @param avctx pointer to AVCodecContext - * @param flags flags to add - */ - public static native void avcodeccontext_add_flags(long avctx, int flags); - - /** - * Add specific flags to AVCodecContext's flags2 member. - * - * @param avctx pointer to AVCodecContext - * @param flags2 flags to add - */ - public static native void avcodeccontext_add_flags2(long avctx, int flags2); - - /** - * Add specified partitions to the avcodeccontext. - * - * @param avctx pointer to AVCodecContext - * @param partitions the partitions to add - */ - public static native void avcodeccontext_add_partitions(long avctx, - int partitions); - - /** - * Gets the samples per packet of the specified AVCodecContext. The - * property is set by libavcodec upon {@link #avcodec_open(long, long)}. - * - * @param avctx the AVCodecContext to get the samples per packet of - * @return the samples per packet of the specified AVCodecContext - */ - public static native int avcodeccontext_get_frame_size(long avctx); - - /** - * Get height of the video. - * - * @param avctx pointer to AVCodecContext - * @return video height - */ - public static native int avcodeccontext_get_height(long avctx); - - /** - * Get pixel format. - * - * @param avctx pointer to AVCodecContext - * @return pixel format - */ - public static native int avcodeccontext_get_pix_fmt(long avctx); - - /** - * Get width of the video. - * - * @param avctx pointer to AVCodecContext - * @return video width - */ - public static native int avcodeccontext_get_width(long avctx); - - /** - * Set the B-Frame strategy. - * - * @param avctx AVCodecContext pointer - * @param b_frame_strategy strategy - */ - public static native void avcodeccontext_set_b_frame_strategy(long avctx, - int b_frame_strategy); - - /** - * Sets the average bit rate of the specified AVCodecContext. The - * property is to be set by the user when encoding and is unused for - * constant quantizer encoding. It is set by libavcodec when decoding and - * its value is 0 or some bitrate if this info is available in the - * stream. - * - * @param avctx the AVCodecContext to set the average bit rate of - * @param bit_rate the average bit rate to be set to the specified - * AVCodecContext - */ - public static native void avcodeccontext_set_bit_rate(long avctx, - int bit_rate); - - /** - * Set the bit rate tolerance - * - * @param avctx the AVCodecContext to set the bit rate of - * @param bit_rate_tolerance bit rate tolerance - */ - public static native void avcodeccontext_set_bit_rate_tolerance(long avctx, - int bit_rate_tolerance); - - /** - * Sets the number of channels of the specified AVCodecContext. The - * property is audio only. - * - * @param avctx the AVCodecContext to set the number of channels of - * @param channels the number of channels to set to the specified - * AVCodecContext - */ - public static native void avcodeccontext_set_channels( - long avctx, int channels); - - public static native void avcodeccontext_set_chromaoffset(long avctx, - int chromaoffset); - - public static native void avcodeccontext_set_crf(long avctx, float crf); - - public static native void avcodeccontext_set_deblockbeta(long avctx, - int deblockbeta); - - /** - * Set the gop size (key frame interval). - * - * @param avctx the AVCodecContext to set the gop size of - * @param gop_size key frame interval - */ - public static native void avcodeccontext_set_gop_size(long avctx, - int gop_size); - - public static native void avcodeccontext_set_i_quant_factor(long avctx, - float i_quant_factor); - - /** - * Sets the minimum GOP size. - * - * @param avctx the AVCodecContext to set the minimum GOP size of - * @param keyint_min the minimum GOP size to set on avctx - */ - public static native void avcodeccontext_set_keyint_min(long avctx, - int keyint_min); - - /** - * Set the maximum B frames. - * - * @param avctx the AVCodecContext to set the maximum B frames of - * @param max_b_frames maximum B frames - */ - public static native void avcodeccontext_set_max_b_frames(long avctx, - int max_b_frames); - - public static native void avcodeccontext_set_mb_decision(long avctx, - int mb_decision); - - public static native void avcodeccontext_set_me_cmp(long avctx, int me_cmp); - - public static native void avcodeccontext_set_me_method(long avctx, - int me_method); - - public static native void avcodeccontext_set_me_range(long avctx, - int me_range); - - public static native void avcodeccontext_set_me_subpel_quality(long avctx, - int me_subpel_quality); - - /** - * Set the pixel format. - * - * @param avctx the AVCodecContext to set the pixel format of - * @param pix_fmt pixel format - */ - public static native void avcodeccontext_set_pix_fmt(long avctx, - int pix_fmt); - - public static native void avcodeccontext_set_profile(long avctx, - int profile); - - public static native void avcodeccontext_set_qcompress(long avctx, - float qcompress); - - public static native void avcodeccontext_set_quantizer(long avctx, - int qmin, int qmax, int max_qdiff); - - public static native void avcodeccontext_set_rc_buffer_size(long avctx, - int rc_buffer_size); - - public static native void avcodeccontext_set_rc_eq(long avctx, String rc_eq); - - public static native void avcodeccontext_set_rc_max_rate(long avctx, - int rc_max_rate); - - public static native void avcodeccontext_set_refs(long avctx, - int refs); - - /** - * Set the RTP payload size. - * - * @param avctx the AVCodecContext to set the RTP payload size of - * @param rtp_payload_size RTP payload size - */ - public static native void avcodeccontext_set_rtp_payload_size(long avctx, - int rtp_payload_size); - - public static native void avcodeccontext_set_sample_aspect_ratio( - long avctx, int num, int den); - - public static native void avcodeccontext_set_sample_fmt( - long avctx, int sample_fmt); - - /** - * Sets the samples per second of the specified AVCodecContext. The - * property is audio only. - * - * @param avctx the AVCodecContext to set the samples per second of - * @param sample_rate the samples per second to set to the specified - * AVCodecContext - */ - public static native void avcodeccontext_set_sample_rate( - long avctx, int sample_rate); - - /** - * Set the scene change threshold (in percent). - * - * @param avctx AVCodecContext pointer - * @param scenechange_threshold value between 0 and 100 - */ - public static native void avcodeccontext_set_scenechange_threshold( - long avctx, int scenechange_threshold); - - /** - * Set the size of the video. - * - * @param avctx pointer to AVCodecContext - * @param width video width - * @param height video height - */ - public static native void avcodeccontext_set_size(long avctx, int width, - int height); - - /** - * Set the number of thread. - * - * @param avctx the AVCodecContext to set the number of thread of - * @param thread_count number of thread to set - */ - public static native void avcodeccontext_set_thread_count(long avctx, - int thread_count); - - public static native void avcodeccontext_set_ticks_per_frame(long avctx, - int ticks_per_frame); - - public static native void avcodeccontext_set_time_base(long avctx, int num, - int den); - - public static native void avcodeccontext_set_trellis(long avctx, - int trellis); - - public static native void avcodeccontext_set_workaround_bugs(long avctx, - int workaround_bugs); - - public static native long avframe_get_pts(long frame); - - public static native void avframe_set_data(long frame, long data0, - long offset1, long offset2); - - public static native void avframe_set_key_frame(long frame, - boolean key_frame); - - public static native void avframe_set_linesize(long frame, int linesize0, - int linesize1, int linesize2); - - public static native int avpicture_fill(long picture, long ptr, - int pix_fmt, int width, int height); - - public static native long avpicture_get_data0(long picture); - - public static native int avpicture_get_size(int pix_fmt, int width, - int height); - - public static native void memcpy(int[] dst, int dst_offset, int dst_length, - long src); - - public static native void memcpy(long dst, byte[] src, int src_offset, - int src_length); - - /** - * Get BGR32 pixel format. - * - * @return BGR32 pixel format - */ - private static native int PIX_FMT_BGR32(); - - /** - * Get BGR32_1 pixel format. - * - * @return BGR32_1 pixel format - */ - private static native int PIX_FMT_BGR32_1(); - - /** - * Get RGB24 pixel format. - * - * @return RGB24 pixel format - */ - private static native int PIX_FMT_RGB24(); - - /** - * Get RGB32 pixel format. - * - * @return RGB32 pixel format - */ - private static native int PIX_FMT_RGB32(); - - /** - * Get RGB32_1 pixel format. - * - * @return RGB32_1 pixel format - */ - private static native int PIX_FMT_RGB32_1(); - - /** - * Free an SwsContext. - * - * @param context SwsContext native pointer - */ - public static native void sws_freeContext(long context); - - /** - * Get a SwsContext pointer. - * - * @param context SwsContext - * @param srcW width of source image - * @param srcH height of source image - * @param srcFormat image format - * @param dstW width of destination image - * @param dstH height destination image - * @param dstFormat destination format - * @param flags flags - * @return cached SwsContext pointer - */ - public static native long sws_getCachedContext( - long context, - int srcW, int srcH, int srcFormat, - int dstW, int dstH, int dstFormat, - int flags); - - /** - * Scale an image. - * - * @param context SwsContext native pointer - * @param src source image (native pointer) - * @param srcSliceY slice Y of source image - * @param srcSliceH slice H of source image - * @param dst destination image (java type) - * @param dstFormat destination format - * @param dstW width of destination image - * @param dstH height destination image - * @return 0 if success, -1 otherwise - */ - public static native int sws_scale( - long context, - long src, int srcSliceY, int srcSliceH, - Object dst, int dstFormat, int dstW, int dstH); - - /** - * Scale image an image. - * - * @param context SwsContext native pointer - * @param src source image (java type) - * @param srcFormat image format - * @param srcW width of source image - * @param srcH height of source image - * @param srcSliceY slice Y of source image - * @param srcSliceH slice H of source image - * @param dst destination image (java type) - * @param dstFormat destination format - * @param dstW width of destination image - * @param dstH height destination image - * @return 0 if success, -1 otherwise - */ - public static native int sws_scale( - long context, - Object src, int srcFormat, int srcW, int srcH, - int srcSliceY, int srcSliceH, - Object dst, int dstFormat, int dstW, int dstH); - - /** - * Allocates a new AVFilterGraph instance. - * - * @return a pointer to the newly-allocated AVFilterGraph instance - */ - public static native long avfilter_graph_alloc(); - - /** - * Checks the validity and configures all the links and formats in a - * specific AVFilterGraph instance. - * - * @param graph a pointer to the AVFilterGraph instance to check - * the validity of and configure - * @param log_ctx the AVClass context to be used for logging - * @return 0 on success; a negative AVERROR on error - */ - public static native int avfilter_graph_config(long graph, long log_ctx); - - /** - * Frees a specific AVFilterGraph instance and destroys its links. - * - * @param graph a pointer to the AVFilterGraph instance to free - */ - public static native void avfilter_graph_free(long graph); - - /** - * Gets a pointer to an AVFilterContext instance with a specific - * name in a specific AVFilterGraph instance. - * - * @param graph a pointer to the AVFilterGraph instance where the - * AVFilterContext instance with the specified name is to be found - * @param name the name of the AVFilterContext instance which is to - * be found in the specified graph - * @return the filter graph pointer - */ - public static native long avfilter_graph_get_filter( - long graph, - String name); - - /** - * Adds a filter graph described by a String to a specific - * AVFilterGraph instance. - * - * @param graph a pointer to the AVFilterGraph instance where to - * link the parsed graph context - * @param filters the String to be parsed - * @param inputs a pointer to a linked list to the inputs of the graph if - * any; otherwise, 0 - * @param outputs a pointer to a linked list to the outputs of the graph if - * any; otherwise, 0 - * @param log_ctx the AVClass context to be used for logging - * @return 0 on success; a negative AVERROR on error - */ - public static native int avfilter_graph_parse( - long graph, - String filters, long inputs, long outputs, long log_ctx); - - /** - * Initializes the libavfilter system and registers all built-in - * filters. - */ - public static native void avfilter_register_all(); - - /** - * Removes a reference to a buffer. If the specified - * AVFilterBufferRef is the last reference to the buffer, the - * buffer is also automatically freed. - * - * @param ref a pointer to the AVFilterBufferRef instance to remove - */ - public static native void avfilter_unref_buffer(long ref); - - public static native long get_filtered_video_frame( - long input, int width, int height, int pixFmt, - long buffer, - long ffsink, - long output); - - static - { - System.loadLibrary("jnffmpeg"); - - av_register_all(); - avfilter_register_all(); - avcodec_init(); - - PIX_FMT_BGR32 = PIX_FMT_BGR32(); - PIX_FMT_BGR32_1 = PIX_FMT_BGR32_1(); - PIX_FMT_RGB24 = PIX_FMT_RGB24(); - PIX_FMT_RGB32 = PIX_FMT_RGB32(); - PIX_FMT_RGB32_1 = PIX_FMT_RGB32_1(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/alaw/DePacketizer.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/alaw/DePacketizer.java deleted file mode 100644 index c695b7915..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/alaw/DePacketizer.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.alaw; - -import javax.media.*; -import javax.media.format.*; - -import com.sun.media.codec.audio.*; -import net.java.sip.communicator.impl.neomedia.codec.*; - -/** - * DePacketizer for ALAW codec - * @author Damian Minkov - */ -public class DePacketizer - extends AudioCodec -{ - /** - * Creates DePacketizer - */ - public DePacketizer() - { - inputFormats = new Format[]{new AudioFormat(Constants.ALAW_RTP)}; - } - - /** - * Returns the name of the DePacketizer - * @return String - */ - public String getName() - { - return "ALAW DePacketizer"; - } - - /** - * Returns the supported output formats - * @param in Format - * @return Format[] - */ - public Format[] getSupportedOutputFormats(Format in) - { - - if (in == null) - { - return new Format[]{new AudioFormat(AudioFormat.ALAW)}; - } - - if (matches(in, inputFormats) == null) - { - return new Format[1]; - } - - if (! (in instanceof AudioFormat)) - { - return new Format[]{new AudioFormat(AudioFormat.ALAW)}; - } - - AudioFormat af = (AudioFormat) in; - return new Format[] - { - new AudioFormat( - AudioFormat.ALAW, - af.getSampleRate(), - af.getSampleSizeInBits(), - af.getChannels()) - }; - } - - /** - * Initializes the codec. - */ - public void open() - {} - - /** - * Clean up - */ - public void close() - {} - - /** - * decode the buffer - * @param inputBuffer Buffer - * @param outputBuffer Buffer - * @return int - */ - public int process(Buffer inputBuffer, Buffer outputBuffer) - { - - if (!checkInputBuffer(inputBuffer)) - { - return BUFFER_PROCESSED_FAILED; - } - - if (isEOM(inputBuffer)) - { - propagateEOM(outputBuffer); - return BUFFER_PROCESSED_OK; - } - - Object outData = outputBuffer.getData(); - outputBuffer.setData(inputBuffer.getData()); - inputBuffer.setData(outData); - outputBuffer.setLength(inputBuffer.getLength()); - outputBuffer.setFormat(outputFormat); - outputBuffer.setOffset(inputBuffer.getOffset()); - return BUFFER_PROCESSED_OK; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/alaw/JavaEncoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/alaw/JavaEncoder.java deleted file mode 100644 index fceeae04d..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/alaw/JavaEncoder.java +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.alaw; - -import javax.media.*; -import javax.media.format.*; - -/** - * The ALAW Encoder. Used the FMJ ALawEncoderUtil. - * - * @author Damian Minkov - */ -public class JavaEncoder - extends com.ibm.media.codec.audio.AudioCodec -{ - /** - * The last used format. - */ - private Format lastFormat = null; - - /** - * The input sample size in bits. - */ - private int inputSampleSize; - - /** - * The byte order. - */ - private boolean bigEndian = false; - - /** - * Constructs the encoder and init the supported formats. - */ - public JavaEncoder() - { - supportedInputFormats = new AudioFormat[] - { - new AudioFormat( - AudioFormat.LINEAR, - Format.NOT_SPECIFIED, - 16, - 1, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED - ), - new AudioFormat( - AudioFormat.LINEAR, - Format.NOT_SPECIFIED, - 8, - 1, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED - )}; // support 1 channel and 8/16 bit samples - - defaultOutputFormats = new AudioFormat[] - { - new AudioFormat( - AudioFormat.ALAW, - 8000, - 8, - 1, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED - )}; - PLUGIN_NAME = "pcm to alaw converter"; - } - - /** - * Returns the output formats according to the input. - * @param in the input format. - * @return the possible output formats. - */ - protected Format[] getMatchingOutputFormats(Format in) - { - AudioFormat inFormat = (AudioFormat) in; - int sampleRate = (int) (inFormat.getSampleRate()); - - supportedOutputFormats = new AudioFormat[] - { - new AudioFormat( - AudioFormat.ALAW, - sampleRate, - 8, - 1, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED - )}; - - return supportedOutputFormats; - } - - /** - * No resources to be opened. - * @throws ResourceUnavailableException if open failed (which cannot - * happend for this codec since no resources are to be opened) - */ - public void open() throws ResourceUnavailableException - {} - - /** - * No resources used to be cleared. - */ - public void close() - {} - - /** - * Calculate the output data size. - * @param inputLength input length. - * @return the output data size. - */ - private int calculateOutputSize(int inputLength) - { - if (inputSampleSize == 16) - { - inputLength /= 2; - } - - return inputLength; - } - - /** - * Init the converter to the new format - * @param inFormat AudioFormat - */ - private void initConverter(AudioFormat inFormat) - { - lastFormat = inFormat; - inputSampleSize = inFormat.getSampleSizeInBits(); - - bigEndian = inFormat.getEndian()==AudioFormat.BIG_ENDIAN; - } - - /** - * Encodes the input buffer passing it to the output one - * @param inputBuffer Buffer - * @param outputBuffer Buffer - * @return int - */ - public int process(Buffer inputBuffer, Buffer outputBuffer) - { - if (!checkInputBuffer(inputBuffer)) - { - return BUFFER_PROCESSED_FAILED; - } - - if (isEOM(inputBuffer)) - { - propagateEOM(outputBuffer); - return BUFFER_PROCESSED_OK; - } - - Format newFormat = inputBuffer.getFormat(); - - if (lastFormat != newFormat) - { - initConverter( (AudioFormat) newFormat); - } - - if (inputBuffer.getLength() == 0) - { - return OUTPUT_BUFFER_NOT_FILLED; - } - - int outLength = calculateOutputSize(inputBuffer.getLength()); - - byte[] inpData = (byte[]) inputBuffer.getData(); - byte[] outData = validateByteArraySize(outputBuffer, outLength); - - aLawEncode(bigEndian, - inpData, inputBuffer.getOffset(), inputBuffer.getLength(), - outData); - - updateOutput(outputBuffer, outputFormat, outLength, 0); - return BUFFER_PROCESSED_OK; - } - - /** - * maximum that can be held in 15 bits - */ - public static final int MAX = 0x7fff; - - /** - * An array where the index is the 16-bit PCM input, and the value is - * the a-law result. - */ - private static byte[] pcmToALawMap; - - static - { - pcmToALawMap = new byte[65536]; - for (int i = Short.MIN_VALUE; i <= Short.MAX_VALUE; i++) - pcmToALawMap[uShortToInt((short) i)] = encode(i); - } - - /** - * 65535 - */ - public static final int MAX_USHORT = (Short.MAX_VALUE) * 2 + 1; - - /** - * Unsigned short to integer. - * @param value unsigned short. - * @return integer. - */ - public static int uShortToInt(short value) - { - if (value >= 0) - return value; - else - return MAX_USHORT + 1 + value; - } - - /** - * Encode an array of pcm values into a pre-allocated target array - * - * @param bigEndian the data byte order. - * @param data An array of bytes in Little-Endian format - * @param target A pre-allocated array to receive the A-law bytes. - * This array must be at least half the size of the source. - * @param offset of the input. - * @param length of the input. - */ - public static void aLawEncode(boolean bigEndian, - byte[] data, int offset, int length, byte[] target) - { - if (bigEndian) - aLawEncodeBigEndian(data, offset, length, target); - else - aLawEncodeLittleEndian(data, offset, length, target); - } - - /** - * Encode little endian data. - * @param data the input data. - * @param offset the input offset. - * @param length the input length. - * @param target the target array to fill. - */ - public static void aLawEncodeLittleEndian(byte[] data, - int offset, int length, byte[] target) - { - int size = length / 2; - for (int i = 0; i < size; i++) - target[i] = - aLawEncode( - ((data[offset + 2 * i + 1] & 0xff) << 8) - | (data[offset + 2 * i]) & 0xff); - } - - /** - * Encode big endian data. - * @param data the input data. - * @param offset the input offset. - * @param length the input length. - * @param target the target array to fill. - */ - public static void aLawEncodeBigEndian(byte[] data, int offset, int length, byte[] target) - { - int size = length / 2; - for (int i = 0; i < size; i++) - target[i] = aLawEncode(((data[offset + 2 * i + 1]) & 0xff) | ((data[offset + 2 * i] & 0xff) << 8)); - } - - /** - * Encode a pcm value into a a-law byte - * - * @param pcm A 16-bit pcm value - * @return A a-law encoded byte - */ - public static byte aLawEncode(int pcm) - { - return pcmToALawMap[uShortToInt((short) (pcm & 0xffff))]; - } - - /** - * Encode one a-law byte from a 16-bit signed integer. Internal use only. - * - * @param pcm A 16-bit signed pcm value - * @return A a-law encoded byte - */ - private static byte encode(int pcm) - { - //Get the sign bit. Shift it for later use without further modification - int sign = (pcm & 0x8000) >> 8; - //If the number is negative, make it positive (now it's a magnitude) - if (sign != 0) - pcm = -pcm; - //The magnitude must fit in 15 bits to avoid overflow - if (pcm > MAX) pcm = MAX; - - /* Finding the "exponent" - * Bits: - * 1 2 3 4 5 6 7 8 9 A B C D E F G - * S 7 6 5 4 3 2 1 0 0 0 0 0 0 0 0 - * We want to find where the first 1 after the sign bit is. - * We take the corresponding value from - * the second row as the exponent value. - * (i.e. if first 1 at position 7 -> exponent = 2) - * The exponent is 0 if the 1 is not found in bits 2 through 8. - * This means the exponent is 0 even if the "first 1" doesn't exist. - */ - int exponent = 7; - //Move to the right and decrement exponent until - //we hit the 1 or the exponent hits 0 - for (int expMask = 0x4000; - (pcm & expMask) == 0 && exponent>0; - exponent--, expMask >>= 1) { } - - /* The last part - the "mantissa" - * We need to take the four bits after the 1 we just found. - * To get it, we shift 0x0f : - * 1 2 3 4 5 6 7 8 9 A B C D E F G - * S 0 0 0 0 0 1 . . . . . . . . . (say that exponent is 2) - * . . . . . . . . . . . . 1 1 1 1 - * We shift it 5 times for an exponent of two, meaning - * we will shift our four bits (exponent + 3) bits. - * For convenience, we will actually just shift the number, - * then AND with 0x0f. - * - * NOTE: If the exponent is 0: - * 1 2 3 4 5 6 7 8 9 A B C D E F G - * S 0 0 0 0 0 0 0 Z Y X W V U T S (we know nothing about bit 9) - * . . . . . . . . . . . . 1 1 1 1 - * We want to get ZYXW, which means a shift of 4 instead of 3 - */ - int mantissa = (pcm >> ((exponent == 0) ? 4 : (exponent + 3))) & 0x0f; - - //The a-law byte bit arrangement is SEEEMMMM - //(Sign, Exponent, and Mantissa.) - byte alaw = (byte)(sign | exponent << 4 | mantissa); - - //Last is to flip every other bit, and the sign bit (0xD5 = 1101 0101) - return (byte)(alaw^0xD5); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/alaw/Packetizer.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/alaw/Packetizer.java deleted file mode 100644 index fc56ec6b4..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/alaw/Packetizer.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.alaw; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; - -/** - * Implements an RTP packetizer for the A-law codec. - * - * @author Damian Minkov - * @author Lyubomir Marinov - */ -public class Packetizer - extends com.ibm.media.codec.audio.AudioPacketizer -{ - /** - * Initializes a new Packetizer instance. - */ - public Packetizer() - { - defaultOutputFormats - = new AudioFormat[] - { - new AudioFormat( - Constants.ALAW_RTP, - Format.NOT_SPECIFIED, - 8, - 1, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED, - 8, - Format.NOT_SPECIFIED, - Format.byteArray) - }; - packetSize = 160; - PLUGIN_NAME = "A-law Packetizer"; - supportedInputFormats - = new AudioFormat[] - { - new AudioFormat( - AudioFormat.ALAW, - Format.NOT_SPECIFIED, - 8, - 1, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED, - 8, - Format.NOT_SPECIFIED, - Format.byteArray) - }; - } - - public Object[] getControls() - { - if (controls == null) - { - controls - = new Control[] - { - new PacketSizeAdapter(this, packetSize, true) - }; - } - return controls; - } - - protected Format[] getMatchingOutputFormats(Format in) - { - AudioFormat af = (AudioFormat) in; - double sampleRate = af.getSampleRate(); - - supportedOutputFormats - = new AudioFormat[] - { - new AudioFormat( - Constants.ALAW_RTP, - sampleRate, - 8, - 1, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED, - 8, - sampleRate, - Format.byteArray) - }; - return supportedOutputFormats; - } - - public void open() - throws ResourceUnavailableException - { - setPacketSize(packetSize); - reset(); - } - - /** - * Sets the packet size to be used by this Packetizer. - * - * @param newPacketSize the new packet size to be used by this - * Packetizer - */ - private synchronized void setPacketSize(int newPacketSize) - { - packetSize = newPacketSize; - - sample_count = packetSize; - - if (history == null) - { - history = new byte[packetSize]; - } - else if (packetSize > history.length) - { - byte[] newHistory = new byte[packetSize]; - - System.arraycopy(history, 0, newHistory, 0, historyLength); - history = newHistory; - } - } - - private static class PacketSizeAdapter - extends com.sun.media.controls.PacketSizeAdapter - { - public PacketSizeAdapter(Codec owner, int packetSize, boolean settable) - { - super(owner, packetSize, settable); - } - - @Override - public int setPacketSize(int numBytes) - { - if (numBytes < 10) - numBytes = 10; - if (numBytes > 8000) - numBytes = 8000; - - packetSize = numBytes; - - ((Packetizer)owner).setPacketSize(packetSize); - - return packetSize; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g722/JNIDecoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g722/JNIDecoder.java deleted file mode 100644 index 3696820d9..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g722/JNIDecoder.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g722; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; - -/** - * - * @author Lyubomir Marinov - */ -public class JNIDecoder - extends AbstractCodecExt -{ - static final Format[] SUPPORTED_INPUT_FORMATS - = new Format[] - { - new AudioFormat( - Constants.G722_RTP, - 8000, - Format.NOT_SPECIFIED /* sampleSizeInBits */, - 1) - }; - - static final Format[] SUPPORTED_OUTPUT_FORMATS - = new Format[] - { - new AudioFormat( - AudioFormat.LINEAR, - 16000, - 16, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED /* frameSizeInBits */, - Format.NOT_SPECIFIED /* frameRate */, - Format.byteArray) - }; - - static - { - System.loadLibrary("jng722"); - } - - private static native void g722_decoder_close(long decoder); - - private static native long g722_decoder_open(); - - private static native void g722_decoder_process( - long decoder, - byte[] input, int inputOffset, - byte[] output, int outputOffset, int outputLength); - - private long decoder; - - /** - * Initializes a new JNIDecoder instance. - */ - public JNIDecoder() - { - super("G.722 JNI Decoder", AudioFormat.class, SUPPORTED_OUTPUT_FORMATS); - - inputFormats = SUPPORTED_INPUT_FORMATS; - } - - /** - * - * @see AbstractCodecExt#doClose() - */ - protected void doClose() - { - g722_decoder_close(decoder); - } - - /** - * - * @throws ResourceUnavailableException - * @see AbstractCodecExt#doOpen() - */ - protected void doOpen() - throws ResourceUnavailableException - { - decoder = g722_decoder_open(); - if (decoder == 0) - throw new ResourceUnavailableException("g722_decoder_open"); - } - - /** - * - * @param inputBuffer - * @param outputBuffer - * @return - * @see AbstractCodecExt#doProcess(Buffer, Buffer) - */ - protected int doProcess(Buffer inputBuffer, Buffer outputBuffer) - { - byte[] input = (byte[]) inputBuffer.getData(); - - int outputOffset = outputBuffer.getOffset(); - int outputLength = inputBuffer.getLength() * 4; - byte[] output - = validateByteArraySize(outputBuffer, outputOffset + outputLength); - - g722_decoder_process( - decoder, - input, inputBuffer.getOffset(), - output, outputOffset, outputLength); - - outputBuffer.setDuration( - (outputLength * 1000000L) - / (16L /* kHz */ * 2L /* sampleSizeInBits / 8 */)); - outputBuffer.setFormat(getOutputFormat()); - outputBuffer.setLength(outputLength); - return BUFFER_PROCESSED_OK; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g722/JNIEncoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g722/JNIEncoder.java deleted file mode 100644 index a48ab050f..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g722/JNIEncoder.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g722; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; - -/** - * @author Lyubomir Marinov - */ -public class JNIEncoder - extends AbstractCodecExt -{ - static - { - System.loadLibrary("jng722"); - } - - private static native void g722_encoder_close(long encoder); - - private static native long g722_encoder_open(); - - private static native void g722_encoder_process( - long encoder, - byte[] input, int inputOffset, - byte[] output, int outputOffset, int outputLength); - - private long encoder; - - /** - * Initializes a new JNIEncoder instance. - */ - public JNIEncoder() - { - super( - "G.722 JNI Encoder", - AudioFormat.class, - JNIDecoder.SUPPORTED_INPUT_FORMATS); - - inputFormats = JNIDecoder.SUPPORTED_OUTPUT_FORMATS; - } - - /** - * - * @param length - * @return - */ - private long computeDuration(long length) - { - return (length * 1000000L) / 8L; - } - - /** - * - * @see AbstractCodecExt#doClose() - */ - protected void doClose() - { - g722_encoder_close(encoder); - } - - /** - * - * @throws ResourceUnavailableException - * @see AbstractCodecExt#doOpen() - */ - protected void doOpen() - throws ResourceUnavailableException - { - encoder = g722_encoder_open(); - if (encoder == 0) - throw new ResourceUnavailableException("g722_encoder_open"); - } - - /** - * - * @param inputBuffer - * @param outputBuffer - * @return - * @see AbstractCodecExt#doProcess(Buffer, Buffer) - */ - protected int doProcess(Buffer inputBuffer, Buffer outputBuffer) - { - int inputOffset = inputBuffer.getOffset(); - int inputLength = inputBuffer.getLength(); - byte[] input = (byte[]) inputBuffer.getData(); - - int outputOffset = outputBuffer.getOffset(); - int outputLength = inputLength / 4; - byte[] output - = validateByteArraySize(outputBuffer, outputOffset + outputLength); - - g722_encoder_process( - encoder, - input, inputOffset, - output, outputOffset, outputLength); - outputBuffer.setDuration(computeDuration(outputLength)); - outputBuffer.setFormat(getOutputFormat()); - outputBuffer.setLength(outputLength); - return BUFFER_PROCESSED_OK; - } - - /** - * Get the output Format. - * - * @return output Format configured for this Codec - * @see net.sf.fmj.media.AbstractCodec#getOutputFormat() - */ - @Override - public Format getOutputFormat() - { - Format outputFormat = super.getOutputFormat(); - - if ((outputFormat != null) - && (outputFormat.getClass() == AudioFormat.class)) - { - AudioFormat outputAudioFormat = (AudioFormat) outputFormat; - - setOutputFormat( - new AudioFormat( - outputAudioFormat.getEncoding(), - outputAudioFormat.getSampleRate(), - outputAudioFormat.getSampleSizeInBits(), - outputAudioFormat.getChannels(), - outputAudioFormat.getEndian(), - outputAudioFormat.getSigned(), - outputAudioFormat.getFrameSizeInBits(), - outputAudioFormat.getFrameRate(), - outputAudioFormat.getDataType()) - { - private static final long serialVersionUID = 0L; - - @Override - public long computeDuration(long length) - { - return JNIEncoder.this.computeDuration(length); - } - }); - } - return outputFormat; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/AcelpCo.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/AcelpCo.java deleted file mode 100644 index b0df9dc19..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/AcelpCo.java +++ /dev/null @@ -1,755 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * Fixed codebook encoding routines. - * - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class AcelpCo -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : ACELP_CO.C - Used for the floating point version of G.729 main body - (not for G.729A) -*/ - - -/** - * - * @param x (i) :Target vector - * @param h (i) :Impulse response of filters - * @param t0 (i) :Pitch lag - * @param pitch_sharp (i) :Last quantized pitch gain - * @param i_subfr (i) :Indicator of 1st subframe, - * @param code (o) :Innovative codebook - * @param y (o) :Filtered innovative codebook - * @param sign (o) :Signs of 4 pulses - * @return index of pulses positions - */ -int ACELP_codebook( - float x[], - float h[], - int t0, - float pitch_sharp, - int i_subfr, - float code[], - float y[], - IntReference sign -) -{ - int DIM_RR = Ld8k.DIM_RR; - int L_SUBFR = Ld8k.L_SUBFR; - - int i, index; - float[] dn = new float[L_SUBFR]; - float[] rr = new float[DIM_RR]; - - /*----------------------------------------------------------------* - * Include fixed-gain pitch contribution into impulse resp. h[] * - * Find correlations of h[] needed for the codebook search. * - *-----------------------------------------------------------------*/ - - if(t0 < L_SUBFR) - for (i = t0; i < L_SUBFR; i++) - h[i] += pitch_sharp * h[i-t0]; - - cor_h(h, rr); - - /*----------------------------------------------------------------* - * Compute correlation of target vector with impulse response. * - *-----------------------------------------------------------------*/ - - CorFunc.cor_h_x(h, x, dn); /* backward filtered target vector dn */ - - /*----------------------------------------------------------------* - * Find innovative codebook. * - *-----------------------------------------------------------------*/ - - index = d4i40_17(dn, rr, h, code, y, sign, i_subfr); - - /*------------------------------------------------------* - * - Add the fixed-gain pitch contribution to code[]. * - *-------------------------------------------------------*/ - - if(t0 < L_SUBFR) - for (i = t0; i < L_SUBFR; i++) - code[i] += pitch_sharp * code[i-t0]; - - return index; -} - -/** - * Compute correlations of h[] needed for the codebook search. - * - * @param h (i) :Impulse response of filters - * @param rr (o) :Correlations of H[] - */ -private void cor_h( - float[] h, - float[] rr -) -{ - int MSIZE = Ld8k.MSIZE; - int NB_POS = Ld8k.NB_POS; - int STEP = Ld8k.STEP; - - int rri0i0, rri1i1, rri2i2, rri3i3, rri4i4; - int rri0i1, rri0i2, rri0i3, rri0i4; - int rri1i2, rri1i3, rri1i4; - int rri2i3, rri2i4; - - int p0, p1, p2, p3, p4; - - int ptr_hd, ptr_hf, ptr_h1, ptr_h2; - float cor; - int i, k, ldec, l_fin_sup, l_fin_inf; - - /* Init pointers */ - rri0i0 = 0; - rri1i1 = rri0i0 + NB_POS; - rri2i2 = rri1i1 + NB_POS; - rri3i3 = rri2i2 + NB_POS; - rri4i4 = rri3i3 + NB_POS; - rri0i1 = rri4i4 + NB_POS; - rri0i2 = rri0i1 + MSIZE; - rri0i3 = rri0i2 + MSIZE; - rri0i4 = rri0i3 + MSIZE; - rri1i2 = rri0i4 + MSIZE; - rri1i3 = rri1i2 + MSIZE; - rri1i4 = rri1i3 + MSIZE; - rri2i3 = rri1i4 + MSIZE; - rri2i4 = rri2i3 + MSIZE; - - /*------------------------------------------------------------* - * Compute rri0i0[], rri1i1[], rri2i2[], rri3i3 and rri4i4[] * - *------------------------------------------------------------*/ - - p0 = rri0i0 + NB_POS-1; /* Init pointers to last position of rrixix[] */ - p1 = rri1i1 + NB_POS-1; - p2 = rri2i2 + NB_POS-1; - p3 = rri3i3 + NB_POS-1; - p4 = rri4i4 + NB_POS-1; - - ptr_h1 = 0; - cor = 0.0f; - for(i=0; i= 0.0f) - { - p_sign[i] = 1.0f; - } - else { - p_sign[i] = -1.0f; - dn[i] = -dn[i]; - } - } - - /*-------------------------------------------------------------------* - * - Compute the search threshold after three pulses * - *-------------------------------------------------------------------*/ - - - average = dn[0] + dn[1] + dn[2]; - max0 = dn[0]; - max1 = dn[1]; - max2 = dn[2]; - for (i = 5; i < L_SUBFR; i+=STEP) - { - average += dn[i] + dn[i+1]+ dn[i+2]; - if (dn[i] > max0) max0 = dn[i]; - if (dn[i+1] > max1) max1 = dn[i+1]; - if (dn[i+2] > max2) max2 = dn[i+2]; - } - max0 += max1+max2; - average *= 0.125f; /* 1/8 */ - thres = average + (max0-average)*THRESHFCB; - - /*-------------------------------------------------------------------* - * Modification of rrixiy to take into account signs. * - *-------------------------------------------------------------------*/ - ptr_ri0i1 = rri0i1; - ptr_ri0i2 = rri0i2; - ptr_ri0i3 = rri0i3; - ptr_ri0i4 = rri0i4; - - for(i0=0; i0 thres) - { - ptr_ri3i3 = rri3i3; /* Init. pointers that depend on 4th loop */ - - for (i3 = 3; i3 < L_SUBFR; i3 += STEP) - { - ps3 = ps2 + dn[i3]; - alp3 = alp2 + rr[ptr_ri3i3] + 2.0f*(rr[ptr_ri1i3] + rr[ptr_ri0i3] + rr[ptr_ri2i3]); - ptr_ri3i3++; - ptr_ri1i3++; - ptr_ri0i3++; - ptr_ri2i3++; - - ps3c = ps3*ps3; - if( (ps3c*alpha) > (psc * alp3) ) - { - psc = ps3c; - alpha = alp3; - ip0 = i0; - ip1 = i1; - ip2 = i2; - ip3 = i3; - } - } /* end of for i3 = */ - - ptr_ri0i3 -= NB_POS; - ptr_ri1i3 -= NB_POS; - - ptr_ri4i4 = rri4i4; /* Init. pointers that depend on 4th loop */ - - for (i3 = 4; i3 < L_SUBFR; i3 += STEP) - { - ps3 = ps2 + dn[i3]; - alp3 = alp2 + rr[ptr_ri4i4] + 2.0f*(rr[ptr_ri1i4] + rr[ptr_ri0i4] + rr[ptr_ri2i4]); - ptr_ri4i4++; - ptr_ri1i4++; - ptr_ri0i4++; - ptr_ri2i4++; - - ps3c = ps3*ps3; - if( (ps3c*alpha) > (psc * alp3) ) - { - psc = ps3c; - alpha = alp3; - ip0 = i0; - ip1 = i1; - ip2 = i2; - ip3 = i3; - } - } /* end of for i3 = */ - ptr_ri0i4 -= NB_POS; - ptr_ri1i4 -= NB_POS; - - time --; - if(time <= 0 ) break end_search; /* Maximum time finish */ - - } /* end of if >thres */ - else { - ptr_ri2i3 += NB_POS; - ptr_ri2i4 += NB_POS; - } - - } /* end of for i2 = */ - - ptr_ri0i2 -= NB_POS; - ptr_ri1i3 += NB_POS; - ptr_ri1i4 += NB_POS; - - } /* end of for i1 = */ - - ptr_ri0i2 += NB_POS; - ptr_ri0i3 += NB_POS; - ptr_ri0i4 += NB_POS; - - } /* end of for i0 = */ - - extra = time; - - /* Find the codeword corresponding to the selected positions */ - - for(i=0; i 0.0f) - for(i=ip0, j=0; i 0.0f) - for(i=ip1, j=0; i 0.0f) - for(i=ip2, j=0; i 0.0f) - for(i=ip3, j=0; i 0.0f) i+=1; - if(p_sign[ip1] > 0.0f) i+=2; - if(p_sign[ip2] > 0.0f) i+=4; - if(p_sign[ip3] > 0.0f) i+=8; - signs.value = i; - - ip0 = ip0 / 5; - ip1 = ip1 / 5; - ip2 = ip2 / 5; - j = (ip3 % 5) - 3; - ip3 = ( (ip3 / 5) << 1 ) + j; - - i = (ip0) + (ip1<<3) + (ip2<<6) + (ip3<<9); - - return i; -} -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Bits.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Bits.java deleted file mode 100644 index 1872e9d9a..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Bits.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * Bit stream manipulation routines. - *

prm2bits_ld8k -converts encoder parameter vector into vector of serial bits

- *

bits2prm_ld8k - converts serial received bits to encoder parameter vector

- *
- * The transmitted parameters for 8000 bits/sec are:
- *
- *     LPC:     1st codebook           7+1 bit
- *              2nd codebook           5+5 bit
- *
- *     1st subframe:
- *          pitch period                 8 bit
- *          parity check on 1st period   1 bit
- *          codebook index1 (positions) 13 bit
- *          codebook index2 (signs)      4 bit
- *          pitch and codebook gains   4+3 bit
- *
- *     2nd subframe:
- *          pitch period (relative)      5 bit
- *          codebook index1 (positions) 13 bit
- *          codebook index2 (signs)      4 bit
- *          pitch and codebook gains   4+3 bit
- * 
- * - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class Bits -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : BITS.C - Used for the floating point version of both - G.729 main body and G.729A -*/ - - -/** - * Converts encoder parameter vector into vector of serial bits. - * - * @param prm input : encoded parameters - * @param bits output: serial bits - */ -static void prm2bits_ld8k( - int prm[], - short bits[] -) -{ - int PRM_SIZE = Ld8k.PRM_SIZE; - short SIZE_WORD = Ld8k.SIZE_WORD; - short SYNC_WORD = Ld8k.SYNC_WORD; - int[] bitsno = TabLd8k.bitsno; - - int j = 0, i; - bits[j] = SYNC_WORD; /* At receiver this bit indicates BFI */ - j++; - bits[j] = SIZE_WORD; /* Number of bits in this frame */ - j++; - - for (i = 0; i < PRM_SIZE; i++) - { - int2bin(prm[i], bitsno[i], bits, j); - j += bitsno[i]; - } -} - -/** - * Convert integer to binary and write the bits bitstream array. - * - * @param value input : decimal value - * @param no_of_bits input : number of bits to use - * @param bitstream output: bitstream - * @param bitstream_offset input: bitstream offset - */ -private static void int2bin( - int value, - int no_of_bits, - short[] bitstream, - int bitstream_offset -) -{ - short BIT_0 = Ld8k.BIT_0; - short BIT_1 = Ld8k.BIT_1; - - int pt_bitstream; - int i, bit; - - pt_bitstream = bitstream_offset + no_of_bits; - - for (i = 0; i < no_of_bits; i++) - { - bit = value & 0x0001; /* get lsb */ - if (bit == 0) - bitstream[--pt_bitstream] = BIT_0; - else - bitstream[--pt_bitstream] = BIT_1; - value >>= 1; - } -} - -/** - * Converts serial received bits to encoder parameter vector. - * - * @param bits input : serial bits - * @param prm output: decoded parameters - */ -static void bits2prm_ld8k(short[] bits, int[] prm) -{ - bits2prm_ld8k(bits, 0, prm, 0); -} - -/** - * Converts serial received bits to encoder parameter vector. - * - * @param bits input : serial bits - * @param bits_offset input : serial bits offset - * @param prm output: decoded parameters - * @param prm_offset input: decoded parameters offset - */ -static void bits2prm_ld8k( - short bits[], - int bits_offset, - int prm[], - int prm_offset -) -{ - int PRM_SIZE = Ld8k.PRM_SIZE; - int[] bitsno = TabLd8k.bitsno; - - int i; - for (i = 0; i < PRM_SIZE; i++) - { - prm[i+prm_offset] = bin2int(bitsno[i], bits, bits_offset); - bits_offset += bitsno[i]; - } -} - - -/** - * Read specified bits from bit array and convert to integer value. - * - * @param no_of_bits input : number of bits to read - * @param bitstream input : array containing bits - * @param bitstream_offset input : array offset - * @return decimal value of bit pattern - */ -private static int bin2int( - int no_of_bits, - short[] bitstream, - int bitstream_offset -) -{ - short BIT_1 = Ld8k.BIT_1; - - int value, i; - int bit; - - value = 0; - for (i = 0; i < no_of_bits; i++) - { - value <<= 1; - bit = bitstream[bitstream_offset ++]; - if (bit == BIT_1) value += 1; - } - return(value); -} -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/CodLd8k.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/CodLd8k.java deleted file mode 100644 index 3a1726f00..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/CodLd8k.java +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * Functions coder_ld8k and init_coder_ld8k - * Coder constant parameters (defined in "ld8k.h") - *
- *   L_WINDOW    : LPC analysis window size.
- *   L_NEXT      : Samples of next frame needed for autocor.
- *   L_FRAME     : Frame size.
- *   L_SUBFR     : Sub-frame size.
- *   M           : LPC order.
- *   MP1         : LPC order+1
- *   L_TOTAL     : Total size of speech buffer.
- *   PIT_MIN     : Minimum pitch lag.
- *   PIT_MAX     : Maximum pitch lag.
- *   L_INTERPOL  : Length of filter for interpolation
- * 
- * - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class CodLd8k - extends Ld8k -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : COD_LD8K.C - Used for the floating point version of G.729 main body - (not for G.729A) -*/ - - - - - /*--------------------------------------------------------* - * Static memory allocation. * - *--------------------------------------------------------*/ - - /* Speech vector */ -private final float[] old_speech = new float[L_TOTAL]; -float[] new_speech; -int new_speech_offset; -private float[] speech; -private int speech_offset; -private float[] p_window; -private int p_window_offset; - - /* Weighted speech vector */ - -private final float[] old_wsp = new float[L_FRAME+PIT_MAX]; -private float[] wsp; -private int wsp_offset; - - /* Excitation vector */ - -private final float[] old_exc = new float[L_FRAME+PIT_MAX+L_INTERPOL]; -private float[] exc; -private int exc_offset; - - /* Zero vector */ - -private final float[] ai_zero = new float[L_SUBFR+MP1]; -private float[] zero; -private int zero_offset; - - - /* Lsp (Line spectral pairs) */ -private final float[/* M */] lsp_old = - { 0.9595f, 0.8413f, 0.6549f, 0.4154f, 0.1423f, - -0.1423f, -0.4154f, -0.6549f, -0.8413f, -0.9595f}; -private final float[] lsp_old_q = new float[M]; - - /* Filter's memory */ - -private final float[] mem_syn = new float[M]; -private final float[] mem_w0 = new float[M]; -private final float[] mem_w = new float[M]; -private final float[] mem_err = new float[M+L_SUBFR]; -private float[] error; -private int error_offset; - -private float sharp; - -private final AcelpCo acelpCo = new AcelpCo(); -private final Pwf pwf = new Pwf(); -private final QuaGain quaGain = new QuaGain(); -private final QuaLsp quaLsp = new QuaLsp(); -private final Taming taming = new Taming(); - -/** - * Initialization of variables for the encoder. - * Initialize pointers to speech vector. - *
- *   |--------------------|-------------|-------------|------------|
- *     previous speech           sf1           sf2         L_NEXT
- *
- *   <----------------  Total speech vector (L_TOTAL)   ----------->
- *   |   <------------  LPC analysis window (L_WINDOW)  ----------->
- *   |   |               <-- present frame (L_FRAME) -->
- * old_speech            |              <-- new speech (L_FRAME) -->
- *     p_wind            |              |
- *                     speech           |
- *                             new_speech
- * 
- */ -void init_coder_ld8k() -{ - - new_speech = old_speech; - new_speech_offset = L_TOTAL - L_FRAME; /* New speech */ - speech = new_speech; /* Present frame */ - speech_offset = new_speech_offset - L_NEXT; - p_window = old_speech; - p_window_offset = L_TOTAL - L_WINDOW; /* For LPC window */ - - /* Initialize static pointers */ - - wsp = old_wsp; - wsp_offset = PIT_MAX; - exc = old_exc; - exc_offset = PIT_MAX + L_INTERPOL; - zero = ai_zero; - zero_offset = MP1; - error = mem_err; - error_offset = M; - - /* Static vectors to zero */ - Util.set_zero(old_speech, L_TOTAL); - Util.set_zero(old_exc, PIT_MAX+L_INTERPOL); - Util.set_zero(old_wsp, PIT_MAX); - Util.set_zero(mem_syn, M); - Util.set_zero(mem_w, M); - Util.set_zero(mem_w0, M); - Util.set_zero(mem_err, M); - Util.set_zero(zero, zero_offset, L_SUBFR); - sharp = SHARPMIN; - - /* Initialize lsp_old_q[] */ - Util.copy(lsp_old, lsp_old_q, M); - - quaLsp.lsp_encw_reset(); - taming.init_exc_err(); -} - -/** - * Encoder routine ( speech data should be in new_speech ). - * - * @param ana output: analysis parameters - */ -void coder_ld8k( - int ana[] -) -{ - /* LPC coefficients */ - float[] r = new float[MP1]; /* Autocorrelations low and hi */ - float[] A_t = new float[(MP1)*2]; /* A(z) unquantized for the 2 subframes */ - float[] Aq_t = new float[(MP1)*2]; /* A(z) quantized for the 2 subframes */ - float[] Ap1 = new float[MP1]; /* A(z) with spectral expansion */ - float[] Ap2 = new float[MP1]; /* A(z) with spectral expansion */ - float[] A, Aq; /* Pointer on A_t and Aq_t */ - int A_offset, Aq_offset; - - /* LSP coefficients */ - float[] lsp_new = new float[M], lsp_new_q = new float[M]; /* LSPs at 2th subframe */ - float[] lsf_int = new float[M]; /* Interpolated LSF 1st subframe. */ - float[] lsf_new = new float[M]; - - /* Variable added for adaptive gamma1 and gamma2 of the PWF */ - - float[] rc = new float[M]; /* Reflection coefficients */ - float[] gamma1 = new float[2]; /* Gamma1 for 1st and 2nd subframes */ - float[] gamma2 = new float[2]; /* Gamma2 for 1st and 2nd subframes */ - - /* Other vectors */ - float[] synth = new float[L_FRAME]; /* Buffer for synthesis speech */ - float[] h1 = new float[L_SUBFR]; /* Impulse response h1[] */ - float[] xn = new float[L_SUBFR]; /* Target vector for pitch search */ - float[] xn2 = new float[L_SUBFR]; /* Target vector for codebook search */ - float[] code = new float[L_SUBFR]; /* Fixed codebook excitation */ - float[] y1 = new float[L_SUBFR]; /* Filtered adaptive excitation */ - float[] y2 = new float[L_SUBFR]; /* Filtered fixed codebook excitation */ - float[] g_coeff = new float[5]; /* Correlations between xn, y1, & y2: - , , , ,*/ - - /* Scalars */ - - int i, j, i_gamma, i_subfr; - IntReference iRef = new IntReference(); - int T_op, t0; - IntReference t0_min = new IntReference(), t0_max = new IntReference(), t0_frac = new IntReference(); - int index, taming; - float gain_pit, gain_code = 0.0f; - FloatReference _gain_pit = new FloatReference(), _gain_code = new FloatReference(); - - int ana_offset = 0; - -/*------------------------------------------------------------------------* - * - Perform LPC analysis: * - * * autocorrelation + lag windowing * - * * Levinson-durbin algorithm to find a[] * - * * convert a[] to lsp[] * - * * quantize and code the LSPs * - * * find the interpolated LSPs and convert to a[] for the 2 * - * subframes (both quantized and unquantized) * - *------------------------------------------------------------------------*/ - - /* LP analysis */ - - Lpc.autocorr(p_window, p_window_offset, M, r); /* Autocorrelations */ - Lpc.lag_window(M, r); /* Lag windowing */ - Lpc.levinson(r, A_t, MP1, rc); /* Levinson Durbin */ - Lpc.az_lsp(A_t, MP1, lsp_new, lsp_old); /* From A(z) to lsp */ - - /* LSP quantization */ - - quaLsp.qua_lsp(lsp_new, lsp_new_q, ana); - ana_offset += 2; /* Advance analysis parameters pointer */ - - /*--------------------------------------------------------------------* - * Find interpolated LPC parameters in all subframes (both quantized * - * and unquantized). * - * The interpolated parameters are in array A_t[] of size (M+1)*4 * - * and the quantized interpolated parameters are in array Aq_t[] * - *--------------------------------------------------------------------*/ - - Lpcfunc.int_lpc(lsp_old, lsp_new, lsf_int, lsf_new, A_t); - Lpcfunc.int_qlpc(lsp_old_q, lsp_new_q, Aq_t); - - /* update the LSPs for the next frame */ - - for(i=0; i PIT_MAX) - { - t0_max.value = PIT_MAX; - t0_min.value = t0_max.value - 6; - } - - /*------------------------------------------------------------------------* - * Loop for every subframe in the analysis frame * - *------------------------------------------------------------------------* - * To find the pitch and innovation parameters. The subframe size is * - * L_SUBFR and the loop is repeated L_FRAME/L_SUBFR times. * - * - find the weighted LPC coefficients * - * - find the LPC residual signal * - * - compute the target signal for pitch search * - * - compute impulse response of weighted synthesis filter (h1[]) * - * - find the closed-loop pitch parameters * - * - encode the pitch delay * - * - update the impulse response h1[] by including fixed-gain pitch * - * - find target vector for codebook search * - * - codebook search * - * - encode codebook address * - * - VQ of pitch and codebook gains * - * - find synthesis speech * - * - update states of weighting filter * - *------------------------------------------------------------------------*/ - - A = A_t; /* pointer to interpolated LPC parameters */ - A_offset = 0; - Aq = Aq_t; /* pointer to interpolated quantized LPC parameters */ - Aq_offset = 0; - - i_gamma = 0; - - for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) - { - /*---------------------------------------------------------------* - * Find the weighted LPC coefficients for the weighting filter. * - *---------------------------------------------------------------*/ - - Lpcfunc.weight_az(A, A_offset, gamma1[i_gamma], M, Ap1); - Lpcfunc.weight_az(A, A_offset, gamma2[i_gamma], M, Ap2); - i_gamma++; - - /*---------------------------------------------------------------* - * Compute impulse response, h1[], of weighted synthesis filter * - *---------------------------------------------------------------*/ - - for (i = 0; i <= M; i++) ai_zero[i] = Ap1[i]; - Filter.syn_filt(Aq, Aq_offset, ai_zero, 0, h1, 0, L_SUBFR, zero, zero_offset, 0); - Filter.syn_filt(Ap2, 0, h1, 0, h1, 0, L_SUBFR, zero, zero_offset, 0); - - /*------------------------------------------------------------------------* - * * - * Find the target vector for pitch search: * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * - * * - * |------| res[n] * - * speech[n]---| A(z) |-------- * - * |------| | |--------| error[n] |------| * - * zero -- (-)--| 1/A(z) |-----------| W(z) |-- target * - * exc |--------| |------| * - * * - * Instead of subtracting the zero-input response of filters from * - * the weighted input speech, the above configuration is used to * - * compute the target vector. This configuration gives better performance * - * with fixed-point implementation. The memory of 1/A(z) is updated by * - * filtering (res[n]-exc[n]) through 1/A(z), or simply by subtracting * - * the synthesis speech from the input speech: * - * error[n] = speech[n] - syn[n]. * - * The memory of W(z) is updated by filtering error[n] through W(z), * - * or more simply by subtracting the filtered adaptive and fixed * - * codebook excitations from the target: * - * target[n] - gain_pit*y1[n] - gain_code*y2[n] * - * as these signals are already available. * - * * - *------------------------------------------------------------------------*/ - - - Filter.residu(Aq, Aq_offset, speech, speech_offset + i_subfr, exc, exc_offset + i_subfr, L_SUBFR); /* LPC residual */ - - Filter.syn_filt(Aq, Aq_offset, exc, exc_offset + i_subfr, error, error_offset, L_SUBFR, mem_err, 0, 0); - - Filter.residu(Ap1, 0, error, error_offset, xn, 0, L_SUBFR); - - Filter.syn_filt(Ap2, 0, xn, 0, xn, 0, L_SUBFR, mem_w0, 0, 0); /* target signal xn[]*/ - - /*----------------------------------------------------------------------* - * Closed-loop fractional pitch search * - *----------------------------------------------------------------------*/ - - t0 = Pitch.pitch_fr3(exc, exc_offset + i_subfr, xn, h1, L_SUBFR, t0_min.value, t0_max.value, - i_subfr, t0_frac); - - - index = Pitch.enc_lag3(t0, t0_frac.value, t0_min, t0_max,PIT_MIN,PIT_MAX,i_subfr); - - ana[ana_offset] = index; - ana_offset++; - if (i_subfr == 0) - { - ana[ana_offset] = PParity.parity_pitch(index); - ana_offset++; - } - - - /*-----------------------------------------------------------------* - * - find unity gain pitch excitation (adaptive codebook entry) * - * with fractional interpolation. * - * - find filtered pitch exc. y1[]=exc[] convolve with h1[]) * - * - compute pitch gain and limit between 0 and 1.2 * - * - update target vector for codebook search * - * - find LTP residual. * - *-----------------------------------------------------------------*/ - - PredLt3.pred_lt_3(exc, exc_offset + i_subfr, t0, t0_frac.value, L_SUBFR); - - Filter.convolve(exc, exc_offset + i_subfr, h1, y1, L_SUBFR); - - gain_pit = Pitch.g_pitch(xn, y1, g_coeff, L_SUBFR); - - /* clip pitch gain if taming is necessary */ - taming = this.taming.test_err(t0, t0_frac.value); - - if( taming == 1){ - if ( gain_pit> GPCLIP) { - gain_pit = GPCLIP; - } - } - - for (i = 0; i < L_SUBFR; i++) - xn2[i] = xn[i] - y1[i]*gain_pit; - - /*-----------------------------------------------------* - * - Innovative codebook search. * - *-----------------------------------------------------*/ - - iRef.value = i; - index = acelpCo.ACELP_codebook(xn2, h1, t0, sharp, i_subfr, code, y2, iRef); - i = iRef.value; - ana[ana_offset] = index; /* Positions index */ - ana_offset++; - ana[ana_offset] = i; /* Signs index */ - ana_offset++; - - - /*-----------------------------------------------------* - * - Quantization of gains. * - *-----------------------------------------------------*/ - CorFunc.corr_xy2(xn, y1, y2, g_coeff); - - _gain_pit.value = gain_pit; - _gain_code.value = gain_code; - ana[ana_offset] = quaGain.qua_gain(code, g_coeff, L_SUBFR, _gain_pit, _gain_code, taming ); - gain_pit = _gain_pit.value; - gain_code = _gain_code.value; - ana_offset++; - - /*------------------------------------------------------------* - * - Update pitch sharpening "sharp" with quantized gain_pit * - *------------------------------------------------------------*/ - - sharp = gain_pit; - if (sharp > SHARPMAX) sharp = SHARPMAX; - if (sharp < SHARPMIN) sharp = SHARPMIN; - /*------------------------------------------------------* - * - Find the total excitation * - * - find synthesis speech corresponding to exc[] * - * - update filters' memories for finding the target * - * vector in the next subframe * - * (update error[-m..-1] and mem_w0[]) * - * update error function for taming process * - *------------------------------------------------------*/ - - for (i = 0; i < L_SUBFR; i++) - exc[exc_offset + i+i_subfr] = gain_pit*exc[exc_offset + i+i_subfr] + gain_code*code[i]; - - this.taming.update_exc_err(gain_pit, t0); - - Filter.syn_filt(Aq, Aq_offset, exc, exc_offset + i_subfr, synth, i_subfr, L_SUBFR, mem_syn, 0, 1); - - for (i = L_SUBFR-M, j = 0; i < L_SUBFR; i++, j++) - { - mem_err[j] = speech[speech_offset + i_subfr+i] - synth[i_subfr+i]; - mem_w0[j] = xn[i] - gain_pit*y1[i] - gain_code*y2[i]; - } - A_offset += MP1; /* interpolated LPC parameters for next subframe */ - Aq_offset += MP1; - - } - - /*--------------------------------------------------* - * Update signal for next frame. * - * -> shift to the left by L_FRAME: * - * speech[], wsp[] and exc[] * - *--------------------------------------------------*/ - - Util.copy(old_speech, L_FRAME, old_speech, L_TOTAL-L_FRAME); - Util.copy(old_wsp, L_FRAME, old_wsp, PIT_MAX); - Util.copy(old_exc, L_FRAME, old_exc, PIT_MAX+L_INTERPOL); -} - -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Coder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Coder.java deleted file mode 100644 index 7f4bc3c59..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Coder.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -import java.io.*; - -/** - * Main program of the ITU-T G.729 8 kbit/s encoder. - * Usage : coder speech_file bitstream_file - * - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class Coder - extends Ld8k -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : CODER.C - Used for the floating point version of G.729 main body - (not for G.729A) -*/ - - /** - * Init the PreProc - */ - private final PreProc preProc = new PreProc(); - - /** - * Init the Ld8k Coder - */ - private final CodLd8k codLd8k = new CodLd8k(); - - /** - * Transmitted parameters - */ - private final int[] prm = new int[PRM_SIZE]; - - /** - * Initialization of the coder. - */ - Coder() - { - preProc.init_pre_process(); - codLd8k.init_coder_ld8k(); /* Initialize the coder */ - } -/** - * Usage : coder speech_file bitstream_file - * - * Format for speech_file: - * Speech is read form a binary file of 16 bits data. - * - * Format for bitstream_file: - * One word (2-bytes) to indicate erasure. - * One word (2 bytes) to indicate bit rate - * 80 words (2-bytes) containing 80 bits. - * - * @param args speech_file bitstream_file - * @throws java.io.IOException - */ -public static void main(String[] args) - throws IOException -{ - InputStream f_speech; /* Speech data */ - OutputStream f_serial; /* Serial bit stream */ - - short[] sp16 = new short[L_FRAME]; /* Buffer to read 16 bits speech */ - short[] serial = new short[SERIAL_SIZE]; /* Output bit stream buffer */ - - int frame; - - System.out.printf("\n"); - System.out.printf("************ ITU G.729 8 Kbit/S SPEECH CODER **************\n"); - System.out.printf("\n"); - System.out.printf("----------------- Floating point C simulation ----------------\n"); - System.out.printf("\n"); - System.out.printf("------------ Version 1.01 (Release 2, November 2006) --------\n"); - System.out.printf("\n"); - - - /*-----------------------------------------------------------------------* - * Open speech file and result file (output serial bit stream) * - *-----------------------------------------------------------------------*/ - - if ( args.length != 2 ) - { - System.out.printf("Usage : coder speech_file bitstream_file \n"); - System.out.printf("\n"); - System.out.printf("Format for speech_file:\n"); - System.out.printf(" Speech is read form a binary file of 16 bits data.\n"); - System.out.printf("\n"); - System.out.printf("Format for bitstream_file:\n"); - System.out.printf(" One word (2-bytes) to indicate erasure.\n"); - System.out.printf(" One word (2 bytes) to indicate bit rate\n"); - System.out.printf(" 80 words (2-bytes) containing 80 bits.\n"); - System.out.printf("\n"); - System.exit( 1 ); - } - - try - { - f_speech = new FileInputStream(args[0]); - } - catch (IOException ex) - { - System.out.printf("Codder - Error opening file %s !!\n", args[0]); - System.exit(0); - throw ex; // Silence the compiler. - } - System.out.printf(" Input speech file : %s\n", args[0]); - - try - { - f_serial = new FileOutputStream(args[1]); - } - catch (IOException ex) - { - System.out.printf("Coder - Error opening file %s !!\n", args[1]); - System.exit(0); - throw ex; // Silence the compiler - } - System.out.printf(" Output bitstream file : %s\n", args[1]); - - /*-------------------------------------------------* - * Initialization of the coder. * - *-------------------------------------------------*/ - - Coder coder = new Coder(); - - /*-------------------------------------------------------------------------* - * Loop for every analysis/transmission frame. * - * -New L_FRAME data are read. (L_FRAME = number of speech data per frame) * - * -Conversion of the speech data from 16 bit integer to real * - * -Call cod_ld8k to encode the speech. * - * -The compressed serial output stream is written to a file. * - * -The synthesis speech is written to a file * - *-------------------------------------------------------------------------* - */ - - frame=0; - while(Util.fread(sp16, L_FRAME, f_speech) == L_FRAME){ - frame++; - System.out.printf(" Frame: %d\r", frame); - - coder.process(sp16, serial); - - Util.fwrite(serial, SERIAL_SIZE, f_serial); - } - - f_serial.close(); - f_speech.close(); -} /* end of main() */ - - /** - * Process L_FRAME short of speech. - * - * @param sp16 input : speach short array - * @param serial output : serial array encoded in bits_ld8k - */ - void process(short[] sp16, short[] serial) - { - float[] new_speech = codLd8k.new_speech; /* Pointer to new speech data */ - int new_speech_offset = codLd8k.new_speech_offset; - - for (int i = 0; i < L_FRAME; i++) - new_speech[new_speech_offset + i] = sp16[i]; - - preProc.pre_process(new_speech, new_speech_offset, L_FRAME); - - codLd8k.coder_ld8k(prm); - - Bits.prm2bits_ld8k(prm, serial); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/CorFunc.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/CorFunc.java deleted file mode 100644 index 6cd5b017b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/CorFunc.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * Functions corr_xy2() and cor_h_x(). - * - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class CorFunc -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : COR_FUNC.C - Used for the floating point version of both - G.729 main body and G.729A -*/ - -/** - * Compute the correlation products needed for gain computation. - * - * @param xn input : target vector x[0:l_subfr] - * @param y1 input : filtered adaptive codebook vector - * @param y2 input : filtered 1st codebook innovation - * @param g_coeff output: , -2 , and 2 - */ -static void corr_xy2( - float xn[], - float y1[], - float y2[], - float g_coeff[] -) -{ - int L_SUBFR = Ld8k.L_SUBFR; - - float y2y2, xny2, y1y2; - int i; - - y2y2= 0.01f; - for (i = 0; i < L_SUBFR; i++) y2y2 += y2[i]*y2[i]; - g_coeff[2] = y2y2 ; - - xny2 = 0.01f; - for (i = 0; i < L_SUBFR; i++) xny2+= xn[i]*y2[i]; - g_coeff[3] = -2.0f * xny2; - - y1y2 = 0.01f; - for (i = 0; i < L_SUBFR; i++) y1y2 += y1[i]*y2[i]; - g_coeff[4] = 2.0f * y1y2 ; -} - -/** - * Compute correlations of input response h[] with the target vector X[]. - * - * @param h (i) :Impulse response of filters - * @param x (i) :Target vector - * @param d (o) :Correlations between h[] and x[] - */ -static void cor_h_x( - float h[], - float x[], - float d[] -) -{ - int L_SUBFR = Ld8k.L_SUBFR; - - int i, j; - float s; - - for (i = 0; i < L_SUBFR; i++) - { - s = 0.0f; - for (j = i; j < L_SUBFR; j++) - s += x[j] * h[j-i]; - d[i] = s; - } -} - -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/DeAcelp.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/DeAcelp.java deleted file mode 100644 index 429df8772..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/DeAcelp.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class DeAcelp -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : DE_ACELP.C - Used for the floating point version of both - G.729 main body and G.729A -*/ - - -/** - * Algebraic codebook decoder. - * - * @param sign input : signs of 4 pulses - * @param index input : positions of 4 pulses - * @param cod output: innovative codevector - */ -static void decod_ACELP( - int sign, - int index, - float cod[] -) -{ - int L_SUBFR = Ld8k.L_SUBFR; - - int[] pos = new int[4]; - int i, j; - - /* decode the positions of 4 pulses */ - - i = index & 7; - pos[0] = i*5; - - index >>= 3; - i = index & 7; - pos[1] = i*5 + 1; - - index >>= 3; - i = index & 7; - pos[2] = i*5 + 2; - - index >>= 3; - j = index & 1; - index >>= 1; - i = index & 7; - pos[3] = i*5 + 3 + j; - - /* find the algebraic codeword */ - - for (i = 0; i < L_SUBFR; i++) cod[i] = 0; - - /* decode the signs of 4 pulses */ - - for (j=0; j<4; j++) - { - - i = sign & 1; - sign >>= 1; - - if (i != 0) { - cod[pos[j]] = 1.0f; - } - else { - cod[pos[j]] = -1.0f; - } - } -} -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/DecGain.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/DecGain.java deleted file mode 100644 index f846e3665..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/DecGain.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class DecGain -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ -/* - File : DEC_GAIN.C - Used for the floating point version of both - G.729 main body and G.729A -*/ -private final float[/* 4 */] past_qua_en={-14.0f,-14.0f,-14.0f,-14.0f}; - -/** - * Decode the adaptive and fixed codebook gains. - * - * @param index input : quantizer index - * @param code input : fixed code book vector - * @param l_subfr input : subframe size - * @param bfi input : bad frame indicator good = 0 - * @param gain_pit output: quantized acb gain - * @param gain_code output: quantized fcb gain - */ -void dec_gain( - int index, - float code[], - int l_subfr, - int bfi, - FloatReference gain_pit, - FloatReference gain_code -) -{ - int NCODE2 = Ld8k.NCODE2; - float[][] gbk1 = TabLd8k.gbk1; - float[][] gbk2 = TabLd8k.gbk2; - int[] imap1 = TabLd8k.imap1; - int[] imap2 = TabLd8k.imap2; - - int index1,index2; - float gcode0, g_code; - - /*----------------- Test erasure ---------------*/ - if (bfi != 0) - { - gain_pit.value *= 0.9f; - if(gain_pit.value > 0.9f) gain_pit.value=0.9f; - gain_code.value *= 0.98f; - - /*----------------------------------------------* - * update table of past quantized energies * - * (frame erasure) * - *----------------------------------------------*/ - Gainpred.gain_update_erasure(past_qua_en); - - return; - } - - /*-------------- Decode pitch gain ---------------*/ - - index1 = imap1[index/NCODE2] ; - index2 = imap2[index%NCODE2] ; - gain_pit.value = gbk1[index1][0]+gbk2[index2][0] ; - - /*-------------- Decode codebook gain ---------------*/ - - /*---------------------------------------------------* - *- energy due to innovation -* - *- predicted energy -* - *- predicted codebook gain => gcode0[exp_gcode0] -* - *---------------------------------------------------*/ - - gcode0 = Gainpred.gain_predict( past_qua_en, code, l_subfr); - - /*-----------------------------------------------------------------* - * *gain_code = (gbk1[indice1][1]+gbk2[indice2][1]) * gcode0; * - *-----------------------------------------------------------------*/ - - g_code = gbk1[index1][1]+gbk2[index2][1]; - gain_code.value = g_code * gcode0; - - /*----------------------------------------------* - * update table of past quantized energies * - *----------------------------------------------*/ - - Gainpred.gain_update( past_qua_en, g_code); -} -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/DecLag3.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/DecLag3.java deleted file mode 100644 index 0ee826c5b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/DecLag3.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class DecLag3 -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : DEC_LAG3.C - Used for the floating point version of both - G.729 main body and G.729A -*/ - -/** - * Decoding of fractional pitch lag with 1/3 resolution. - * See the source for more details about the encoding procedure. - * - * @param index input : received pitch index - * @param pit_min input : minimum pitch lag - * @param pit_max input : maximum pitch lag - * @param i_subfr input : subframe flag - * @param T0 output: integer part of pitch lag - * @param T0_frac output: fractional part of pitch lag - */ -static void dec_lag3( - int index, - int pit_min, - int pit_max, - int i_subfr, - IntReference T0, - IntReference T0_frac -) -{ - int i; - int _T0 = T0.value, _T0_frac = T0_frac.value; - int T0_min, T0_max; - - if (i_subfr == 0) /* if 1st subframe */ - { - if (index < 197) - { - _T0 = (index+2)/3 + 19; - _T0_frac = index - _T0*3 + 58; - } - else - { - _T0 = index - 112; - _T0_frac = 0; - } - } - - else /* second subframe */ - { - /* find T0_min and T0_max for 2nd subframe */ - - T0_min = _T0 - 5; - if (T0_min < pit_min) - T0_min = pit_min; - - T0_max = T0_min + 9; - if(T0_max > pit_max) - { - T0_max = pit_max; - T0_min = T0_max -9; - } - - i = (index+2)/3 - 1; - _T0 = i + T0_min; - _T0_frac = index - 2 - i*3; - } - T0.value = _T0; - T0_frac.value = _T0_frac; -} -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/DecLd8k.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/DecLd8k.java deleted file mode 100644 index c1516550a..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/DecLd8k.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * Functions init_decod_ld8k and decod_ld8k. - *
- * Decoder constant parameters (defined in "ld8k.h")
- *   L_FRAME     : Frame size.
- *   L_SUBFR     : Sub-frame size.
- *   M           : LPC order.
- *   MP1         : LPC order+1
- *   PIT_MIN     : Minimum pitch lag.
- *   PIT_MAX     : Maximum pitch lag.
- *   L_INTERPOL  : Length of filter for interpolation
- *   PRM_SIZE    : Size of vector containing analysis parameters
- * 
- * - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class DecLd8k - extends Ld8k -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : DEC_LD8K.C - Used for the floating point version of G.729 main body - (not for G.729A) -*/ - -/*--------------------------------------------------------* - * Static memory allocation. * - *--------------------------------------------------------*/ - -/** - * Excitation vector - */ -private final float[] old_exc = new float[L_FRAME+PIT_MAX+L_INTERPOL]; - -/** - * Excitation vector - */ -private float[] exc; - -/** - * Excitation vector offset - */ -private int exc_offset; - -/** - * Lsp (Line spectral pairs) - */ -private final float[/* M */] lsp_old={ - 0.9595f, 0.8413f, 0.6549f, 0.4154f, 0.1423f, - -0.1423f, -0.4154f, -0.6549f, -0.8413f, -0.9595f}; - -/** - * Filter's memory - */ -private final float[] mem_syn = new float[M]; - -/** - * pitch sharpening of previous fr - */ -private float sharp ; - -/** -* integer delay of previous frame -*/ -private int old_t0; - -/** - * fixed codebook gain - */ -private final FloatReference gain_code = new FloatReference(); - -/** - * adaptive codebook gain - */ -private final FloatReference gain_pitch = new FloatReference(); - -private final DecGain decGain = new DecGain(); -private final Lspdec lspdec = new Lspdec(); - -/** - * Initialization of variables for the decoder section. - */ -void init_decod_ld8k() -{ - /* Initialize static pointer */ - exc = old_exc; - exc_offset = PIT_MAX + L_INTERPOL; - - /* Static vectors to zero */ - Util.set_zero(old_exc,PIT_MAX + L_INTERPOL); - Util.set_zero(mem_syn, M); - - sharp = SHARPMIN; - old_t0 = 60; - gain_code.value = 0.f; - gain_pitch.value = 0.f; - - lspdec.lsp_decw_reset(); -} - -/** - * Decoder - * - * @param parm input : synthesis parameters (parm[0] = bfi) - * @param voicing input : voicing decision from previous frame - * @param synth output: synthesized speech - * @param synth_offset input : synthesized speech offset - * @param A_t output: two sets of A(z) coefficients length=2*MP1 - * @return output: integer delay of first subframe - */ -int decod_ld8k( - int parm[], - int voicing, - float synth[], - int synth_offset, - float A_t[] -) -{ - int parm_offset = 0; - - int t0_first = 0; /* output: integer delay of first subframe */ - float[] Az; /* Pointer to A_t (LPC coefficients) */ - int Az_offset; - float[] lsp_new = new float[M]; /* LSPs */ - float[] code = new float[L_SUBFR]; /* algebraic codevector */ - - /* Scalars */ - int i, i_subfr; - IntReference t0 = new IntReference(), t0_frac = new IntReference(); - int index; - - int bfi; - int bad_pitch; - - /* Test bad frame indicator (bfi) */ - - bfi = parm[parm_offset]; - parm_offset++; - - /* Decode the LSPs */ - - lspdec.d_lsp(parm, parm_offset, lsp_new, bfi); - parm_offset += 2; /* Advance synthesis parameters pointer */ - - /* Interpolation of LPC for the 2 subframes */ - - Lpcfunc.int_qlpc(lsp_old, lsp_new, A_t); - - /* update the LSFs for the next frame */ - - Util.copy(lsp_new, lsp_old, M); - -/*------------------------------------------------------------------------* - * Loop for every subframe in the analysis frame * - *------------------------------------------------------------------------* - * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR * - * times * - * - decode the pitch delay * - * - decode algebraic code * - * - decode pitch and codebook gains * - * - find the excitation and compute synthesis speech * - *------------------------------------------------------------------------*/ - - Az = A_t; /* pointer to interpolated LPC parameters */ - Az_offset = 0; - - for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { - - index = parm[parm_offset]; /* pitch index */ - parm_offset++; - - if (i_subfr == 0) { /* if first subframe */ - i = parm[parm_offset]; /* get parity check result */ - parm_offset++; - bad_pitch = bfi+ i; - if( bad_pitch == 0) - { - DecLag3.dec_lag3(index, PIT_MIN, PIT_MAX, i_subfr, t0, t0_frac); - old_t0 = t0.value; - } - else /* Bad frame, or parity error */ - { - t0.value = old_t0; - t0_frac.value = 0; - old_t0++; - if( old_t0> PIT_MAX) { - old_t0 = PIT_MAX; - } - } - t0_first = t0.value; /* If first frame */ - } - else /* second subframe */ - { - if( bfi == 0) - { - DecLag3.dec_lag3(index, PIT_MIN, PIT_MAX, i_subfr, t0, t0_frac); - old_t0 = t0.value; - } - else - { - t0.value = old_t0; - t0_frac.value = 0; - old_t0++; - if( old_t0 >PIT_MAX) { - old_t0 = PIT_MAX; - } - } - } - - - /*-------------------------------------------------* - * - Find the adaptive codebook vector. * - *--------------------------------------------------*/ - - PredLt3.pred_lt_3(exc, exc_offset + i_subfr, t0.value, t0_frac.value, L_SUBFR); - - /*-------------------------------------------------------* - * - Decode innovative codebook. * - * - Add the fixed-gain pitch contribution to code[]. * - *-------------------------------------------------------*/ - - if(bfi != 0) { /* Bad Frame Error Concealment */ - parm[parm_offset + 0] = (Util.random_g729() & 0x1fff); /* 13 bits random*/ - parm[parm_offset + 1]= (Util.random_g729() & 0x000f); /* 4 bits random */ - } - - DeAcelp.decod_ACELP(parm[parm_offset + 1], parm[parm_offset + 0], code); - parm_offset +=2; - for (i = t0.value; i < L_SUBFR; i++) code[i] += sharp * code[i-t0.value]; - - /*-------------------------------------------------* - * - Decode pitch and codebook gains. * - *-------------------------------------------------*/ - - index = parm[parm_offset]; /* index of energy VQ */ - parm_offset++; - decGain.dec_gain(index, code, L_SUBFR, bfi, gain_pitch, gain_code); - - /*-------------------------------------------------------------* - * - Update pitch sharpening "sharp" with quantized gain_pitch * - *-------------------------------------------------------------*/ - - sharp = gain_pitch.value; - if (sharp > SHARPMAX) sharp = SHARPMAX; - if (sharp < SHARPMIN) sharp = SHARPMIN; - - /*-------------------------------------------------------* - * - Find the total excitation. * - *-------------------------------------------------------*/ - - if(bfi != 0 ) { - if(voicing == 0) { /* for unvoiced frame */ - for (i = 0; i < L_SUBFR; i++) { - exc[exc_offset + i+i_subfr] = gain_code.value*code[i]; - } - } else { /* for voiced frame */ - for (i = 0; i < L_SUBFR; i++) { - exc[exc_offset + i+i_subfr] = gain_pitch.value*exc[exc_offset + i+i_subfr]; - } - } - } else { /* No frame errors */ - for (i = 0; i < L_SUBFR; i++) { - exc[exc_offset + i+i_subfr] = gain_pitch.value*exc[exc_offset + i+i_subfr] + gain_code.value*code[i]; - } - } - - /*-------------------------------------------------------* - * - Find synthesis speech corresponding to exc[]. * - *-------------------------------------------------------*/ - - Filter.syn_filt(Az, Az_offset, exc, exc_offset + i_subfr, synth, synth_offset + i_subfr, L_SUBFR, mem_syn, 0, 1); - - Az_offset += MP1; /* interpolated LPC parameters for next subframe */ - } - - /*--------------------------------------------------* - * Update signal for next frame. * - * -> shift to the left by L_FRAME exc[] * - *--------------------------------------------------*/ - Util.copy(old_exc, L_FRAME, old_exc, PIT_MAX+L_INTERPOL); - return t0_first; -} -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Decoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Decoder.java deleted file mode 100644 index fa085d737..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Decoder.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -import java.io.*; - -/** - * Main program of the G.729 8.0 kbit/s decoder. - * Usage : decoder bitstream_file synth_file. - * - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class Decoder - extends Ld8k -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : DECODER.C - Used for the floating point version of G.729 main body - (not for G.729A) -*/ - - /** - * DecLd8k reference - */ - private final DecLd8k decLd8k = new DecLd8k(); - - /** - * Postfil reference - */ - private final Postfil postfil = new Postfil(); - - /** - * PostPro reference - */ - private final PostPro postPro = new PostPro(); - /** - * Synthesis - */ - private final float[] synth_buf = new float[L_FRAME+M]; - - /** - * Synthesis - */ - private final float[] synth; - - - /** - * Synthesis - */ - private int synth_offset; - - /** - * Synthesis parameters + BFI - */ - private final int[] parm = new int[PRM_SIZE+1]; - - /** - * Synthesis parameters + BFI - */ - private final float[] Az_dec = new float[2*MP1]; - - /** - * postfilter output - */ - private final float[] pst_out = new float[L_FRAME]; - - /** - * voicing for previous subframe - */ - private int voicing; - - /** - * Initialization of decoder - */ - Decoder() - { - - synth = synth_buf; - synth_offset = M; - - decLd8k.init_decod_ld8k(); - postfil.init_post_filter(); - postPro.init_post_process(); - - voicing = 60; - } - - /** - * Converts floats array into shorts array. - * - * @param floats - * @param shorts - */ - private static void floats2shorts(float[] floats, short[] shorts) - { - for (int i = 0; i < floats.length; i++) - { - /* round and convert to int */ - float f = floats[i]; - if (f >= 0.0f) - f += 0.5f; - else - f -= 0.5f; - if (f > 32767.0f) - f = 32767.0f; - if (f < -32768.0f) - f = -32768.0f; - shorts[i] = (short) f; - } - } - -/** - * Main decoder routine - * Usage :Decoder bitstream_file outputspeech_file - * - * Format for bitstream_file: - * One (2-byte) synchronization word - * One (2-byte) size word, - * 80 words (2-byte) containing 80 bits. - * - * Format for outputspeech_file: - * Synthesis is written to a binary file of 16 bits data. - * - * @param args bitstream_file outputspeech_file - * @throws java.io.IOException - */ -public static void main(String[] args) - throws IOException -{ - OutputStream f_syn; - InputStream f_serial; - - short[] serial = new short[SERIAL_SIZE]; /* Serial stream */ - short[] sp16 = new short[L_FRAME]; /* Buffer to write 16 bits speech */ - - int frame; - - System.out.printf("\n"); - System.out.printf("************** G.729 8 KBIT/S SPEECH DECODER ************\n"); - System.out.printf("\n"); - System.out.printf("----------------- Floating point C simulation ----------------\n"); - System.out.printf("\n"); - System.out.printf("------------ Version 1.01 (Release 2, November 2006) --------\n"); - System.out.printf("\n"); - - /* Passed arguments */ - - if ( args.length != 2) - { - System.out.printf("Usage :Decoder bitstream_file outputspeech_file\n"); - System.out.printf("\n"); - System.out.printf("Format for bitstream_file:\n"); - System.out.printf(" One (2-byte) synchronization word \n"); - System.out.printf(" One (2-byte) size word,\n"); - System.out.printf(" 80 words (2-byte) containing 80 bits.\n"); - System.out.printf("\n"); - System.out.printf("Format for outputspeech_file:\n"); - System.out.printf(" Synthesis is written to a binary file of 16 bits data.\n"); - System.exit( 1 ); - } - - /* Open file for synthesis and packed serial stream */ - - try - { - f_serial = new FileInputStream(args[0]); - } - catch (IOException ex) - { - System.out.printf("Decoder - Error opening file %s !!\n", args[0]); - System.exit(0); - throw ex; // Silence the compiler. - } - - try - { - f_syn = new FileOutputStream(args[1]); - } - catch (IOException ex) - { - System.out.printf("Decoder - Error opening file %s !!\n", args[1]); - System.exit(0); - throw ex; // Silence the compiler. - } - - System.out.printf("Input bitstream file : %s\n",args[0]); - System.out.printf("Synthesis speech file : %s\n",args[1]); - -/*-----------------------------------------------------------------* - * Initialization of decoder * - *-----------------------------------------------------------------*/ - - Decoder decoder = new Decoder(); - -/*-----------------------------------------------------------------* - * Loop for each "L_FRAME" speech data * - *-----------------------------------------------------------------*/ - - frame =0; - while(Util.fread(serial, SERIAL_SIZE, f_serial) == SERIAL_SIZE) - { - frame++; - System.out.printf(" Frame: %d\r", frame); - - decoder.process(serial, sp16); - - Util.fwrite(sp16, L_FRAME, f_syn); - } - - f_syn.close(); - f_serial.close(); -} - - /** - * Process SERIAL_SIZE short of speech. - * - * @param serial input : serial array encoded in bits_ld8k - * @param sp16 output : speech short array - */ - void process(short[] serial, short[] sp16) - { - Bits.bits2prm_ld8k(serial, 2, parm, 1); - - /* the hardware detects frame erasures by checking if all bits - are set to zero - */ - parm[0] = 0; /* No frame erasure */ - for (int i=2; i < SERIAL_SIZE; i++) - if (serial[i] == 0 ) parm[0] = 1; /* frame erased */ - - /* check parity and put 1 in parm[4] if parity error */ - - parm[4] = PParity.check_parity_pitch(parm[3], parm[4] ); - - int t0_first = decLd8k.decod_ld8k(parm, voicing, synth, synth_offset, Az_dec); /* Decoder */ - - /* Post-filter and decision on voicing parameter */ - voicing = 0; - - float[] ptr_Az = Az_dec; /* Decoded Az for post-filter */ - int ptr_Az_offset = 0; - - for(int i=0; iSIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * General filter routines. - * - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class Filter -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : FILTER.C - Used for the floating point version of both - G.729 main body and G.729A -*/ - -/** - * Convolve vectors x and h and put result in y. - * - * @param x input : input vector x[0:l] - * @param x_offset input : input vector offset - * @param h input : impulse response or second input h[0:l] - * @param y output: x convolved with h , y[0:l] - * @param l input : dimension of all vectors - */ -static void convolve( - float x[], - int x_offset, - float h[], - float y[], - int l -) -{ - float temp; - int i, n; - - for (n = 0; n < l; n++) - { - temp = 0.0f; - for (i = 0; i <= n; i++) - temp += x[x_offset + i]*h[n-i]; - y[n] = temp; - } -} - -/** - * Filter with synthesis filter 1/A(z). - * - * @param a input : predictor coefficients a[0:m] - * @param a_offset input : predictor coefficients a offset - * @param x input : excitation signal - * @param x_offset input : excitation signal offset - * @param y output: filtered output signal - * @param y_offset output: filtered output signal offset - * @param l input : vector dimension - * @param mem in/out: filter memory - * @param mem_offset input : filter memory ofset - * @param update input : 0 = no memory update, 1 = update - */ -static void syn_filt( - float a[], - int a_offset, - float x[], - int x_offset, - float y[], - int y_offset, - int l, - float mem[], - int mem_offset, - int update -) -{ - int L_SUBFR = Ld8k.L_SUBFR; - int M = Ld8k.M; - - int i,j; - - /* This is usually done by memory allocation (l+m) */ - float[] yy_b = new float[L_SUBFR+M]; - float s; - int yy, py, pa; - /* Copy mem[] to yy[] */ - yy = 0; //index instead of pointer - for (i = 0; i SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class Gainpred -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : GAINPRED.C - Used for the floating point version of both - G.729 main body and G.729A -*/ - -/** - * MA prediction is performed on the innovation energy (in dB with mean - * removed). - * - * @param past_qua_en (i) :Past quantized energies - * @param code (i) :Innovative vector. - * @param l_subfr (i) :Subframe length. - * @return Predicted codebook gain - */ -static float gain_predict( - float past_qua_en[], - float code[], - int l_subfr -) -{ - float MEAN_ENER = Ld8k.MEAN_ENER; - float[] pred = TabLd8k.pred; - - float ener_code, pred_code; - int i; - float gcode0; /* (o) :Predicted codebook gain */ - - pred_code = MEAN_ENER ; - - /* innovation energy */ - ener_code = 0.01f; - for(i=0; i 0; i--) - past_qua_en[i] = past_qua_en[i-1]; - past_qua_en[0] = 20.0f*(float)Math.log10((double)g_code); -} - -/** - * Update table of past quantized energies (frame erasure). - *
- *     av_pred_en = 0.0;                                                     
- *     for (i = 0; i < 4; i++)                                               
- *        av_pred_en += past_qua_en[i];                                      
- *     av_pred_en = av_pred_en*0.25 - 4.0;                                   
- *     if (av_pred_en < -14.0) av_pred_en = -14.0; 
- * 
- * - * @param past_qua_en input/output:Past quantized energies - */ -static void gain_update_erasure( - float past_qua_en[] -) -{ - int i; - float av_pred_en; - - av_pred_en = 0.0f; - for (i = 0; i < 4; i++) - av_pred_en += past_qua_en[i]; - av_pred_en = av_pred_en*0.25f - 4.0f; - if (av_pred_en < -14.0f) av_pred_en = -14.0f; - - for (i = 3; i > 0; i--) - past_qua_en[i] = past_qua_en[i-1]; - past_qua_en[0] = av_pred_en; -} - -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/IntReference.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/IntReference.java deleted file mode 100644 index dc35aeca2..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/IntReference.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * @author Lubomir Marinov - */ -class IntReference -{ - int value; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/JavaDecoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/JavaDecoder.java deleted file mode 100644 index c19fd02ff..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/JavaDecoder.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.sf.fmj.media.*; - -/** - * @author Lubomir Marinov - */ -public class JavaDecoder - extends AbstractCodecExt -{ - private static final short BIT_0 = Ld8k.BIT_0; - - private static final short BIT_1 = Ld8k.BIT_1; - - private static final int L_FRAME = Ld8k.L_FRAME; - - private static final int SERIAL_SIZE = Ld8k.SERIAL_SIZE; - - private static final short SIZE_WORD = Ld8k.SIZE_WORD; - - private static final short SYNC_WORD = Ld8k.SYNC_WORD; - - private static final int INPUT_FRAME_SIZE_IN_BYTES = L_FRAME / 8; - - private static final int OUTPUT_FRAME_SIZE_IN_BYTES = 2 * L_FRAME; - - private Decoder decoder; - - private short[] serial; - - private short[] sp16; - - /** - * Initializes a new JavaDecoder instance. - */ - public JavaDecoder() - { - super( - "G.729 Decoder", - AudioFormat.class, - new AudioFormat[] - { - new AudioFormat( - AudioFormat.LINEAR, - 8000, - 16, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED) - }); - - inputFormats - = new AudioFormat[] - { - new AudioFormat( - AudioFormat.G729_RTP, - 8000, - AudioFormat.NOT_SPECIFIED, - 1) - }; - } - - private void depacketize( - byte[] inputFrame, - int inputFrameOffset, - short[] serial) - { - serial[0] = SYNC_WORD; - serial[1] = SIZE_WORD; - for (int s = 0; s < L_FRAME; s++) - { - int input = inputFrame[inputFrameOffset + s / 8]; - - input &= 1 << (7 - (s % 8)); - serial[2 + s] = (0 != input) ? BIT_1 : BIT_0; - } - } - - /* - * Implements AbstractCodecExt#doClose(). - */ - protected void doClose() - { - serial = null; - sp16 = null; - decoder = null; - } - - /** - * Opens this Codec and acquires the resources that it needs to - * operate. A call to {@link PlugIn#open()} on this instance will result in - * a call to doOpen only if {@link AbstractCodec#opened} is - * false. All required input and/or output formats are assumed to - * have been set on this Codec before doOpen is called. - * - * @throws ResourceUnavailableException if any of the resources that this - * Codec needs to operate cannot be acquired - * @see AbstractCodecExt#doOpen() - */ - protected void doOpen() - throws ResourceUnavailableException - { - serial = new short[SERIAL_SIZE]; - sp16 = new short[L_FRAME]; - decoder = new Decoder(); - } - - /* - * Implements AbstractCodecExt#doProcess(Buffer, Buffer). - */ - protected int doProcess(Buffer inputBuffer, Buffer outputBuffer) - { - byte[] input = (byte[]) inputBuffer.getData(); - - int inputLength = inputBuffer.getLength(); - - if (inputLength < INPUT_FRAME_SIZE_IN_BYTES) - { - discardOutputBuffer(outputBuffer); - return BUFFER_PROCESSED_OK | OUTPUT_BUFFER_NOT_FILLED; - } - - int inputOffset = inputBuffer.getOffset(); - - depacketize(input, inputOffset, serial); - inputLength -= INPUT_FRAME_SIZE_IN_BYTES; - inputBuffer.setLength(inputLength); - inputOffset += INPUT_FRAME_SIZE_IN_BYTES; - inputBuffer.setOffset(inputOffset); - - decoder.process(serial, sp16); - - byte[] output - = validateByteArraySize( - outputBuffer, - outputBuffer.getOffset() + OUTPUT_FRAME_SIZE_IN_BYTES); - - writeShorts(sp16, output, outputBuffer.getOffset()); - outputBuffer.setLength(OUTPUT_FRAME_SIZE_IN_BYTES); - - int processResult = BUFFER_PROCESSED_OK; - - if (inputLength > 0) - processResult |= INPUT_BUFFER_NOT_CONSUMED; - return processResult; - } - - private static void writeShorts( - short[] input, - byte[] output, - int outputOffset) - { - for (int i=0, o=outputOffset; iBuffer
produced by this Codec - * in nanosecond. We packetize 2 audio frames in one G729 packet. - */ - private int duration = OUTPUT_FRAME_SIZE_IN_BYTES * 2 * 1000000; - - /** - * Initializes a new JavaEncoder instance. - */ - public JavaEncoder() - { - super( - "G.729 Encoder", - AudioFormat.class, - new AudioFormat[] - { - new AudioFormat( - AudioFormat.G729_RTP, - 8000, - AudioFormat.NOT_SPECIFIED, - 1) - }); - - inputFormats - = new AudioFormat[] - { - new AudioFormat( - AudioFormat.LINEAR, - 8000, - 16, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED) - }; - } - - /** - * Get the output format. - * - * @return output format - * @see net.sf.fmj.media.AbstractCodec#getOutputFormat() - */ - @Override - public Format getOutputFormat() - { - Format outputFormat = super.getOutputFormat(); - - if ((outputFormat != null) - && (outputFormat.getClass() == AudioFormat.class)) - { - AudioFormat outputAudioFormat = (AudioFormat) outputFormat; - - outputFormat = setOutputFormat( - new AudioFormat( - outputAudioFormat.getEncoding(), - outputAudioFormat.getSampleRate(), - outputAudioFormat.getSampleSizeInBits(), - outputAudioFormat.getChannels(), - outputAudioFormat.getEndian(), - outputAudioFormat.getSigned(), - outputAudioFormat.getFrameSizeInBits(), - outputAudioFormat.getFrameRate(), - outputAudioFormat.getDataType()) - { - private static final long serialVersionUID = 0L; - - @Override - public long computeDuration(long length) - { - return JavaEncoder.this.duration; - } - }); - } - return outputFormat; - } - - protected void discardOutputBuffer(Buffer outputBuffer) - { - super.discardOutputBuffer(outputBuffer); - - outputFrameCount = 0; - } - - /* - * Implements AbstractCodecExt#doClose(). - */ - protected void doClose() - { - prevInput = null; - prevInputLength = 0; - - sp16 = null; - serial = null; - coder = null; - } - - /** - * Opens this Codec and acquires the resources that it needs to - * operate. A call to {@link PlugIn#open()} on this instance will result in - * a call to doOpen only if {@link AbstractCodec#opened} is - * false. All required input and/or output formats are assumed to - * have been set on this Codec before doOpen is called. - * - * @throws ResourceUnavailableException if any of the resources that this - * Codec needs to operate cannot be acquired - * @see AbstractCodecExt#doOpen() - */ - protected void doOpen() - throws ResourceUnavailableException - { - prevInput = new byte[INPUT_FRAME_SIZE_IN_BYTES]; - prevInputLength = 0; - - sp16 = new short[L_FRAME]; - serial = new short[SERIAL_SIZE]; - coder = new Coder(); - - outputFrameCount = 0; - } - - /* - * Implements AbstractCodecExt#doProcess(Buffer, Buffer). - */ - protected int doProcess(Buffer inputBuffer, Buffer outputBuffer) - { - byte[] input = (byte[]) inputBuffer.getData(); - - int inputLength = inputBuffer.getLength(); - int inputOffset = inputBuffer.getOffset(); - - if ((prevInputLength + inputLength) < INPUT_FRAME_SIZE_IN_BYTES) - { - System.arraycopy( - input, - inputOffset, - prevInput, - prevInputLength, - inputLength); - prevInputLength += inputLength; - return BUFFER_PROCESSED_OK | OUTPUT_BUFFER_NOT_FILLED; - } - - int readShorts = 0; - - if (prevInputLength > 0) - { - readShorts - += readShorts(prevInput, 0, sp16, 0, prevInputLength / 2); - prevInputLength = 0; - } - readShorts - = readShorts( - input, - inputOffset, - sp16, - readShorts, - sp16.length - readShorts); - - int readBytes = 2 * readShorts; - - inputLength -= readBytes; - inputBuffer.setLength(inputLength); - inputOffset += readBytes; - inputBuffer.setOffset(inputOffset); - - coder.process(sp16, serial); - - byte[] output - = validateByteArraySize( - outputBuffer, - outputBuffer.getOffset() + 2 * OUTPUT_FRAME_SIZE_IN_BYTES); - - packetize( - serial, - output, - outputBuffer.getOffset() - + OUTPUT_FRAME_SIZE_IN_BYTES * outputFrameCount); - outputBuffer.setLength( - outputBuffer.getLength() + OUTPUT_FRAME_SIZE_IN_BYTES); - - outputBuffer.setFormat(outputFormat); - - int processResult = BUFFER_PROCESSED_OK; - - if (outputFrameCount == 1) - outputFrameCount = 0; - else - { - outputFrameCount = 1; - processResult |= OUTPUT_BUFFER_NOT_FILLED; - } - if (inputLength > 0) - processResult |= INPUT_BUFFER_NOT_CONSUMED; - - if(processResult == BUFFER_PROCESSED_OK) - { - updateOutput( - outputBuffer, - getOutputFormat(), outputBuffer.getLength(), - outputBuffer.getOffset()); - outputBuffer.setDuration(duration); - } - return processResult; - } - - private void packetize( - short[] serial, - byte[] outputFrame, - int outputFrameOffset) - { - Arrays.fill( - outputFrame, - outputFrameOffset, - outputFrameOffset + L_FRAME / 8, - (byte) 0); - - for (int s = 0; s < L_FRAME; s++) - if (BIT_1 == serial[2 + s]) - { - int o = outputFrameOffset + s / 8; - int output = outputFrame[o]; - - output |= 1 << (7 - (s % 8)); - outputFrame[o] = (byte) (output & 0xFF); - } - } - - private static int readShorts( - byte[] input, - int inputOffset, - short[] output, - int outputOffset, - int outputLength) - { - for (int o=outputOffset, i=inputOffset; oSIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class Ld8k -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : LD8K.H - Used for the floating point version of G.729 main body - (not for G.729A) -*/ - - -/*--------------------------------------------------------------------------- - * ld8k.h - include file for all ITU-T 8 kb/s CELP coder routines - *--------------------------------------------------------------------------- - */ - -static final float PI = 3.14159265358979323846f; -/** - * Largest floating point number - */ -static final float FLT_MAX_G729 = 1.e38f; -/** - * Largest floating point number - */ -static final float FLT_MIN_G729 = -FLT_MAX_G729; - -/** - * Total size of speech buffer - */ -static final int L_TOTAL = 240; -/** - * LPC update frame size - */ -static final int L_FRAME = 80; -/** - * Sub-frame size - */ -static final int L_SUBFR = 40; - -/*---------------------------------------------------------------------------* - * Constants for bitstream packing * - *---------------------------------------------------------------------------*/ -/** - * Definition of one-bit in bit-stream. - */ -static final short BIT_1 = 0x0081; -/** - * Definition of zero-bit in bit-stream. - */ -static final short BIT_0 = 0x007f; -/** - * Definition of frame erasure flag. - */ -static final short SYNC_WORD = 0x6b21; -/** - * Size of bitstream frame. - */ -static final short SIZE_WORD = 80; -/** - * Number of parameters per 10 ms frame. - */ -static final int PRM_SIZE = 11; -/** - * Bits per frame. - */ -static final int SERIAL_SIZE = 82; - -/*---------------------------------------------------------------------------* - * Constants for lpc analysis and lsp quantizer. * - *---------------------------------------------------------------------------*/ -/** - * LPC analysis window size. - */ -static final int L_WINDOW = 240; -/** - * Samples of next frame needed for LPC ana. - */ -static final int L_NEXT = 40; - -/** - * LPC order. - */ -static final int M = 10; -/** - * LPC order+1. - */ -static final int MP1 = (M+1); -/** - * Resolution of lsp search. - */ -static final int GRID_POINTS = 60; - -/** - * MA prediction order for LSP. - */ -static final int MA_NP = 4; -/** - * Number of modes for MA prediction. - */ -static final int MODE = 2; -/** - * Number of bits in first stage. - */ -static final int NC0_B = 7; -/** - * Number of entries in first stage. - */ -static final int NC0 = (1<0 - */ -static final float GAMMA3_PLUS = 0.2f; -/** - * tilt weighting factor when k1<0 - */ -static final float GAMMA3_MINUS = 0.9f; - -/* long term pst parameters : */ -/** - * Sub-frame size + 1 - */ -static final int L_SUBFRP1 = (L_SUBFR + 1); -/** - * resolution for fractionnal delay - */ -static final int F_UP_PST = 8; -/** - * length of short interp. subfilters - */ -static final int LH2_S = 4; -/** - * length of long interp. subfilters - */ -static final int LH2_L = 16; -/** - * threshold LT pst switch off - */ -static final float THRESCRIT = 0.5f; -/** - * LT weighting factor - */ -static final float GAMMA_G = 0.5f; -/** - * gain adjustment factor - */ -static final float AGC_FAC = 0.9875f; -/** - * gain adjustment factor - */ -static final float AGC_FAC1 = (1.f - AGC_FAC); -static final int LH_UP_S = (LH2_S/2); -static final int LH_UP_L = (LH2_L/2); -static final int LH2_L_P1 = (LH2_L + 1); -/** - * LT gain minimum - */ -static final float MIN_GPLT = (1.f / (1.f + GAMMA_G)); - -/* Array sizes */ -static final int MEM_RES2 = (PIT_MAX + 1 + LH_UP_L); -static final int SIZ_RES2 = (MEM_RES2 + L_SUBFR); -static final int SIZ_Y_UP = ((F_UP_PST-1) * L_SUBFRP1); -static final int SIZ_TAB_HUP_L = ((F_UP_PST-1) * LH2_L); -static final int SIZ_TAB_HUP_S = ((F_UP_PST-1) * LH2_S); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Lpc.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Lpc.java deleted file mode 100644 index 8f4eb6b13..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Lpc.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * Lpc analysis routines. - * NOTE: these routines are assuming that the order is defined as M - * and that NC is defined as M/2. M has to be even - * - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class Lpc -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : LPC.C - Used for the floating point version of G.729 main body - (not for G.729A) -*/ - - - -/** - * Compute the auto-correlations of windowed speech signal - * - * @param x (i) input signal x[0:L_WINDOW] - * @param x_offset (i) input signal offset - * @param m (i) LPC order - * @param r (o) auto-correlation vector r[0:M] - */ -static void autocorr( - float[] x, - int x_offset, - int m, - float[] r -) -{ - int L_WINDOW = Ld8k.L_WINDOW; - float[] hamwindow = TabLd8k.hamwindow; - - float[] y = new float[L_WINDOW]; - float sum; - int i, j; - - - for (i = 0; i < L_WINDOW; i++) - y[i] = x[x_offset + i]*hamwindow[i]; - - for (i = 0; i <= m; i++) - { - sum = 0.0f; - for (j = 0; j < L_WINDOW-i; j++) - sum += y[j]*y[j+i]; - r[i] = sum; - } - if (r[0]<1.0f) r[0]=1.0f; -} - -/** - * Lag windowing of the autocorrelations - * - * @param m (i) LPC order - * @param r (i/o) correlation - */ -static void lag_window( - int m, - float r[] -) -{ - float[] lwindow = TabLd8k.lwindow; - - int i; - - for (i=1; i<= m; i++) - r[i] *= lwindow[i-1]; -} - -/** - * Levinson-Durbin recursion to compute LPC parameters. - * - * @param r (i) auto correlation coefficients r[0:M] - * @param a (o) lpc coefficients a[0] = 1 - * @param a_offset (i) lpc coefficients offset - * @param rc (o) reflection coefficients rc[0:M-1] - * @return prediction error (energy) - */ -static float levinson( - float[] r, - float[] a, - int a_offset, - float[] rc -) -{ - int M = Ld8k.M; - - float s, at, err; - int i, j, l; - - rc[0] = (-r[1])/r[0]; - a[a_offset + 0] = 1.0f; - a[a_offset + 1] = rc[0]; - err = r[0] + r[1]*rc[0]; - for (i = 2; i <= M; i++) - { - s = 0.0f; - for (j = 0; j < i; j++) - s += r[i-j]*a[a_offset + j]; - rc[i-1]= (-s)/(err); - for (j = 1; j <= (i/2); j++) - { - l = i-j; - at = a[a_offset + j] + rc[i-1]*a[a_offset + l]; - a[a_offset + l] += rc[i-1]*a[a_offset + j]; - a[a_offset + j] = at; - } - a[a_offset + i] = rc[i-1]; - err += rc[i-1]*s; - if (err <= 0.0f) - err = 0.001f; - } - return (err); -} - -/** * - * Compute the LSPs from the LP coefficients a[] using Chebyshev - * polynomials. The found LSPs are in the cosine domain with values - * in the range from 1 down to -1. - * The table grid[] contains the points (in the cosine domain) at - * which the polynomials are evaluated. The table corresponds to - * NO_POINTS frequencies uniformly spaced between 0 and pi. - * - * @param a (i) LP filter coefficients - * @param a_offset (i) LP filter coefficients offset - * @param lsp (o) Line spectral pairs (in the cosine domain) - * @param old_lsp (i) LSP vector from past frame - */ -static void az_lsp( - float[] a, - int a_offset, - float[] lsp, - float[] old_lsp -) -{ - int GRID_POINTS = Ld8k.GRID_POINTS; - int M = Ld8k.M; - int NC = Ld8k.NC; - float[] grid = TabLd8k.grid; - - int i, j, nf, ip; - float xlow,ylow,xhigh,yhigh,xmid,ymid,xint; - float[] coef; - - float[] f1 = new float[NC+1], f2 = new float[NC+1]; - - /*-------------------------------------------------------------* - * find the sum and diff polynomials F1(z) and F2(z) * - * F1(z) = [A(z) + z^11 A(z^-1)]/(1+z^-1) * - * F2(z) = [A(z) - z^11 A(z^-1)]/(1-z^-1) * - *-------------------------------------------------------------*/ - - f1[0] = 1.0f; - f2[0] = 1.0f; - for (i=1, j=a_offset+M; i<=NC; i++, j--){ - float ai = a[a_offset + i]; - float aj = a[j]; - f1[i] = ai+aj-f1[i-1]; - f2[i] = ai-aj+f2[i-1]; - } - - /*---------------------------------------------------------------------* - * Find the LSPs (roots of F1(z) and F2(z) ) using the * - * Chebyshev polynomial evaluation. * - * The roots of F1(z) and F2(z) are alternatively searched. * - * We start by finding the first root of F1(z) then we switch * - * to F2(z) then back to F1(z) and so on until all roots are found. * - * * - * - Evaluate Chebyshev pol. at grid points and check for sign change.* - * - If sign change track the root by subdividing the interval * - * NO_ITER times and ckecking sign change. * - *---------------------------------------------------------------------*/ - - nf=0; /* number of found frequencies */ - ip=0; /* flag to first polynomial */ - - coef = f1; /* start with F1(z) */ - - xlow=grid[0]; - ylow = chebyshev(xlow,coef,NC); - - j = 0; - while ( (nf < M) && (j < GRID_POINTS) ) - { - j++; - xhigh = xlow; - yhigh = ylow; - xlow = grid[j]; - ylow = chebyshev(xlow,coef,NC); - - if (ylow*yhigh <= 0.0f) /* if sign change new root exists */ - { - j--; - - /* divide the interval of sign change by 4 */ - - for (i = 0; i < 4; i++) - { - xmid = 0.5f*(xlow + xhigh); - ymid = chebyshev(xmid,coef,NC); - if (ylow*ymid <= 0.0f) - { - yhigh = ymid; - xhigh = xmid; - } - else - { - ylow = ymid; - xlow = xmid; - } - } - - /* linear interpolation for evaluating the root */ - - xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow); - - lsp[nf] = xint; /* new root */ - nf++; - - ip = 1 - ip; /* flag to other polynomial */ - coef = (ip != 0) ? f2 : f1; /* pointer to other polynomial */ - - xlow = xint; - ylow = chebyshev(xlow,coef,NC); - } - } - - /* Check if M roots found */ - /* if not use the LSPs from previous frame */ - - if ( nf < M) - for(i=0; iSIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class Lpcfunc -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - - -/* - File : LPCFUNC.C - Used for the floating point version of G.729 main body - (not for G.729A) -*/ - -/** - * Convert LSPs to predictor coefficients a[] - * - * @param lsp input : lsp[0:M-1] - * @param a output: predictor coeffs a[0:M], a[0] = 1. - * @param a_offset input: predictor coeffs a offset. - */ -private static void lsp_az( - float[] lsp, - float[] a, - int a_offset -) -{ - int M = Ld8k.M; - int NC = Ld8k.NC; - - float[] f1 = new float[NC+1], f2 = new float[NC+1]; - int i,j; - - - get_lsp_pol(lsp, 0,f1); - get_lsp_pol(lsp, 1,f2); - - for (i = NC; i > 0; i--) - { - f1[i] += f1[i-1]; - f2[i] -= f2[i-1]; - } - a[a_offset + 0] = 1.0f; - for (i = 1, j = M; i <= NC; i++, j--) - { - a[a_offset + i] = 0.5f*(f1[i] + f2[i]); - a[a_offset + j] = 0.5f*(f1[i] - f2[i]); - } -} - - -/** - * Find the polynomial F1(z) or F2(z) from the LSFs - * - * @param lsp input : line spectral freq. (cosine domain) - * @param lsp_offset input : line spectral freq offset - * @param f output: the coefficients of F1 or F2 - */ -private static void get_lsp_pol( - float lsp[], - int lsp_offset, - float f[] -) -{ - int NC = Ld8k.NC; - - float b; - int i,j; - - f[0] = 1.0f; - b = -2.0f*lsp[lsp_offset + 0]; - f[1] = b; - for (i = 2; i <= NC; i++) - { - b = -2.0f*lsp[lsp_offset + 2*i-2]; - f[i] = b*f[i-1] + 2.0f*f[i-2]; - for (j = i-1; j > 1; j--) - f[j] += b*f[j-1] + f[j-2]; - f[1] += b; - } -} - -/** - * Convert from lsf[0..M-1 to lsp[0..M-1] - * - * @param lsf input : lsf - * @param lsp output: lsp - * @param m input : length - */ -static void lsf_lsp( - float lsf[], - float lsp[], - int m -) -{ - int i; - for ( i = 0; i < m; i++ ) - lsp[i] = (float)Math.cos((double)lsf[i]); -} - -/** - * Convert from lsp[0..M-1 to lsf[0..M-1] - * - * @param lsp input : lsp coefficients - * @param lsf output: lsf (normalized frequencies - * @param m input: length - */ -static void lsp_lsf( - float lsp[], - float lsf[], - int m -) -{ - int i; - - for ( i = 0; i < m; i++ ) - lsf[i] = (float)Math.acos((double)lsp[i]); -} - - -/** - * Weighting of LPC coefficients ap[i] = a[i] * (gamma ** i) - * - * @param a input : lpc coefficients a[0:m] - * @param a_offset input : lpc coefficients offset - * @param gamma input : weighting factor - * @param m input : filter order - * @param ap output: weighted coefficients ap[0:m] - */ -static void weight_az( - float[] a, - int a_offset, - float gamma, - int m, - float[] ap -) -{ - float fac; - int i; - - ap[0] = a[a_offset + 0]; - fac = gamma; - for (i = 1; i SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class Lspdec -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : LSPDEC.C - Used for the floating point version of both - G.729 main body and G.729A -*/ - -private static final int M = Ld8k.M; -private static final int MA_NP = Ld8k.MA_NP; - -/* static memory */ -/** - * Previous LSP vector - */ -private final float[][] freq_prev = new float[MA_NP][M]; -/** - * Previous LSP vector(init) - */ -private static final float[/* M */] FREQ_PREV_RESET = { - 0.285599f, 0.571199f, 0.856798f, 1.142397f, 1.427997f, - 1.713596f, 1.999195f, 2.284795f, 2.570394f, 2.855993f -}; /* PI*(float)(j+1)/(float)(M+1) */ - -/* static memory for frame erase operation */ -/** - * Previous MA prediction coef - */ -private int prev_ma; -/** - * Previous LSP vector - */ -private final float[] prev_lsp = new float[M]; - - -/** - * Set the previous LSP vectors. - */ -void lsp_decw_reset() -{ - int i; - - for(i=0; i>> NC0_B) & 1; - code0 = prm[prm_offset + 0] & (short)(NC0 - 1); - code1 = (prm[prm_offset + 1] >>> NC1_B) & (short)(NC1 - 1); - code2 = prm[prm_offset + 1] & (short)(NC1 - 1); - - Lspgetq.lsp_get_quant(lspcb1, lspcb2, code0, code1, code2, fg[mode_index], - freq_prev, lsp_q, fg_sum[mode_index]); - - Util.copy(lsp_q, prev_lsp, M ); - prev_ma = mode_index; - } - else /* Frame erased */ - { - Util.copy(prev_lsp, lsp_q, M ); - - /* update freq_prev */ - Lspgetq.lsp_prev_extract(prev_lsp, buf, - fg[prev_ma], freq_prev, fg_sum_inv[prev_ma]); - Lspgetq.lsp_prev_update(buf, freq_prev); - } -} - -/** - * Decode lsp parameters - * - * @param index input : indexes - * @param index_offset input : indexes offset - * @param lsp_q output: decoded lsp - * @param bfi input : frame erase information - */ -void d_lsp( - int index[], - int index_offset, - float lsp_q[], - int bfi -) -{ - int i; - - lsp_iqua_cs(index, index_offset, lsp_q,bfi); /* decode quantized information */ - - /* Convert LSFs to LSPs */ - - for (i=0; iSIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class Lspgetq -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : LSPGETQ.C - Used for the floating point version of both - G.729 main body and G.729A -*/ - -/** - * Reconstruct quantized LSP parameter and check the stabilty - * - * @param lspcb1 input : first stage LSP codebook - * @param lspcb2 input : Second stage LSP codebook - * @param code0 input : selected code of first stage - * @param code1 input : selected code of second stage - * @param code2 input : selected code of second stage - * @param fg input : MA prediction coef. - * @param freq_prev input : previous LSP vector - * @param lspq output: quantized LSP parameters - * @param fg_sum input : present MA prediction coef. - */ -static void lsp_get_quant( - float lspcb1[][/* M */], - float lspcb2[][/* M */], - int code0, - int code1, - int code2, - float fg[][/* M */], - float freq_prev[][/* M */], - float lspq[], - float fg_sum[] -) -{ - float GAP1 = Ld8k.GAP1; - float GAP2 = Ld8k.GAP2; - int M = Ld8k.M; - int NC = Ld8k.NC; - - int j; - float[] buf = new float[M]; - - - for(j=0; j 0) { - buf[j-1] -= tmp; - buf[j] += tmp; - } - } -} - -/** - * Check for higher (5-9) - * - * @param buf in/out: lsp vectors - * @param gap input : gap - */ -static void lsp_expand_2( - float buf[], - float gap -) -{ - int M = Ld8k.M; - int NC = Ld8k.NC; - - int j; - float diff, tmp; - - for(j=NC; j 0) { - buf[j-1] -= tmp; - buf[j] += tmp; - } - } -} - -/** - * - * @param buf in/out: LSP parameters - * @param gap input: gap - */ -static void lsp_expand_1_2( - float buf[], - float gap -) -{ - int M = Ld8k.M; - - int j; - float diff, tmp; - - for(j=1; j 0) { - buf[j-1] -= tmp; - buf[j] += tmp; - } - } -} - - - -/* - Functions which use previous LSP parameter (freq_prev). -*/ - - -/** - * Compose LSP parameter from elementary LSP with previous LSP. - * - * @param lsp_ele (i) Q13 : LSP vectors - * @param lsp (o) Q13 : quantized LSP parameters - * @param fg (i) Q15 : MA prediction coef. - * @param freq_prev (i) Q13 : previous LSP vector - * @param fg_sum (i) Q15 : present MA prediction coef. - */ -private static void lsp_prev_compose( - float lsp_ele[], - float lsp[], - float fg[][/* M */], - float freq_prev[][/* M */], - float fg_sum[] -) -{ - int M = Ld8k.M; - int MA_NP = Ld8k.MA_NP; - - int j, k; - - for(j=0; j 0 ; k-- ) - Util.copy(freq_prev[k-1], freq_prev[k], M); - - Util.copy(lsp_ele, freq_prev[0], M); -} - -/** - * Check stability of lsp coefficients - * - * @param buf in/out: LSP parameters - */ -private static void lsp_stability( - float buf[] -) -{ - float GAP3 = Ld8k.GAP3; - float L_LIMIT = Ld8k.L_LIMIT; - int M = Ld8k.M; - float M_LIMIT = Ld8k.M_LIMIT; - - int j; - float diff, tmp; - - - for(j=0; j M_LIMIT ) { - buf[M-1] = M_LIMIT; - System.out.printf("warning LSP High \n"); - } -} -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/PParity.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/PParity.java deleted file mode 100644 index be9553731..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/PParity.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class PParity -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : P_PARITY.C - Used for the floating point version of both - G.729 main body and G.729A -*/ - -/** - * Compute parity bit for first 6 MSBs - * - * @param pitch_index input : index for which parity is computed - * @return parity bit (XOR of 6 MSB bits) - */ -static int parity_pitch( - int pitch_index -) -{ - int temp, sum, i, bit; - - temp = pitch_index >> 1; - - sum = 1; - for (i = 0; i <= 5; i++) { - temp >>= 1; - bit = temp & 1; - sum = sum + bit; - } - sum = sum & 1; - return (sum); -} - -/** - * Check parity of index with transmitted parity - * - * @param pitch_index input : index of parameter - * @param parity input : parity bit - * @return 0 = no error, 1= error - */ -static int check_parity_pitch( - int pitch_index, - int parity -) -{ - int temp, sum, i, bit; - temp = pitch_index >> 1; - - sum = 1; - for (i = 0; i <= 5; i++) { - temp >>= 1; - bit = temp & 1; - sum = sum + bit; - } - sum += parity; - sum = sum & 1; - return (sum); -} -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Pitch.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Pitch.java deleted file mode 100644 index 5b6934a52..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Pitch.java +++ /dev/null @@ -1,516 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * Long Term Prediction Routines - * - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class Pitch -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : PITCH.C - Used for the floating point version of G.729 main body - (not for G.729A) -*/ - -/** - * Compute the open loop pitch lag. - * - * @param signal input : signal to compute pitch - * s[-PIT_MAX : l_frame-1] - * @param signal_offset input : signal offset - * @param pit_min input : minimum pitch lag - * @param pit_max input : maximum pitch lag - * @param l_frame input : error minimization window - * @return open-loop pitch lag - */ -static int pitch_ol( - float[] signal, - - int signal_offset, - int pit_min, - int pit_max, - int l_frame -) -{ - float THRESHPIT = Ld8k.THRESHPIT; - - float max1, max2, max3; - int p_max1, p_max2, p_max3; - - /*--------------------------------------------------------------------* - * The pitch lag search is divided in three sections. * - * Each section cannot have a pitch multiple. * - * We find a maximum for each section. * - * We compare the maxima of each section by favoring small lag. * - * * - * First section: lag delay = PIT_MAX to 80 * - * Second section: lag delay = 79 to 40 * - * Third section: lag delay = 39 to 20 * - *--------------------------------------------------------------------*/ - - FloatReference maxRef = new FloatReference(); - p_max1 = lag_max(signal, signal_offset, l_frame, pit_max, 80 , maxRef); - max1 = maxRef.value; - p_max2 = lag_max(signal, signal_offset, l_frame, 79 , 40 , maxRef); - max2 = maxRef.value; - p_max3 = lag_max(signal, signal_offset, l_frame, 39 , pit_min , maxRef); - max3 = maxRef.value; - - /*--------------------------------------------------------------------* - * Compare the 3 sections maxima, and favor small lag. * - *--------------------------------------------------------------------*/ - - if ( max1 * THRESHPIT < max2 ) { - max1 = max2; - p_max1 = p_max2; - } - - if ( max1 * THRESHPIT < max3 ) p_max1 = p_max3; - - return (p_max1); -} - -/** - * Find the lag that has maximum correlation - * - * @param signal input : Signal to compute the open loop pitch - * signal[-142:-1] should be known. - * @param signal_offset input : signal offset - * @param l_frame input : Length of frame to compute pitch - * @param lagmax input : maximum lag - * @param lagmin input : minimum lag - * @param cor_max input : normalized correlation of selected lag - * @return lag found - */ -private static int lag_max( - float[] signal, - int signal_offset, - int l_frame, - int lagmax, - int lagmin, - FloatReference cor_max -) -{ - float FLT_MIN_G729 = Ld8k.FLT_MIN_G729; - - int i, j; - int p, p1; - float max, t0; - int p_max = 0; - - max = FLT_MIN_G729; - - for (i = lagmax; i >= lagmin; i--) { - p = signal_offset; - p1 = signal_offset - i; - t0 = 0.0f; - - for (j=0; j= max) { - max = t0; - p_max = i; - } - } - - /* compute energy */ - - t0 = 0.01f; /* to avoid division by zero */ - p = signal_offset - p_max; - for(i=0; i= max) - { - max = corr[corr_offset + i]; - lag = i; - } - } - - /* If first subframe and lag > 84 do not search fractionnal pitch */ - - if( (i_subfr == 0) && (lag > 84) ) - { - pit_frac.value = 0; - return(lag); - } - - /* test the fractions around lag and choose the one which maximizes - the interpolated normalized correlation */ - corr_offset += lag; - max = interpol_3(corr, corr_offset, -2); - frac = -2; - - for (i = -1; i <= 2; i++) - { - corr_int = interpol_3(corr, corr_offset, i); - if(corr_int > max) - { - max = corr_int; - frac = i; - } - } - - /* limit the fraction value in the interval [-1,0,1] */ - - if (frac == -2) - { - frac = 1; - lag -= 1; - } - if (frac == 2) - { - frac = -1; - lag += 1; - } - - pit_frac.value = frac; - - return lag; -} - -/** - * Find the normalized correlation between the target vector and - * the filtered past excitation. - * - * @param exc input : excitation buffer - * @param exc_offset input : excitation buffer offset - * @param xn input : target vector - * @param h input : imp response of synth and weighting flt - * @param l_subfr input : Length of frame to compute pitch - * @param t_min input : minimum value of searched range - * @param t_max input : maximum value of search range - * @param corr_norm output: normalized correlation (correlation - * between target and filtered excitation divided - * by the square root of energy of filtered - * excitation) - * @param corr_norm_offset input: normalized correlation offset - */ -private static void norm_corr( - float[] exc, - int exc_offset, - float xn[], - float h[], - int l_subfr, - int t_min, - int t_max, - float corr_norm[], - int corr_norm_offset -) -{ - int L_SUBFR = Ld8k.L_SUBFR; - - int i, j, k; - float[] excf = new float[L_SUBFR]; /* filtered past excitation */ - float alp, s, norm; - - k = exc_offset -t_min; - - /* compute the filtered excitation for the first delay t_min */ - - Filter.convolve(exc, k, h, excf, l_subfr); - - /* loop for every possible period */ - - for (i = t_min; i <= t_max; i++) - { - /* Compute 1/sqrt(energie of excf[]) */ - - alp = 0.01f; - for (j = 0; j < l_subfr; j++) - alp += excf[j]*excf[j]; - - norm = inv_sqrt(alp); - - - /* Compute correlation between xn[] and excf[] */ - - s = 0.0f; - for (j = 0; j < l_subfr; j++) s += xn[j]*excf[j]; - - - /* Normalize correlation = correlation * (1/sqrt(energie)) */ - - corr_norm[corr_norm_offset + i] = s*norm; - - /* modify the filtered excitation excf[] for the next iteration */ - - if (i != t_max) - { - k--; - for (j = l_subfr-1; j > 0; j--) - excf[j] = excf[j-1] + exc[k]*h[j]; - excf[0] = exc[k]; - } - } -} - -/** - * Compute adaptive codebook gain and compute , -2 - * - * @param xn input : target vector - * @param y1 input : filtered adaptive codebook vector - * @param g_coeff output: and -2 - * @param l_subfr input : vector dimension - * @return pitch gain - */ -static float g_pitch( - float xn[], - float y1[], - float g_coeff[], - int l_subfr -) -{ - float GAIN_PIT_MAX = Ld8k.GAIN_PIT_MAX; - - float xy, yy, gain; - int i; - - xy = 0.0f; - for (i = 0; i < l_subfr; i++) { - xy += xn[i] * y1[i]; - } - yy = 0.01f; - for (i = 0; i < l_subfr; i++) { - yy += y1[i] * y1[i]; /* energy of filtered excitation */ - } - g_coeff[0] = yy; - g_coeff[1] = -2.0f*xy +0.01f; - - /* find pitch gain and bound it by [0,1.2] */ - - gain = xy/yy; - - if (gain<0.0f) gain = 0.0f; - if (gain>GAIN_PIT_MAX) gain = GAIN_PIT_MAX; - - return gain; -} - -/** - * Function enc_lag3() - * Encoding of fractional pitch lag with 1/3 resolution. - *
- * The pitch range for the first subframe is divided as follows:
- *   19 1/3  to   84 2/3   resolution 1/3
- *   85      to   143      resolution 1
- *
- * The period in the first subframe is encoded with 8 bits.
- * For the range with fractions:
- *   index = (T-19)*3 + frac - 1;   where T=[19..85] and frac=[-1,0,1]
- * and for the integer only range
- *   index = (T - 85) + 197;        where T=[86..143]
- *----------------------------------------------------------------------
- * For the second subframe a resolution of 1/3 is always used, and the
- * search range is relative to the lag in the first subframe.
- * If t0 is the lag in the first subframe then
- *  t_min=t0-5   and  t_max=t0+4   and  the range is given by
- *       t_min - 2/3   to  t_max + 2/3
- *
- * The period in the 2nd subframe is encoded with 5 bits:
- *   index = (T-(t_min-1))*3 + frac - 1;    where T[t_min-1 .. t_max+1]
- * 
- * - * @param T0 input : Pitch delay - * @param T0_frac input : Fractional pitch delay - * @param T0_min in/out: Minimum search delay - * @param T0_max in/out: Maximum search delay - * @param pit_min input : Minimum pitch delay - * @param pit_max input : Maximum pitch delay - * @param pit_flag input : Flag for 1st subframe - * @return Return index of encoding - */ -static int enc_lag3( - int T0, - int T0_frac, - IntReference T0_min, - IntReference T0_max, - int pit_min, - int pit_max, - int pit_flag -) -{ - int index; - int _T0_min = T0_min.value, _T0_max = T0_max.value; - - if (pit_flag == 0) /* if 1st subframe */ - { - /* encode pitch delay (with fraction) */ - - if (T0 <= 85) - index = T0*3 - 58 + T0_frac; - else - index = T0 + 112; - - /* find T0_min and T0_max for second subframe */ - - _T0_min = T0 - 5; - if (_T0_min < pit_min) _T0_min = pit_min; - _T0_max = _T0_min + 9; - if (_T0_max > pit_max) - { - _T0_max = pit_max; - _T0_min = _T0_max - 9; - } - } - - else /* second subframe */ - { - index = T0 - _T0_min; - index = index*3 + 2 + T0_frac; - } - T0_min.value = _T0_min; - T0_max.value = _T0_max; - return index; -} - -/** - * For interpolating the normalized correlation - * - * @param x input : function to be interpolated - * @param x_offset input : function offset - * @param frac input : fraction value to evaluate - * @return interpolated value - */ -private static float interpol_3( - float[] x, - int x_offset, - int frac -) -{ - int L_INTER4 = Ld8k.L_INTER4; - int UP_SAMP = Ld8k.UP_SAMP; - float[] inter_3 = TabLd8k.inter_3; - - int i; - float s; - int x1, x2, c1, c2; - - if (frac < 0) { - frac += UP_SAMP; - x_offset--; - } - x1 = x_offset; - x2 = x_offset + 1; - c1 = frac; - c2 = UP_SAMP-frac; - - s = 0.0f; - for(i=0; i< L_INTER4; i++, c1+=UP_SAMP, c2+=UP_SAMP) - { - s+= x[x1] * inter_3[c1] + x[x2] * inter_3[c2]; - x1--; - x2++; - } - - return s; -} - -/** - * Compute y = 1 / sqrt(x) - * - * @param x input : value of x - * @return output: 1/sqrt(x) - */ -private static float inv_sqrt( - float x -) -{ - return (1.0f / (float)Math.sqrt((double)x) ); -} -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/PostPro.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/PostPro.java deleted file mode 100644 index 5c9c99e1a..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/PostPro.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * Post-processing of output speech. - * 2nd order high pass filter with cut off frequency at 100 Hz. - * Designed with SPPACK efi command -40 dB att, 0.25 ri. - * - * Algorithm: - *
- *  y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2]
- *                   + a[1]*y[i-1] + a[2]*y[i-2];
- *
- *     b[3] = {0.93980581E+00, -0.18795834E+01,  0.93980581E+00};
- *     a[3] = {0.10000000E+01, +0.19330735E+01, -0.93589199E+00};
- * 
- * - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class PostPro -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : POST_PRO.C - Used for the floating point version of both - G.729 main body and G.729A -*/ - -/** - * High-pass fir memory - */ -private float x0, x1; - -/** - * High-pass iir memory - */ -private float y1, y2; - -/** - * Init Post Process. - */ -void init_post_process() -{ - x0 = x1 = 0.0f; - y2 = y1 = 0.0f; -} - -/** - * Post Process - * - * @param signal (i/o) : signal - * @param lg (i) : lenght of signal - */ -void post_process( - float signal[], - int lg -) -{ - float[] a100 = TabLd8k.a100; - float[] b100 = TabLd8k.b100; - - int i; - float x2; - float y0; - - for(i=0; iSIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * Post - filtering : short term + long term. - * Floating point computation. - *
- *      Short term postfilter :
- *      Hst(z) = Hst0(z) Hst1(z)
- *      Hst0(z) = 1/g0 A(gamma2)(z) / A(gamma1)(z)
- *      if {hi} = i.r. filter A(gamma2)/A(gamma1) (truncated)
- *      g0 = SUM(|hi|) if > 1
- *      g0 = 1. else
- *      Hst1(z) = 1/(1+ |mu|) (1 + mu z-1)
- *      with mu = 1st parcor calculated on {hi}
-
- *      Long term postfilter :
- *      harmonic postfilter :   H0(z) = gl * (1 + b * z-p)
- *      b = gamma_g * gain_ltp
- *      gl = 1 / 1 + b
- *      copmuation of delay on A(gamma2)(z) s(z)
- *      sub optimal research
- *      1. search best integer delay
- *      2. search around integer sub multiples (3 val. / sub mult)
- *      3. search around integer with fractionnal delays (1/8)
- * 
- * - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class Postfil - extends Ld8k -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : POSTFIL.C - Used for the floating point version of G.729 main body - (not for G.729A) -*/ - -/* Static arrays and variables */ -/** - * s.t. numerator coeff. - */ -private final float[] apond2 = new float[LONG_H_ST]; - -/** - * s.t. postfilter memory - */ -private final float[] mem_stp = new float[M]; - -/** - * null memory to compute h_st - */ -private final float[] mem_zero = new float[M]; - -/** - * A(gamma2) residual - */ -private final float[] res2 = new float[SIZ_RES2]; - -/* Static pointers */ -private int res2_ptr; -private float[] ptr_mem_stp; -private int ptr_mem_stp_offset; - -/** - * for gain adjustment - */ -private float gain_prec; - -/** - * Initialize postfilter functions - */ -void init_post_filter() -{ - int i; - - /* Initialize arrays and pointers */ - - /* A(gamma2) residual */ - for(i=0; iLONG_H_ST-1] with zeroes */ - for(i=MP1; i 0 delay - */ -int post( - int t0, - float[] signal_ptr, - int signal_ptr_offset, - float[] coeff, - int coeff_offset, - float[] sig_out, - int sig_out_offset -) -{ - int vo; /* output: voicing decision 0 = uv, > 0 delay */ - - float[] apond1 = new float[MP1]; /* s.t. denominator coeff. */ - float[] sig_ltp = new float[L_SUBFRP1]; /* H0 output signal */ - int sig_ltp_ptr; - float parcor0; - - /* Compute weighted LPC coefficients */ - Lpcfunc.weight_az(coeff, coeff_offset, GAMMA1_PST, M, apond1); - Lpcfunc.weight_az(coeff, coeff_offset, GAMMA2_PST, M, apond2); - - /* Compute A(gamma2) residual */ - Filter.residu(apond2, 0, signal_ptr, signal_ptr_offset, res2, res2_ptr, L_SUBFR); - - /* Harmonic filtering */ - sig_ltp_ptr = 1; - vo = pst_ltp(t0, res2, res2_ptr, sig_ltp, sig_ltp_ptr); - - /* Save last output of 1/A(gamma1) */ - /* (from preceding subframe) */ - sig_ltp[0] = ptr_mem_stp[ptr_mem_stp_offset]; - - /* Control short term pst filter gain and compute parcor0 */ - parcor0 = calc_st_filt(apond2, apond1, sig_ltp, sig_ltp_ptr); - - /* 1/A(gamma1) filtering, mem_stp is updated */ - Filter.syn_filt(apond1, 0, sig_ltp, sig_ltp_ptr, sig_ltp, sig_ltp_ptr, L_SUBFR, mem_stp, 0, 1); - - /* (1 + mu z-1) tilt filtering */ - filt_mu(sig_ltp, sig_out, sig_out_offset, parcor0); - - /* gain control */ - gain_prec = scale_st(signal_ptr, signal_ptr_offset, sig_out, sig_out_offset, gain_prec); - - /* Update for next frame */ - Util.copy(res2, L_SUBFR, res2, MEM_RES2); - - return vo; -} - -/** - * Harmonic postfilter - * - * @param t0 input : pitch delay given by coder - * @param ptr_sig_in input : postfilter input filter (residu2) - * @param ptr_sig_in_offset input : postfilter input filter offset - * @param ptr_sig_pst0 output: harmonic postfilter output - * @param ptr_sig_pst0_offset input: harmonic postfilter offset - * @return voicing decision 0 = uv, > 0 delay - */ -private int pst_ltp( - int t0, - float[] ptr_sig_in, - int ptr_sig_in_offset, - float[] ptr_sig_pst0, - int ptr_sig_pst0_offset -) -{ - int vo; - -/* Declare variables */ - int ltpdel, phase; - float num_gltp, den_gltp; - float num2_gltp, den2_gltp; - float gain_plt; - float[] y_up = new float[SIZ_Y_UP]; - float[] ptr_y_up; - int ptr_y_up_offset; - int off_yup; - - /* Sub optimal delay search */ - IntReference _ltpdel = new IntReference(); - IntReference _phase = new IntReference(); - FloatReference _num_gltp = new FloatReference(); - FloatReference _den_gltp = new FloatReference(); - IntReference _off_yup = new IntReference(); - search_del(t0, ptr_sig_in, ptr_sig_in_offset, _ltpdel, _phase, _num_gltp, _den_gltp, - y_up, _off_yup); - ltpdel = _ltpdel.value; - phase = _phase.value; - num_gltp = _num_gltp.value; - den_gltp = _den_gltp.value; - off_yup = _off_yup.value; - - vo = ltpdel; - - if(num_gltp == 0.f) { - Util.copy(ptr_sig_in, ptr_sig_in_offset, ptr_sig_pst0, ptr_sig_pst0_offset, L_SUBFR); - } - else { - - if(phase == 0) { - ptr_y_up = ptr_sig_in; - ptr_y_up_offset = ptr_sig_in_offset - ltpdel; - } - - else { - /* Filtering with long filter */ - FloatReference _num2_gltp = new FloatReference(); - FloatReference _den2_gltp = new FloatReference(); - compute_ltp_l(ptr_sig_in, ptr_sig_in_offset, ltpdel, phase, ptr_sig_pst0, ptr_sig_pst0_offset, - _num2_gltp, _den2_gltp); - num2_gltp = _num2_gltp.value; - den2_gltp = _den2_gltp.value; - - if(select_ltp(num_gltp, den_gltp, num2_gltp, den2_gltp) == 1) { - - /* select short filter */ - ptr_y_up = y_up; - ptr_y_up_offset = ((phase-1) * L_SUBFRP1 + off_yup); - } - else { - /* select long filter */ - num_gltp = num2_gltp; - den_gltp = den2_gltp; - ptr_y_up = ptr_sig_pst0; - ptr_y_up_offset = ptr_sig_pst0_offset; - } - } - - if(num_gltp > den_gltp) { - /* beta bounded to 1 */ - gain_plt = MIN_GPLT; - } - else { - gain_plt = den_gltp / (den_gltp + GAMMA_G * num_gltp); - } - - /* filtering by H0(z) (harmonic filter) */ - filt_plt(ptr_sig_in, ptr_sig_in_offset, ptr_y_up, ptr_y_up_offset, ptr_sig_pst0, ptr_sig_pst0_offset, gain_plt); - } - return vo; -} - -/** - * Computes best (shortest) integer LTP delay + fine search - * - * @param t0 input : pitch delay given by coder - * @param ptr_sig_in input : input signal (with delay line) - * @param ptr_sig_in_offset input : input signal offset - * @param ltpdel output: delay = *ltpdel - *phase / f_up - * @param phase output: phase - * @param num_gltp output: numerator of LTP gain - * @param den_gltp output: denominator of LTP gain - * @param y_up - * @param off_yup - */ -private void search_del( - int t0, - float[] ptr_sig_in, - int ptr_sig_in_offset, - IntReference ltpdel, - IntReference phase, - FloatReference num_gltp, - FloatReference den_gltp, - float[] y_up, - IntReference off_yup -) -{ - float[] tab_hup_s = TabLd8k.tab_hup_s; - - /* pointers on tables of constants */ - int ptr_h; - - /* Variables and local arrays */ - float[] tab_den0 = new float[F_UP_PST-1], tab_den1 = new float[F_UP_PST-1]; - int ptr_den0, ptr_den1; - int ptr_sig_past, ptr_sig_past0; - int ptr1; - - int i, n, ioff, i_max; - float ener, num, numsq, den0, den1; - float den_int, num_int; - float den_max, num_max, numsq_max; - int phi_max; - int lambda, phi; - float temp0, temp1; - int ptr_y_up; - - - /* Compute current signal energy */ - ener = 0.f; - for(i=0; i num_int) { - i_max = i; - num_int = num; - } - ptr_sig_past--; - } - if(num_int <= 0.f) { - num_gltp.value = 0.f; - den_gltp.value = 1.f; - ltpdel.value = 0; - phase.value = 0; - return; - } - - /* Calculates denominator for lambda_max */ - lambda += i_max; - ptr_sig_past = ptr_sig_in_offset - lambda; - den_int=0.f; - for(n=0; nMath.abs(y_up[ptr_y_up + L_SUBFR])) { - if(den0 > den_max) { - den_max = den0; - } - } - else { - if(den1 > den_max) { - den_max = den1; - } - } - ptr_y_up += L_SUBFRP1; - ptr_h += LH2_S; - } - if(den_max < 0.1f ) { - num_gltp.value = 0.f; - den_gltp.value = 1.f; - ltpdel.value = 0; - phase.value = 0; - return; - } - /* Computation of the numerators */ - /* and selection of best num*num/den */ - /* for non null phases */ - - /* Initialize with null phase */ - num_max = num_int; - den_max = den_int; - numsq_max = num_max * num_max; - phi_max = 0; - ioff = 1; - - ptr_den0 = 0; - ptr_den1 = 0; - ptr_y_up = 0; - - /* if den_max = 0 : will be selected and declared unvoiced */ - /* if num!=0 & den=0 : will be selected and declared unvoiced */ - /* degenerated seldom cases, switch off LT is OK */ - - /* Loop on phase */ - for(phi=1; phi temp1) { - num_max = num; - numsq_max = numsq; - den_max = den0; - ioff = 0; - phi_max = phi; - } - - /* computes num for lambda_max - phi/F_UP_PST */ - ptr_y_up++; - num = 0.f; - for(n = 0; n temp1) { - num_max = num; - numsq_max = numsq; - den_max = den1; - ioff = 1; - phi_max = phi; - } - ptr_y_up += L_SUBFR; - } - - /* test if normalised crit0[iopt] > THRESCRIT */ - - if((num_max == 0.f) || (den_max <= 0.1f)) { - num_gltp.value = 0.f; - den_gltp.value = 1.f; - ltpdel.value = 0; - phase.value = 0; - return; - } - - /* comparison num * num */ - /* with ener * den x THRESCRIT */ - temp1 = den_max * ener * THRESCRIT; - if(numsq_max >= temp1) { - ltpdel.value = lambda + 1 - ioff; - off_yup.value = ioff; - phase.value = phi_max; - num_gltp.value = num_max; - den_gltp.value = den_max; - } - else { - num_gltp.value = 0.f; - den_gltp.value = 1.f; - ltpdel.value = 0; - phase.value = 0; - } -} - -/** - * Ltp postfilter - * - * @param s_in input : input signal with past - * @param s_in_offset input : input signal offset - * @param s_ltp input : filtered signal with gain 1 - * @param s_ltp_offset input : filtered signal offset - * @param s_out output: output signal - * @param s_out_offset input: output signal offset - * @param gain_plt input : filter gain - */ -private void filt_plt( - float[] s_in, - int s_in_offset, - float[] s_ltp, - int s_ltp_offset, - float[] s_out, - int s_out_offset, - float gain_plt -) -{ - - /* Local variables */ - int n; - float temp; - float gain_plt_1; - - gain_plt_1 = 1.f - gain_plt; - - for(n=0; n num1 * num1 * den2) { - return(2); - } - else { - return(1); - } -} - -/** - * Computes impulse response of A(gamma2) / A(gamma1). - * controls gain : computation of energy impulse response as - * SUMn (abs (h[n])) and computes parcor0 - * - * @param apond2 input : coefficients of numerator - * @param apond1 input : coefficients of denominator - * @param sig_ltp_ptr in/out: input of 1/A(gamma1) : scaled by 1/g0 - * @param sig_ltp_ptr_offset input : input of 1/A(gamma1) ... offset - * @return 1st parcor calcul. on composed filter - */ -private float calc_st_filt( - float[] apond2, - float[] apond1, - float[] sig_ltp_ptr, - int sig_ltp_ptr_offset -) -{ - float[] h = new float[LONG_H_ST]; - float parcor0; /* output: 1st parcor calcul. on composed filter */ - float g0, temp; - - /* computes impulse response of apond1 / apond2 */ - Filter.syn_filt(apond1, 0, apond2, 0, h, 0, LONG_H_ST, mem_zero, 0, 0); - - /* computes 1st parcor */ - parcor0 = calc_rc0_h(h); - - /* computes gain g0 */ - g0 = 0.f; - for(int i=0; i 1.f) { - temp = 1.f/g0; - for(int i=sig_ltp_ptr_offset, toIndex = sig_ltp_ptr_offset + L_SUBFR; i 0.f) { - mu = parcor0 * GAMMA3_PLUS; - } - else { - mu = parcor0 * GAMMA3_MINUS; - } - ga = 1.f / (1.f - Math.abs(mu)); - - ptrs = 0; /* points on sig_in(-1) */ - for(n=0; nSIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * Preprocessing of input speech. - * - 2nd order high pass filter with cut off frequency at 140 Hz. - * - * 2nd order high pass filter with cut off frequency at 140 Hz. - * Designed with SPPACK efi command -40 dB att, 0.25 ri. - * - * Algorithm: - *
- *  y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2]
- *                   + a[1]*y[i-1] + a[2]*y[i-2];
- *
- *     b[3] = {0.92727435E+00, -0.18544941E+01, 0.92727435E+00};
- *     a[3] = {0.10000000E+01, 0.19059465E+01, -0.91140240E+00};
- * 
- * - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class PreProc -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : PRE_PROC.C - Used for the floating point version of both - G.729 main body and G.729A -*/ - -/** - * High-pass fir memory - */ -private float x0, x1; - -/** - * High-pass iir memory - */ -private float y1, y2; - -/** - * Init Pre Process - */ -void init_pre_process() -{ - x0 = x1 = 0.0f; - y2 = y1 = 0.0f; -} - -/** - * Pre Process - * - * @param signal (i/o) : signal - * @param signal_offset (input) : signal offset - * @param lg (i) : length of signal - */ -void pre_process( - float[] signal, - int signal_offset, - int lg -) -{ - float[] a140 = TabLd8k.a140; - float[] b140 = TabLd8k.b140; - - float x2; - float y0; - - for(int i=signal_offset, toIndex=lg+signal_offset; iSIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class PredLt3 -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : PRED_LT3.C - Used for the floating point version of both - G.729 main body and G.729A -*/ - -/** - * Compute the result of long term prediction with fractional - * interpolation of resolution 1/3. - * - * On return exc[0..L_subfr-1] contains the interpolated signal - * (adaptive codebook excitation) - * - * @param exc in/out: excitation vector, exc[0:l_sub-1] = out - * @param exc_offset input: excitation vector offset - * @param t0 input : pitch lag - * @param frac input : Fraction of pitch lag (-1, 0, 1) / 3 - * @param l_subfr input : length of subframe. - */ -static void pred_lt_3( - float[] exc, - int exc_offset, - int t0, - int frac, - int l_subfr -) -{ - int L_INTER10 = Ld8k.L_INTER10; - int UP_SAMP = Ld8k.UP_SAMP; - float[] inter_3l = TabLd8k.inter_3l; - - int i, j, k; - float s; - int x0, x1, x2, c1, c2; - - x0 = exc_offset - t0; - - frac = -frac; - if (frac < 0) { - frac += UP_SAMP; - x0--; - } - - for (j=0; jSIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class Pwf -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : PWF.C - Used for the floating point version of G.729 main body - (not for G.729A) -*/ - - -private int smooth = 1; -private final float[/* 2 */] lar_old = {0.0f, 0.0f}; - -/** - * Adaptive bandwidth expansion for perceptual weighting filter - * - * @param gamma1 output: gamma1 value - * @param gamma2 output: gamma2 value - * @param lsfint input : Interpolated lsf vector : 1st subframe - * @param lsfnew input : lsf vector : 2nd subframe - * @param r_c input : Reflection coefficients - */ -void perc_var( - float[] gamma1, - float[] gamma2, - float[] lsfint, - float[] lsfnew, - float[] r_c -) -{ - float ALPHA = Ld8k.ALPHA; - float BETA = Ld8k.BETA; - float GAMMA1_0 = Ld8k.GAMMA1_0; - float GAMMA1_1 = Ld8k.GAMMA1_1; - float GAMMA2_0_H = Ld8k.GAMMA2_0_H; - float GAMMA2_0_L = Ld8k.GAMMA2_0_L; - float GAMMA2_1 = Ld8k.GAMMA2_1; - int M = Ld8k.M; - float THRESH_H1 = Ld8k.THRESH_H1; - float THRESH_H2 = Ld8k.THRESH_H2; - float THRESH_L1 = Ld8k.THRESH_L1; - float THRESH_L2 = Ld8k.THRESH_L2; - - float[] lar = new float[4]; - float[] lsf; - float critlar0, critlar1; - float d_min, temp; - int i, k; - - - float[] lar_new = lar; - int lar_new_offset = 2; - - /* reflection coefficients --> lar */ - for (i=0; i<2; i++) - lar_new[lar_new_offset + i] = (float)Math.log10( (double)( ( 1.0f + r_c[i]) / (1.0f - r_c[i]))); - - /* Interpolation of lar for the 1st subframe */ - for (i=0; i<2; i++) { - lar[i] = 0.5f * (lar_new[lar_new_offset + i] + lar_old[i]); - lar_old[i] = lar_new[lar_new_offset + i]; - } - - for (k=0; k<2; k++) { /* LOOP : gamma2 for 1st to 2nd subframes */ - - /* ----------------------------------------------------- */ - /* First criterion based on the first two lars */ - /* */ - /* smooth == 1 ==> gamma2 is set to 0.6 */ - /* gamma1 is set to 0.94 */ - /* */ - /* smooth == 0 ==> gamma2 can vary from 0.4 to 0.7 */ - /* (gamma2 = -6.0 dmin + 1.0) */ - /* gamma1 is set to 0.98 */ - /* ----------------------------------------------------- */ - critlar0 = lar[2*k]; - critlar1 = lar[2*k+1]; - - if (smooth != 0) { - if ((critlar0 THRESH_H1)) smooth = 0; - } - else { - if ((critlar0 > THRESH_L2)||(critlar1 < THRESH_H2)) smooth = 1; - } - - if (smooth == 0) { - /* ------------------------------------------------------ */ - /* Second criterion based on the minimum distance between */ - /* two successives lsfs */ - /* ------------------------------------------------------ */ - gamma1[k] = GAMMA1_0; - if (k == 0) lsf = lsfint; - else lsf = lsfnew; - d_min = lsf[1] - lsf[0]; - for (i=1; i GAMMA2_0_H) gamma2[k] = GAMMA2_0_H; - if (gamma2[k] < GAMMA2_0_L) gamma2[k] = GAMMA2_0_L; - } - else { - gamma1[k] = GAMMA1_1; - gamma2[k] = GAMMA2_1;; - } - } -} -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/QuaGain.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/QuaGain.java deleted file mode 100644 index 3f7407f78..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/QuaGain.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class QuaGain -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : QUA_GAIN.C - Used for the floating point version of both - G.729 main body and G.729A -*/ - - -/* gain quantizer routines */ - -private final float[/* 4 */] past_qua_en={-14.0f,-14.0f,-14.0f,-14.0f}; - -/** - * Quantization of pitch and codebook gains - * - * @param code input : fixed codebook vector - * @param g_coeff input : correlation factors - * @param l_subfr input : fcb vector length - * @param gain_pit output: quantized acb gain - * @param gain_code output: quantized fcb gain - * @param tameflag input : flag set to 1 if taming is needed - * @return quantizer index - */ -int qua_gain( - float code[], - float[] g_coeff, - int l_subfr, - FloatReference gain_pit, - FloatReference gain_code, - int tameflag -) -{ - float FLT_MAX_G729 = Ld8k.FLT_MAX_G729; - float GP0999 = Ld8k.GP0999; - float GPCLIP2 = Ld8k.GPCLIP2; - int NCAN1 = Ld8k.NCAN1; - int NCAN2 = Ld8k.NCAN2; - int NCODE2 = Ld8k.NCODE2; - float[][] gbk1 = TabLd8k.gbk1; - float[][] gbk2 = TabLd8k.gbk2; - int[] map1 = TabLd8k.map1; - int[] map2 = TabLd8k.map2; - - /* - * MA prediction is performed on the innovation energy (in dB with mean * - * removed). * - * An initial predicted gain, g_0, is first determined and the correction * - * factor alpha = gain / g_0 is quantized. * - * The pitch gain and the correction factor are vector quantized and the * - * mean-squared weighted error criterion is used in the quantizer search. * - * CS Codebook , fast pre-selection version * - */ - - int i,j, index1 = 0, index2 = 0; - int cand1,cand2 ; - float gcode0 ; - float dist, dist_min, g_pitch, g_code; - float[] best_gain = new float[2]; - float tmp; - - /*---------------------------------------------------* - *- energy due to innovation -* - *- predicted energy -* - *- predicted codebook gain => gcode0[exp_gcode0] -* - *---------------------------------------------------*/ - - gcode0 = Gainpred.gain_predict( past_qua_en, code, l_subfr); - - /*-- pre-selection --*/ - tmp = -1.f/(4.f*g_coeff[0]*g_coeff[2]-g_coeff[4]*g_coeff[4]) ; - best_gain[0] = (2.f*g_coeff[2]*g_coeff[1]-g_coeff[3]*g_coeff[4])*tmp ; - best_gain[1] = (2.f*g_coeff[0]*g_coeff[3]-g_coeff[1]*g_coeff[4])*tmp ; - - if (tameflag == 1){ - if(best_gain[0]> GPCLIP2) best_gain[0] = GPCLIP2; - } - /*----------------------------------------------* - * - presearch for gain codebook - * - *----------------------------------------------*/ - - IntReference cand1Ref = new IntReference(); - IntReference cand2Ref = new IntReference(); - gbk_presel(best_gain,cand1Ref,cand2Ref,gcode0) ; - cand1 = cand1Ref.value; - cand2 = cand2Ref.value; - - /*-- selection --*/ - dist_min = FLT_MAX_G729; - if(tameflag == 1) { - for (i=0;i0.0f){ - /* pre select codebook #1 */ - _cand1 = 0 ; - do{ - if(y>thr1[_cand1]*gcode0) (_cand1)++ ; - else break ; - } while((_cand1)<(NCODE1-NCAN1)) ; - /* pre select codebook #2 */ - _cand2 = 0 ; - do{ - if(x>thr2[_cand2]*gcode0) (_cand2)++ ; - else break ; - } while((_cand2)<(NCODE2-NCAN2)) ; - } - else{ - /* pre select codebook #1 */ - _cand1 = 0 ; - do{ - if(ySIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * Functions related to the quantization of LSP's. - * - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class QuaLsp -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : QUA_LSP.C - Used for the floating point version of both - G.729 main body and G.729A -*/ - -/* static memory */ -/** - * previous LSP vector - */ -private final float[][] freq_prev = new float[Ld8k.MA_NP][Ld8k.M]; - -/** - * previous LSP vector(init) - */ -private static final float[/* M */] FREQ_PREV_RESET = { - 0.285599f, 0.571199f, 0.856798f, 1.142397f, 1.427997f, - 1.713596f, 1.999195f, 2.284795f, 2.570394f, 2.855993f -}; /* PI*(float)(j+1)/(float)(M+1) */ - -/** - * @param lsp (i) : Unquantized LSP - * @param lsp_q (o) : Quantized LSP - * @param ana (o) : indexes - */ -void qua_lsp( - float lsp[], - float lsp_q[], - int ana[] -) -{ - int M = Ld8k.M; - - int i; - float[] lsf = new float[M], lsf_q = new float[M]; /* domain 0.0<= lsf 0.0f) wegt[0] = 1.0f; - else wegt[0] = tmp * tmp * 10.f + 1.0f; - - for ( i=1; i 0.0f) wegt[i] = 1.0f; - else wegt[i] = tmp * tmp * 10.f + 1.0f; - } - - tmp = PI92 - flsp[M-2] - 1.0f; - if (tmp > 0.0f) wegt[M-1] = 1.0f; - else wegt[M-1] = tmp * tmp * 10.f + 1.0f; - - wegt[4] *= CONST12; - wegt[5] *= CONST12; -} - -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/TabLd8k.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/TabLd8k.java deleted file mode 100644 index f21e69639..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/TabLd8k.java +++ /dev/null @@ -1,2626 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class TabLd8k -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : TAB_LD8K.H - Used for the floating point version of G.729 main body - (not for G.729A) -*/ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - -u---------------------------------------------------------------------- -*/ - -/* - File : TAB_LD8K.C - Used for the floating point version of G.729 main body - (not for G.729A) -*/ - -static final float[/* L_WINDOW */] hamwindow = { -0.08000000f, -0.08005703f, -0.08022812f, -0.08051321f, -0.08091225f, -0.08142514f, -0.08205172f, -0.08279188f, -0.08364540f, -0.08461212f, -0.08569173f, -0.08688401f, -0.08818865f, -0.08960532f, -0.09113365f, -0.09277334f, -0.09452391f, -0.09638494f, -0.09835598f, -0.10043652f, -0.10262608f, -0.10492408f, -0.10732999f, -0.10984316f, -0.11246302f, -0.11518890f, -0.11802010f, -0.12095598f, -0.12399574f, -0.12713866f, -0.13038395f, -0.13373083f, -0.13717847f, -0.14072597f, -0.14437246f, -0.14811710f, -0.15195890f, -0.15589692f, -0.15993017f, -0.16405767f, -0.16827843f, -0.17259133f, -0.17699537f, -0.18148938f, -0.18607232f, -0.19074300f, -0.19550033f, -0.20034306f, -0.20527001f, -0.21027996f, -0.21537170f, -0.22054392f, -0.22579536f, -0.23112471f, -0.23653066f, -0.24201185f, -0.24756692f, -0.25319457f, -0.25889328f, -0.26466170f, -0.27049842f, -0.27640197f, -0.28237087f, -0.28840363f, -0.29449883f, -0.30065489f, -0.30687031f, -0.31314352f, -0.31947297f, -0.32585713f, -0.33229437f, -0.33878314f, -0.34532180f, -0.35190874f, -0.35854232f, -0.36522087f, -0.37194279f, -0.37870640f, -0.38550997f, -0.39235184f, -0.39923036f, -0.40614375f, -0.41309035f, -0.42006844f, -0.42707625f, -0.43411207f, -0.44117412f, -0.44826069f, -0.45537004f, -0.46250033f, -0.46964988f, -0.47681686f, -0.48399949f, -0.49119604f, -0.49840465f, -0.50562358f, -0.51285106f, -0.52008528f, -0.52732444f, -0.53456670f, -0.54181033f, -0.54905349f, -0.55629444f, -0.56353134f, -0.57076240f, -0.57798582f, -0.58519983f, -0.59240264f, -0.59959245f, -0.60676748f, -0.61392599f, -0.62106609f, -0.62818617f, -0.63528436f, -0.64235890f, -0.64940804f, -0.65643007f, -0.66342324f, -0.67038584f, -0.67731601f, -0.68421221f, -0.69107264f, -0.69789559f, -0.70467937f, -0.71142232f, -0.71812278f, -0.72477907f, -0.73138952f, -0.73795253f, -0.74446648f, -0.75092971f, -0.75734061f, -0.76369762f, -0.76999915f, -0.77624369f, -0.78242958f, -0.78855544f, -0.79461962f, -0.80062068f, -0.80655706f, -0.81242740f, -0.81823015f, -0.82396388f, -0.82962728f, -0.83521879f, -0.84073710f, -0.84618086f, -0.85154873f, -0.85683930f, -0.86205131f, -0.86718345f, -0.87223446f, -0.87720311f, -0.88208807f, -0.88688827f, -0.89160240f, -0.89622939f, -0.90076804f, -0.90521723f, -0.90957582f, -0.91384280f, -0.91801709f, -0.92209762f, -0.92608339f, -0.92997342f, -0.93376678f, -0.93746245f, -0.94105959f, -0.94455731f, -0.94795465f, -0.95125085f, -0.95444512f, -0.95753652f, -0.96052444f, -0.96340811f, -0.96618676f, -0.96885973f, -0.97142631f, -0.97388595f, -0.97623801f, -0.97848189f, -0.98061699f, -0.98264289f, -0.98455900f, -0.98636484f, -0.98806006f, -0.98964417f, -0.99111670f, -0.99247742f, -0.99372596f, -0.99486196f, -0.99588519f, -0.99679530f, -0.99759221f, -0.99827564f, -0.99884540f, -0.99930143f, -0.99964350f, -0.99987161f, -0.99998569f, -1.00000000f, -0.99921930f, -0.99687845f, -0.99298108f, -0.98753333f, -0.98054361f, -0.97202289f, -0.96198452f, -0.95044410f, -0.93741965f, -0.92293155f, -0.90700239f, -0.88965708f, -0.87092263f, -0.85082841f, -0.82940567f, -0.80668795f, -0.78271067f, -0.75751126f, -0.73112911f, -0.70360541f, -0.67498308f, -0.64530689f, -0.61462307f, -0.58297962f, -0.55042595f, -0.51701277f, -0.48279238f, -0.44781810f, -0.41214463f, -0.37582767f, -0.33892387f, -0.30149087f, -0.26358715f, -0.22527184f, -0.18660481f, -0.14764643f, -0.10845750f, -0.06909923f, -0.02963307f -}; - -static final float[/* M */] lwindow = { -0.99879038f, -0.99546894f, -0.98995779f, -0.98229335f, -0.97252620f, -0.96072035f, -0.94695264f, -0.93131180f, -0.91389754f, -0.89481964f -}; - -static final float[/* GRID_POINTS+1 */] grid = { -0.9997559f, -0.9986295f, -0.9945219f, -0.9876884f, -0.9781476f, -0.9659258f, -0.9510565f, -0.9335804f, -0.9135454f, -0.8910065f, -0.8660254f, -0.8386706f, -0.8090170f, -0.7771460f, -0.7431448f, -0.7071068f, -0.6691306f, -0.6293204f, -0.5877852f, -0.5446391f, -0.5000000f, -0.4539905f, -0.4067366f, -0.3583679f, -0.3090170f, -0.2588190f, -0.2079117f, -0.1564345f, -0.1045285f, -0.0523360f, -0.0000000f, --0.0523360f, --0.1045285f, --0.1564345f, --0.2079117f, --0.2588190f, --0.3090170f, --0.3583679f, --0.4067366f, --0.4539905f, --0.5000000f, --0.5446391f, --0.5877852f, --0.6293204f, --0.6691306f, --0.7071068f, --0.7431448f, --0.7771460f, --0.8090170f, --0.8386706f, --0.8660254f, --0.8910065f, --0.9135454f, --0.9335804f, --0.9510565f, --0.9659258f, --0.9781476f, --0.9876884f, --0.9945219f, --0.9986295f, --0.9997559f -}; - -/*First Stage Codebook */ -static final float[/* NC0 */][/* M */] lspcb1 = { -{0.1814f, -0.2647f, -0.4580f, -1.1077f, -1.4813f, -1.7022f, -2.1953f, -2.3405f, -2.5867f, -2.6636f}, - -{0.2113f, -0.3223f, -0.4212f, -0.5946f, -0.7479f, -0.9615f, -1.9097f, -2.1750f, -2.4773f, -2.6737f}, - -{0.1915f, -0.2755f, -0.3770f, -0.5950f, -1.3505f, -1.6349f, -2.2348f, -2.3552f, -2.5768f, -2.6540f}, - -{0.2116f, -0.3067f, -0.4099f, -0.5748f, -0.8518f, -1.2569f, -2.0782f, -2.1920f, -2.3371f, -2.4842f}, - -{0.2129f, -0.2974f, -0.4039f, -1.0659f, -1.2735f, -1.4658f, -1.9061f, -2.0312f, -2.6074f, -2.6750f}, - -{0.2181f, -0.2893f, -0.4117f, -0.5519f, -0.8295f, -1.5825f, -2.1575f, -2.3179f, -2.5458f, -2.6417f}, - -{0.1991f, -0.2971f, -0.4104f, -0.7725f, -1.3073f, -1.4665f, -1.6208f, -1.6973f, -2.3732f, -2.5743f}, - -{0.1818f, -0.2886f, -0.4018f, -0.7630f, -1.1264f, -1.2699f, -1.6899f, -1.8650f, -2.1633f, -2.6186f}, - -{0.2282f, -0.3093f, -0.4243f, -0.5329f, -1.1173f, -1.7717f, -1.9420f, -2.0780f, -2.5160f, -2.6137f}, - -{0.2528f, -0.3693f, -0.5290f, -0.7146f, -0.9528f, -1.1269f, -1.2936f, -1.9589f, -2.4548f, -2.6653f}, - -{0.2332f, -0.3263f, -0.4174f, -0.5202f, -1.3633f, -1.8447f, -2.0236f, -2.1474f, -2.3572f, -2.4738f}, - -{0.1393f, -0.2216f, -0.3204f, -0.5644f, -0.7929f, -1.1705f, -1.7051f, -2.0054f, -2.3623f, -2.5985f}, - -{0.2677f, -0.3871f, -0.5746f, -0.7091f, -1.3311f, -1.5260f, -1.7288f, -1.9122f, -2.5787f, -2.6598f}, - -{0.1570f, -0.2328f, -0.3111f, -0.4216f, -1.1688f, -1.4605f, -1.9505f, -2.1173f, -2.4038f, -2.7460f}, - -{0.2346f, -0.3321f, -0.5621f, -0.8160f, -1.4042f, -1.5860f, -1.7518f, -1.8631f, -2.0749f, -2.5380f}, - -{0.2505f, -0.3368f, -0.4758f, -0.6405f, -0.8104f, -1.2533f, -1.9329f, -2.0526f, -2.2155f, -2.6459f}, - -{0.2196f, -0.3049f, -0.6857f, -1.3976f, -1.6100f, -1.7958f, -2.0813f, -2.2211f, -2.4789f, -2.5857f}, - -{0.1232f, -0.2011f, -0.3527f, -0.6969f, -1.1647f, -1.5081f, -1.8593f, -2.2576f, -2.5594f, -2.6896f}, - -{0.3682f, -0.4632f, -0.6600f, -0.9118f, -1.5245f, -1.7071f, -1.8712f, -1.9939f, -2.4356f, -2.5380f}, - -{0.2690f, -0.3711f, -0.4635f, -0.6644f, -1.4633f, -1.6495f, -1.8227f, -1.9983f, -2.1797f, -2.2954f}, - -{0.3555f, -0.5240f, -0.9751f, -1.1685f, -1.4114f, -1.6168f, -1.7769f, -2.0178f, -2.4420f, -2.5724f}, - -{0.3493f, -0.4404f, -0.7231f, -0.8587f, -1.1272f, -1.4715f, -1.6760f, -2.2042f, -2.4735f, -2.5604f}, - -{0.3747f, -0.5263f, -0.7284f, -0.8994f, -1.4017f, -1.5502f, -1.7468f, -1.9816f, -2.2380f, -2.3404f}, - -{0.2972f, -0.4470f, -0.5941f, -0.7078f, -1.2675f, -1.4310f, -1.5930f, -1.9126f, -2.3026f, -2.4208f}, - -{0.2467f, -0.3180f, -0.4712f, -1.1281f, -1.6206f, -1.7876f, -1.9544f, -2.0873f, -2.3521f, -2.4721f}, - -{0.2292f, -0.3430f, -0.4383f, -0.5747f, -1.3497f, -1.5187f, -1.9070f, -2.0958f, -2.2902f, -2.4301f}, - -{0.2573f, -0.3508f, -0.4484f, -0.7079f, -1.6577f, -1.7929f, -1.9456f, -2.0847f, -2.3060f, -2.4208f}, - -{0.1968f, -0.2789f, -0.3594f, -0.4361f, -1.0034f, -1.7040f, -1.9439f, -2.1044f, -2.2696f, -2.4558f}, - -{0.2955f, -0.3853f, -0.7986f, -1.2470f, -1.4723f, -1.6522f, -1.8684f, -2.0084f, -2.2849f, -2.4268f}, - -{0.2036f, -0.3189f, -0.4314f, -0.6393f, -1.2834f, -1.4278f, -1.5796f, -2.0506f, -2.2044f, -2.3656f}, - -{0.2916f, -0.3684f, -0.5907f, -1.1394f, -1.3933f, -1.5540f, -1.8341f, -1.9835f, -2.1301f, -2.2800f}, - -{0.2289f, -0.3402f, -0.5166f, -0.7716f, -1.0614f, -1.2389f, -1.4386f, -2.0769f, -2.2715f, -2.4366f}, - -{0.0829f, -0.1723f, -0.5682f, -0.9773f, -1.3973f, -1.6174f, -1.9242f, -2.2128f, -2.4855f, -2.6327f}, - -{0.2244f, -0.3169f, -0.4368f, -0.5625f, -0.6897f, -1.3763f, -1.7524f, -1.9393f, -2.5121f, -2.6556f}, - -{0.1591f, -0.2387f, -0.2924f, -0.4056f, -1.4677f, -1.6802f, -1.9389f, -2.2067f, -2.4635f, -2.5919f}, - -{0.1756f, -0.2566f, -0.3251f, -0.4227f, -1.0167f, -1.2649f, -1.6801f, -2.1055f, -2.4088f, -2.7276f}, - -{0.1050f, -0.2325f, -0.7445f, -0.9491f, -1.1982f, -1.4658f, -1.8093f, -2.0397f, -2.4155f, -2.5797f}, - -{0.2043f, -0.3324f, -0.4522f, -0.7477f, -0.9361f, -1.1533f, -1.6703f, -1.7631f, -2.5071f, -2.6528f}, - -{0.1522f, -0.2258f, -0.3543f, -0.5504f, -0.8815f, -1.5516f, -1.8110f, -1.9915f, -2.3603f, -2.7735f}, - -{0.1862f, -0.2759f, -0.4715f, -0.6908f, -0.8963f, -1.4341f, -1.6322f, -1.7630f, -2.2027f, -2.6043f}, - -{0.1460f, -0.2254f, -0.3790f, -0.8622f, -1.3394f, -1.5754f, -1.8084f, -2.0798f, -2.4319f, -2.7632f}, - -{0.2621f, -0.3792f, -0.5463f, -0.7948f, -1.0043f, -1.1921f, -1.3409f, -1.4845f, -2.3159f, -2.6002f}, - -{0.1935f, -0.2937f, -0.3656f, -0.4927f, -1.4015f, -1.6086f, -1.7724f, -1.8837f, -2.4374f, -2.5971f}, - -{0.2171f, -0.3282f, -0.4412f, -0.5713f, -1.1554f, -1.3506f, -1.5227f, -1.9923f, -2.4100f, -2.5391f}, - -{0.2274f, -0.3157f, -0.4263f, -0.8202f, -1.4293f, -1.5884f, -1.7535f, -1.9688f, -2.3939f, -2.4934f}, - -{0.1704f, -0.2633f, -0.3259f, -0.4134f, -1.2948f, -1.4802f, -1.6619f, -2.0393f, -2.3165f, -2.6083f}, - -{0.1763f, -0.2585f, -0.4012f, -0.7609f, -1.1503f, -1.5847f, -1.8309f, -1.9352f, -2.0982f, -2.6681f}, - -{0.2447f, -0.3535f, -0.4618f, -0.5979f, -0.7530f, -0.8908f, -1.5393f, -2.0075f, -2.3557f, -2.6203f}, - -{0.1826f, -0.3496f, -0.7764f, -0.9888f, -1.3915f, -1.7421f, -1.9412f, -2.1620f, -2.4999f, -2.6931f}, - -{0.3033f, -0.3802f, -0.6981f, -0.8664f, -1.0254f, -1.5401f, -1.7180f, -1.8124f, -2.5068f, -2.6119f}, - -{0.2960f, -0.4001f, -0.6465f, -0.7672f, -1.3782f, -1.5751f, -1.9559f, -2.1373f, -2.3601f, -2.4760f}, - -{0.3132f, -0.4613f, -0.6544f, -0.8532f, -1.0721f, -1.2730f, -1.7566f, -1.9217f, -2.1693f, -2.6531f}, - -{0.3329f, -0.4131f, -0.8073f, -1.1297f, -1.2869f, -1.4937f, -1.7885f, -1.9150f, -2.4505f, -2.5760f}, - -{0.2340f, -0.3605f, -0.7659f, -0.9874f, -1.1854f, -1.3337f, -1.5128f, -2.0062f, -2.4427f, -2.5859f}, - -{0.4131f, -0.5330f, -0.6530f, -0.9360f, -1.3648f, -1.5388f, -1.6994f, -1.8707f, -2.4294f, -2.5335f}, - -{0.3754f, -0.5229f, -0.7265f, -0.9301f, -1.1724f, -1.3440f, -1.5118f, -1.7098f, -2.5218f, -2.6242f}, - -{0.2138f, -0.2998f, -0.6283f, -1.2166f, -1.4187f, -1.6084f, -1.7992f, -2.0106f, -2.5377f, -2.6558f}, - -{0.1761f, -0.2672f, -0.4065f, -0.8317f, -1.0900f, -1.4814f, -1.7672f, -1.8685f, -2.3969f, -2.5079f}, - -{0.2801f, -0.3535f, -0.4969f, -0.9809f, -1.4934f, -1.6378f, -1.8021f, -2.1200f, -2.3135f, -2.4034f}, - -{0.2365f, -0.3246f, -0.5618f, -0.8176f, -1.1073f, -1.5702f, -1.7331f, -1.8592f, -1.9589f, -2.3044f}, - -{0.2529f, -0.3251f, -0.5147f, -1.1530f, -1.3291f, -1.5005f, -1.7028f, -1.8200f, -2.3482f, -2.4831f}, - -{0.2125f, -0.3041f, -0.4259f, -0.9935f, -1.1788f, -1.3615f, -1.6121f, -1.7930f, -2.5509f, -2.6742f}, - -{0.2685f, -0.3518f, -0.5707f, -1.0410f, -1.2270f, -1.3927f, -1.7622f, -1.8876f, -2.0985f, -2.5144f}, - -{0.2373f, -0.3648f, -0.5099f, -0.7373f, -0.9129f, -1.0421f, -1.7312f, -1.8984f, -2.1512f, -2.6342f}, - -{0.2229f, -0.3876f, -0.8621f, -1.1986f, -1.5655f, -1.8861f, -2.2376f, -2.4239f, -2.6648f, -2.7359f}, - -{0.3009f, -0.3719f, -0.5887f, -0.7297f, -0.9395f, -1.8797f, -2.0423f, -2.1541f, -2.5132f, -2.6026f}, - -{0.3114f, -0.4142f, -0.6476f, -0.8448f, -1.2495f, -1.7192f, -2.2148f, -2.3432f, -2.5246f, -2.6046f}, - -{0.3666f, -0.4638f, -0.6496f, -0.7858f, -0.9667f, -1.4213f, -1.9300f, -2.0564f, -2.2119f, -2.3170f}, - -{0.4218f, -0.5075f, -0.8348f, -1.0009f, -1.2057f, -1.5032f, -1.9416f, -2.0540f, -2.4352f, -2.5504f}, - -{0.3726f, -0.4602f, -0.5971f, -0.7093f, -0.8517f, -1.2361f, -1.8052f, -1.9520f, -2.4137f, -2.5518f}, - -{0.4482f, -0.5318f, -0.7114f, -0.8542f, -1.0328f, -1.4751f, -1.7278f, -1.8237f, -2.3496f, -2.4931f}, - -{0.3316f, -0.4498f, -0.6404f, -0.8162f, -1.0332f, -1.2209f, -1.5130f, -1.7250f, -1.9715f, -2.4141f}, - -{0.2375f, -0.3221f, -0.5042f, -0.9760f, -1.7503f, -1.9014f, -2.0822f, -2.2225f, -2.4689f, -2.5632f}, - -{0.2813f, -0.3575f, -0.5032f, -0.5889f, -0.6885f, -1.6040f, -1.9318f, -2.0677f, -2.4546f, -2.5701f}, - -{0.2198f, -0.3072f, -0.4090f, -0.6371f, -1.6365f, -1.9468f, -2.1507f, -2.2633f, -2.5063f, -2.5943f}, - -{0.1754f, -0.2716f, -0.3361f, -0.5550f, -1.1789f, -1.3728f, -1.8527f, -1.9919f, -2.1349f, -2.3359f}, - -{0.2832f, -0.3540f, -0.6080f, -0.8467f, -1.0259f, -1.6467f, -1.8987f, -1.9875f, -2.4744f, -2.5527f}, - -{0.2670f, -0.3564f, -0.5628f, -0.7172f, -0.9021f, -1.5328f, -1.7131f, -2.0501f, -2.5633f, -2.6574f}, - -{0.2729f, -0.3569f, -0.6252f, -0.7641f, -0.9887f, -1.6589f, -1.8726f, -1.9947f, -2.1884f, -2.4609f}, - -{0.2155f, -0.3221f, -0.4580f, -0.6995f, -0.9623f, -1.2339f, -1.6642f, -1.8823f, -2.0518f, -2.2674f}, - -{0.4224f, -0.7009f, -1.1714f, -1.4334f, -1.7595f, -1.9629f, -2.2185f, -2.3304f, -2.5446f, -2.6369f}, - -{0.4560f, -0.5403f, -0.7568f, -0.8989f, -1.1292f, -1.7687f, -1.9575f, -2.0784f, -2.4260f, -2.5484f}, - -{0.4299f, -0.5833f, -0.8408f, -1.0596f, -1.5524f, -1.7484f, -1.9471f, -2.2034f, -2.4617f, -2.5812f}, - -{0.2614f, -0.3624f, -0.8381f, -0.9829f, -1.2220f, -1.6064f, -1.8083f, -1.9362f, -2.1397f, -2.2773f}, - -{0.5064f, -0.7481f, -1.1021f, -1.3271f, -1.5486f, -1.7096f, -1.9503f, -2.1006f, -2.3911f, -2.5141f}, - -{0.5375f, -0.6552f, -0.8099f, -1.0219f, -1.2407f, -1.4160f, -1.8266f, -1.9936f, -2.1951f, -2.2911f}, - -{0.4994f, -0.6575f, -0.8365f, -1.0706f, -1.4116f, -1.6224f, -1.9200f, -2.0667f, -2.3262f, -2.4539f}, - -{0.3353f, -0.4426f, -0.6469f, -0.9161f, -1.2528f, -1.3956f, -1.6080f, -1.8909f, -2.0600f, -2.1380f}, - -{0.2745f, -0.4341f, -1.0424f, -1.2928f, -1.5461f, -1.7940f, -2.0161f, -2.1758f, -2.4742f, -2.5937f}, - -{0.1562f, -0.2393f, -0.4786f, -0.9513f, -1.2395f, -1.8010f, -2.0320f, -2.2143f, -2.5243f, -2.6204f}, - -{0.2979f, -0.4242f, -0.8224f, -1.0564f, -1.4881f, -1.7808f, -2.0898f, -2.1882f, -2.3328f, -2.4389f}, - -{0.2294f, -0.3070f, -0.5490f, -0.9244f, -1.2229f, -1.8248f, -1.9704f, -2.0627f, -2.2458f, -2.3653f}, - -{0.3423f, -0.4502f, -0.9144f, -1.2313f, -1.3694f, -1.5517f, -1.9907f, -2.1326f, -2.4509f, -2.5789f}, - -{0.2470f, -0.3275f, -0.4729f, -1.0093f, -1.2519f, -1.4216f, -1.8540f, -2.0877f, -2.3151f, -2.4156f}, - -{0.3447f, -0.4401f, -0.7099f, -1.0493f, -1.2312f, -1.4001f, -2.0225f, -2.1317f, -2.2894f, -2.4263f}, - -{0.3481f, -0.4494f, -0.6446f, -0.9336f, -1.1198f, -1.2620f, -1.8264f, -1.9712f, -2.1435f, -2.2552f}, - -{0.1646f, -0.3229f, -0.7112f, -1.0725f, -1.2964f, -1.5663f, -1.9843f, -2.2363f, -2.5798f, -2.7572f}, - -{0.2614f, -0.3707f, -0.5241f, -0.7425f, -0.9269f, -1.2976f, -2.0945f, -2.2014f, -2.6204f, -2.6959f}, - -{0.1963f, -0.2900f, -0.4131f, -0.8397f, -1.2171f, -1.3705f, -2.0665f, -2.1546f, -2.4640f, -2.5782f}, - -{0.3387f, -0.4415f, -0.6121f, -0.8005f, -0.9507f, -1.0937f, -2.0836f, -2.2342f, -2.3849f, -2.5076f}, - -{0.2362f, -0.5876f, -0.7574f, -0.8804f, -1.0961f, -1.4240f, -1.9519f, -2.1742f, -2.4935f, -2.6493f}, - -{0.2793f, -0.4282f, -0.6149f, -0.8352f, -1.0106f, -1.1766f, -1.8392f, -2.0119f, -2.6433f, -2.7117f}, - -{0.3603f, -0.4604f, -0.5955f, -0.9251f, -1.1006f, -1.2572f, -1.7688f, -1.8607f, -2.4687f, -2.5623f}, - -{0.3975f, -0.5849f, -0.8059f, -0.9182f, -1.0552f, -1.1850f, -1.6356f, -1.9627f, -2.3318f, -2.4719f}, - -{0.2231f, -0.3192f, -0.4256f, -0.7373f, -1.4831f, -1.6874f, -1.9765f, -2.1097f, -2.6152f, -2.6906f}, - -{0.1221f, -0.2081f, -0.3665f, -0.7734f, -1.0341f, -1.2818f, -1.8162f, -2.0727f, -2.4446f, -2.7377f}, - -{0.2010f, -0.2791f, -0.3796f, -0.8845f, -1.4030f, -1.5615f, -2.0538f, -2.1567f, -2.3171f, -2.4686f}, - -{0.2086f, -0.3053f, -0.4047f, -0.8224f, -1.0656f, -1.2115f, -1.9641f, -2.0871f, -2.2430f, -2.4313f}, - -{0.3203f, -0.4285f, -0.5467f, -0.6891f, -1.2039f, -1.3569f, -1.8578f, -2.2055f, -2.3906f, -2.4881f}, - -{0.3074f, -0.4192f, -0.5772f, -0.7799f, -0.9866f, -1.1335f, -1.6068f, -2.2441f, -2.4194f, -2.5089f}, - -{0.2108f, -0.2910f, -0.4993f, -0.7695f, -0.9528f, -1.5681f, -1.7838f, -2.1495f, -2.3522f, -2.4636f}, - -{0.3492f, -0.4560f, -0.5906f, -0.7379f, -0.8855f, -1.0257f, -1.7128f, -1.9997f, -2.2019f, -2.3694f}, - -{0.5185f, -0.7316f, -0.9708f, -1.1954f, -1.5066f, -1.7887f, -2.1396f, -2.2918f, -2.5429f, -2.6489f}, - -{0.4276f, -0.4946f, -0.6934f, -0.8308f, -0.9944f, -1.4582f, -2.0324f, -2.1294f, -2.4891f, -2.6324f}, - -{0.3847f, -0.5973f, -0.7202f, -0.8787f, -1.3938f, -1.5959f, -1.8463f, -2.1574f, -2.5050f, -2.6687f}, - -{0.4835f, -0.5919f, -0.7235f, -0.8862f, -1.0756f, -1.2853f, -1.9118f, -2.0215f, -2.2213f, -2.4638f}, - -{0.5492f, -0.8062f, -0.9810f, -1.1293f, -1.3189f, -1.5415f, -1.9385f, -2.1378f, -2.4439f, -2.5691f}, - -{0.5190f, -0.6764f, -0.8123f, -1.0154f, -1.2085f, -1.4266f, -1.8433f, -2.0866f, -2.5113f, -2.6474f}, - -{0.4602f, -0.6503f, -0.9602f, -1.1427f, -1.3043f, -1.4427f, -1.6676f, -1.8758f, -2.2868f, -2.4271f}, - -{0.3764f, -0.4845f, -0.7627f, -0.9914f, -1.1961f, -1.3421f, -1.5129f, -1.6707f, -2.1836f, -2.3322f}, - -{0.3334f, -0.5701f, -0.8622f, -1.1232f, -1.3851f, -1.6767f, -2.0600f, -2.2946f, -2.5375f, -2.7295f}, - -{0.1449f, -0.2719f, -0.5783f, -0.8807f, -1.1746f, -1.5422f, -1.8804f, -2.1934f, -2.4734f, -2.8728f}, - -{0.2333f, -0.3024f, -0.4780f, -1.2327f, -1.4180f, -1.5815f, -1.9804f, -2.0921f, -2.3524f, -2.5304f}, - -{0.2154f, -0.3075f, -0.4746f, -0.8477f, -1.1170f, -1.5369f, -1.9847f, -2.0733f, -2.1880f, -2.2504f}, - -{0.1709f, -0.4486f, -0.8705f, -1.0643f, -1.3047f, -1.5269f, -1.9175f, -2.1621f, -2.4073f, -2.5718f}, - -{0.2835f, -0.3752f, -0.5234f, -0.9898f, -1.1484f, -1.2974f, -1.9363f, -2.0378f, -2.4065f, -2.6214f}, - -{0.3211f, -0.4077f, -0.5809f, -1.0206f, -1.2542f, -1.3835f, -1.5723f, -2.1209f, -2.3464f, -2.4336f}, - -{0.2101f, -0.3146f, -0.6779f, -0.8783f, -1.0561f, -1.3045f, -1.8395f, -2.0695f, -2.2831f, -2.4328f} -}; - -/*Second Stage Codebook*/ -static final float[/* NC1 */][/* M */] lspcb2 = { -{-0.0532f, --0.0995f, --0.0906f, -0.1261f, --0.0633f, -0.0711f, --0.1467f, -0.1012f, -0.0106f, -0.0470f}, - -{-0.1017f, --0.1088f, -0.0566f, --0.0010f, --0.1528f, -0.1771f, -0.0089f, --0.0282f, -0.1055f, -0.0808f}, - -{-0.1247f, -0.0283f, --0.0374f, -0.0393f, --0.0269f, --0.0200f, --0.0643f, --0.0921f, --0.1994f, -0.0327f}, - -{0.0070f, --0.0242f, --0.0415f, --0.0041f, --0.1793f, -0.0700f, -0.0972f, --0.0207f, --0.0771f, -0.0997f}, - -{0.0209f, --0.0428f, -0.0359f, -0.2027f, -0.0554f, -0.0634f, -0.0356f, -0.0195f, --0.0782f, --0.1583f}, - -{-0.0856f, --0.1028f, --0.0071f, -0.1160f, -0.1089f, -0.1892f, -0.0874f, -0.0644f, --0.0872f, --0.0236f}, - -{0.0713f, -0.0039f, --0.0353f, -0.0435f, --0.0407f, --0.0558f, -0.0748f, --0.0346f, --0.1686f, --0.0905f}, - -{-0.0134f, --0.0987f, -0.0283f, -0.0095f, --0.0107f, --0.0420f, -0.1638f, -0.1328f, --0.0799f, --0.0695f}, - -{-0.1049f, -0.1510f, -0.0672f, -0.1043f, -0.0872f, --0.0663f, --0.2139f, --0.0239f, --0.0120f, --0.0338f}, - -{-0.1071f, --0.1165f, --0.1524f, --0.0365f, -0.0260f, --0.0288f, --0.0889f, -0.1159f, -0.1852f, -0.1093f}, - -{-0.0094f, -0.0420f, --0.0758f, -0.0932f, -0.0505f, -0.0614f, --0.0443f, --0.1172f, --0.0590f, -0.1693f}, - -{-0.0384f, --0.0375f, --0.0313f, --0.1539f, --0.0524f, -0.0550f, --0.0569f, --0.0133f, -0.1233f, -0.2714f}, - -{0.0869f, -0.0847f, -0.0637f, -0.0794f, -0.1594f, --0.0035f, --0.0462f, -0.0909f, --0.1227f, -0.0294f}, - -{-0.0137f, --0.0332f, --0.0611f, -0.1156f, -0.2116f, -0.0332f, --0.0019f, -0.1110f, --0.0317f, -0.2061f}, - -{0.0703f, --0.0013f, --0.0572f, --0.0243f, -0.1345f, --0.1235f, -0.0710f, --0.0065f, --0.0912f, -0.1072f}, - -{0.0178f, --0.0349f, --0.1563f, --0.0487f, -0.0044f, --0.0609f, --0.1682f, -0.0023f, --0.0542f, -0.1811f}, - -{-0.1384f, --0.1020f, -0.1649f, -0.1568f, --0.0116f, -0.1240f, --0.0271f, -0.0541f, -0.0455f, --0.0433f}, - -{-0.1782f, --0.1511f, -0.0509f, --0.0261f, -0.0570f, -0.0817f, -0.0805f, -0.2003f, -0.1138f, -0.0653f}, - -{-0.0019f, -0.0081f, -0.0572f, -0.1245f, --0.0914f, -0.1691f, --0.0223f, --0.1108f, --0.0881f, --0.0320f}, - -{-0.0413f, -0.0181f, -0.1764f, -0.0092f, --0.0928f, -0.0695f, -0.1523f, -0.0412f, -0.0508f, --0.0148f}, - -{0.0476f, -0.0292f, -0.1915f, -0.1198f, -0.0139f, -0.0451f, --0.1225f, --0.0619f, --0.0717f, --0.1104f}, - -{-0.0382f, --0.0120f, -0.1159f, -0.0039f, -0.1348f, -0.0088f, --0.0173f, -0.1789f, -0.0078f, --0.0959f}, - -{0.1376f, -0.0713f, -0.1020f, -0.0339f, --0.1415f, -0.0254f, -0.0368f, --0.1077f, -0.0143f, --0.0494f}, - -{0.0658f, --0.0140f, -0.1046f, --0.0603f, -0.0273f, --0.1114f, -0.0761f, --0.0093f, -0.0338f, --0.0538f}, - -{0.2683f, -0.2853f, -0.1549f, -0.0819f, -0.0372f, --0.0327f, --0.0642f, -0.0172f, -0.1077f, --0.0170f}, - -{-0.1949f, -0.0672f, -0.0978f, --0.0557f, --0.0069f, --0.0851f, -0.1057f, -0.1294f, -0.0505f, -0.0545f}, - -{0.1409f, -0.0724f, --0.0094f, -0.1511f, --0.0039f, -0.0710f, --0.1266f, --0.1093f, -0.0817f, -0.0363f}, - -{0.0485f, -0.0682f, -0.0248f, --0.0974f, --0.1122f, -0.0004f, -0.0845f, --0.0357f, -0.1282f, -0.0955f}, - -{0.0408f, -0.1801f, -0.0772f, --0.0098f, -0.0059f, --0.1296f, --0.0591f, -0.0443f, --0.0729f, --0.1041f}, - -{-0.0666f, --0.0403f, --0.0524f, --0.0831f, -0.1384f, --0.1443f, --0.0909f, -0.1636f, -0.0320f, -0.0077f}, - -{0.1612f, -0.1010f, --0.0486f, --0.0704f, -0.0417f, --0.0945f, --0.0590f, --0.1523f, --0.0086f, -0.0120f}, - -{-0.0199f, -0.0823f, --0.0014f, --0.1082f, -0.0649f, --0.1374f, --0.0324f, --0.0296f, -0.0885f, -0.1141f} -}; - -/*MA prediction coef. */ -static final float fg[/* MODE */][/* MA_NP */][/* M */] = { -{{0.2570f, -0.2780f, -0.2800f, -0.2736f, -0.2757f, -0.2764f, -0.2675f, -0.2678f, -0.2779f, -0.2647f}, - -{0.2142f, -0.2194f, -0.2331f, -0.2230f, -0.2272f, -0.2252f, -0.2148f, -0.2123f, -0.2115f, -0.2096f}, - -{0.1670f, -0.1523f, -0.1567f, -0.1580f, -0.1601f, -0.1569f, -0.1589f, -0.1555f, -0.1474f, -0.1571f}, - -{0.1238f, -0.0925f, -0.0798f, -0.0923f, -0.0890f, -0.0828f, -0.1010f, -0.0988f, -0.0872f, -0.1060f}, -}, - -{{0.2360f, -0.2405f, -0.2499f, -0.2495f, -0.2517f, -0.2591f, -0.2636f, -0.2625f, -0.2551f, -0.2310f}, - -{0.1285f, -0.0925f, -0.0779f, -0.1060f, -0.1183f, -0.1176f, -0.1277f, -0.1268f, -0.1193f, -0.1211f}, - -{0.0981f, -0.0589f, -0.0401f, -0.0654f, -0.0761f, -0.0728f, -0.0841f, -0.0826f, -0.0776f, -0.0891f}, - -{0.0923f, -0.0486f, -0.0287f, -0.0498f, -0.0526f, -0.0482f, -0.0621f, -0.0636f, -0.0584f, -0.0794f}, -}, - -}; - -/*present MA prediction coef.*/ -static final float[/* MODE */][/* M */] fg_sum = { -{0.2380000054836f, -0.2578000128269f, -0.2504000067711f, -0.2531000375748f, -0.2480000108480f, -0.2587000429630f, -0.2577999532223f, -0.2656000256538f, -0.2760000228882f, -0.2625999450684f}, - -{0.4451000094414f, -0.5595000386238f, -0.6034000515938f, -0.5292999744415f, -0.5012999176979f, -0.5023000240326f, -0.4625000357628f, -0.4645000100136f, -0.4895999729633f, -0.4793999791145f} -}; - -/*inverse coef. */ -static final float[/* MODE */][/* M */] fg_sum_inv = { -{4.2016806602478f, -3.8789758682251f, -3.9936101436615f, -3.9510068893433f, -4.0322580337524f, -3.8654806613922f, -3.8789765834808f, -3.7650599479675f, -3.6231880187988f, -3.8080739974976f}, - -{2.2466859817505f, -1.7873100042343f, -1.6572753190994f, -1.8892878293991f, -1.9948137998581f, -1.9908419847488f, -2.1621620655060f, -2.1528525352478f, -2.0424838066101f, -2.0859408378601f} -}; - -static final float[/* FIR_SIZE_ANA */] inter_3 = { -0.900839f, -0.760084f, -0.424082f, -0.084078f, --0.105570f, --0.121120f, --0.047624f, -0.016285f, -0.031217f, -0.015738f, -0.000000f, --0.005925f, -0.000000f -}; - -static final float[/* FIR_SIZE_SYN */] inter_3l = { -0.898517f, -0.769271f, -0.448635f, -0.095915f, --0.134333f, --0.178528f, --0.084919f, -0.036952f, -0.095533f, -0.068936f, --0.000000f, --0.050404f, --0.050835f, --0.014169f, -0.023083f, -0.033543f, -0.016774f, --0.007466f, --0.019340f, --0.013755f, -0.000000f, -0.009400f, -0.009029f, -0.002381f, --0.003658f, --0.005027f, --0.002405f, -0.001050f, -0.002780f, -0.002145f, -0.000000f -}; - -static final float[/* 4 */] pred = { -0.68f, -0.58f, -0.34f, -0.19f -}; - -static final float[/* 2 */][/* 2 */] coef = { -{31.134575f, -1.612322f}, - -{0.481389f, -0.053056f} -}; - -static final float[/* NCODE1-NCAN1 */] thr1 = { -0.659681f, -0.755274f, -1.207205f, -1.987740f -}; - -static final float[/* NCODE2-NCAN2 */] thr2 = { -0.429912f, -0.494045f, -0.618737f, -0.650676f, -0.717949f, -0.770050f, -0.850628f, -0.932089f -}; - -static final float[/* NCODE1 */][/* 2 */] gbk1 = { -{0.000010f, -0.185084f}, - -{0.094719f, -0.296035f}, - -{0.111779f, -0.613122f}, - -{0.003516f, -0.659780f}, - -{0.117258f, -1.134277f}, - -{0.197901f, -1.214512f}, - -{0.021772f, -1.801288f}, - -{0.163457f, -3.315700f} -}; - -static final float[/* NCODE2*/][/* 2 */] gbk2 = { -{0.050466f, -0.244769f}, - -{0.121711f, -0.000010f}, - -{0.313871f, -0.072357f}, - -{0.375977f, -0.292399f}, - -{0.493870f, -0.593410f}, - -{0.556641f, -0.064087f}, - -{0.645363f, -0.362118f}, - -{0.706138f, -0.146110f}, - -{0.809357f, -0.397579f}, - -{0.866379f, -0.199087f}, - -{0.923602f, -0.599938f}, - -{0.925376f, -1.742757f}, - -{0.942028f, -0.029027f}, - -{0.983459f, -0.414166f}, - -{1.055892f, -0.227186f}, - -{1.158039f, -0.724592f} -}; - -static final float[/* SIZ_TAB_HUP_S */] tab_hup_s = { --0.005772f, -0.087669f, -0.965882f, --0.048753f, --0.014793f, -0.214886f, -0.868791f, --0.065537f, --0.028507f, -0.374334f, -0.723418f, --0.060834f, --0.045567f, -0.550847f, -0.550847f, --0.045567f, --0.060834f, -0.723418f, -0.374334f, --0.028507f, --0.065537f, -0.868791f, -0.214886f, --0.014793f, --0.048753f, -0.965882f, -0.087669f, --0.005772f -}; - -static final float[/* SIZ_TAB_HUP_L */] tab_hup_l = { --0.001246f, -0.002200f, --0.004791f, -0.009621f, --0.017685f, -0.031212f, --0.057225f, -0.135470f, -0.973955f, --0.103495f, -0.048663f, --0.027090f, -0.015280f, --0.008160f, -0.003961f, --0.001827f, --0.002388f, -0.004479f, --0.009715f, -0.019261f, --0.035118f, -0.061945f, --0.115187f, -0.294161f, -0.898322f, --0.170283f, -0.083211f, --0.046645f, -0.026210f, --0.013854f, -0.006641f, --0.003099f, --0.003277f, -0.006456f, --0.013906f, -0.027229f, --0.049283f, -0.086990f, --0.164590f, -0.464041f, -0.780309f, --0.199879f, -0.100795f, --0.056792f, -0.031761f, --0.016606f, -0.007866f, --0.003740f, --0.003770f, -0.007714f, --0.016462f, -0.031849f, --0.057272f, -0.101294f, --0.195755f, -0.630993f, -0.630993f, --0.195755f, -0.101294f, --0.057272f, -0.031849f, --0.016462f, -0.007714f, --0.003770f, --0.003740f, -0.007866f, --0.016606f, -0.031761f, --0.056792f, -0.100795f, --0.199879f, -0.780309f, -0.464041f, --0.164590f, -0.086990f, --0.049283f, -0.027229f, --0.013906f, -0.006456f, --0.003277f, --0.003099f, -0.006641f, --0.013854f, -0.026210f, --0.046645f, -0.083211f, --0.170283f, -0.898322f, -0.294161f, --0.115187f, -0.061945f, --0.035118f, -0.019261f, --0.009715f, -0.004479f, --0.002388f, --0.001827f, -0.003961f, --0.008160f, -0.015280f, --0.027090f, -0.048663f, --0.103495f, -0.973955f, -0.135470f, --0.057225f, -0.031212f, --0.017685f, -0.009621f, --0.004791f, -0.002200f, --0.001246f -}; - -static final int[/* NCODE1 */] map1 = { - 5, 1, 4, 7, 3, 0, 6, 2}; - -static final int[/* NCODE2 */] map2 = { - 4, 6, 0, 2,12,14, 8,10,15,11, 9,13, 7, 3, 1, 5}; - -static final int[/* NCODE1 */] imap1 = { - 5, 1, 7, 4, 2, 0, 6, 3}; -static final int[/* NCODE2 */] imap2 = { - 2,14, 3,13, 0,15, 1,12, 6,10, 7, 9, 4,11, 5, 8}; - -static final int[/* PRM_SIZE */] bitsno = {1+Ld8k.NC0_B, /* MA + 1st stage */ - Ld8k.NC1_B*2, /* 2nd stage */ - 8,1, 13,4, 7, /* first subframe */ - 5, 13,4, 7}; /* second subframe */ - -/* filter coefficients (fc = 140 Hz) */ -static final float[/* 3 */] b140 = {0.92727435E+00f, -0.18544941E+01f, 0.92727435E+00f}; -static final float[/* 3 */] a140 = {1.00000000E+00f, 0.19059465E+01f, -0.91140240E+00f}; - -/* filter coefficients (fc = 100 Hz ) */ -static final float[/* 3 */] b100 = {0.93980581E+00f, -0.18795834E+01f, 0.93980581E+00f}; -static final float[/* 3 */] a100 = {1.00000000E+00f, 0.19330735E+01f, -0.93589199E+00f}; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Taming.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Taming.java deleted file mode 100644 index 07c1c8fdb..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Taming.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -/** - * Taming functions. - * - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class Taming -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : TAMING.C - Used for the floating point version of both - G.729 main body and G.729A -*/ - -private final float[] exc_err = new float[4]; - -void init_exc_err() -{ - int i; - for(i=0; i<4; i++) exc_err[i] = 1.0f; -} - -/** - * Computes the accumulated potential error in the - * adaptive codebook contribution - * - * @param t0 (i) integer part of pitch delay - * @param t0_frac (i) fractional part of pitch delay - * @return flag set to 1 if taming is necessary - */ -int test_err( -int t0, -int t0_frac -) -{ - float INV_L_SUBFR = Ld8k.INV_L_SUBFR; - int L_INTER10 = Ld8k.L_INTER10; - int L_SUBFR = Ld8k.L_SUBFR; - float THRESH_ERR = Ld8k.THRESH_ERR; - - int i, t1, zone1, zone2, flag; - float maxloc; - - t1 = (t0_frac > 0) ? (t0+1) : t0; - - i = t1 - L_SUBFR - L_INTER10; - if(i < 0) i = 0; - zone1 = (int) ( (float)i * INV_L_SUBFR); - - i = t1 + L_INTER10 - 2; - zone2 = (int)( (float)i * INV_L_SUBFR); - - maxloc = -1.0f; - flag = 0 ; - for(i=zone2; i>=zone1; i--) { - if(exc_err[i] > maxloc) maxloc = exc_err[i]; - } - if(maxloc > THRESH_ERR) { - flag = 1; - } - return(flag); -} - -/** - * Maintains the memory used to compute the error - * function due to an adaptive codebook mismatch between encoder and - * decoder - * - * @param gain_pit (i) pitch gain - * @param t0 (i) integer part of pitch delay - */ -void update_exc_err( - float gain_pit, - int t0 -) -{ - float INV_L_SUBFR = Ld8k.INV_L_SUBFR; - int L_SUBFR = Ld8k.L_SUBFR; - - int i, zone1, zone2, n; - float worst, temp; - - worst = (float)-1.; - - n = t0- L_SUBFR; - if(n < 0) { - temp = 1.0f + gain_pit * exc_err[0]; - if(temp > worst) worst = temp; - temp = 1.0f + gain_pit * temp; - if(temp > worst) worst = temp; - } - - else { - zone1 = (int) ((float)n * INV_L_SUBFR); - - i = t0 - 1; - zone2 = (int)((float)i * INV_L_SUBFR); - - for(i = zone1; i <= zone2; i++) { - temp = 1.0f + gain_pit * exc_err[i]; - if(temp > worst) worst = temp; - } - } - - for(i=3; i>=1; i--) exc_err[i] = exc_err[i-1]; - exc_err[0] = worst; -} - -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Util.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Util.java deleted file mode 100644 index 173a12ccf..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/g729/Util.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -/* - * WARNING: The use of G.729 may require a license fee and/or royalty fee in - * some countries and is licensed by - * SIPRO Lab Telecom. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.g729; - -import java.io.*; - -/** - * Auxiliary functions. - * - * @author Lubomir Marinov (translation of ITU-T C source code to Java) - */ -class Util -{ - -/* ITU-T G.729 Software Package Release 2 (November 2006) */ -/* - ITU-T G.729 Annex C - Reference C code for floating point - implementation of G.729 - Version 1.01 of 15.September.98 -*/ - -/* ----------------------------------------------------------------------- - COPYRIGHT NOTICE ----------------------------------------------------------------------- - ITU-T G.729 Annex C ANSI C source code - Copyright (C) 1998, AT&T, France Telecom, NTT, University of - Sherbrooke. All rights reserved. - ----------------------------------------------------------------------- -*/ - -/* - File : UTIL.C - Used for the floating point version of both - G.729 main body and G.729A -*/ - -/** - * Assigns the value zero to element of the specified array of floats. - * The number of components set to zero equal to the length argument. - * - * @param x (o) : vector to clear - * @param L (i) : length of vector - */ -static void set_zero( - float x[], - int L -) -{ - set_zero(x, 0, L); -} - -/** - * Assigns the value zero to element of the specified array of floats. - * The number of components set to zero equal to the length argument. - * The components at positions offset through offset+length-1 in the - * array are set to zero. - * - * @param x (o) : vector to clear - * @param offset (i) : offset of vector - * @param length (i) : length of vector - */ -static void set_zero(float[] x, int offset, int length) -{ - for (int i = offset, toIndex = offset + length; i < toIndex; i++) - x[i] = 0.0f; -} - -/** - * Copies an array from the specified x array, to the specified y array. - * The number of components copied is equal to the length argument. - * - * @param x (i) : input vector - * @param y (o) : output vector - * @param L (i) : vector length - */ -static void copy( - float x[], - float y[], - int L -) -{ - copy(x, 0, y, L); -} - -/** - * Copies an array from the specified source array, - * beginning at the specified destination array. - * A subsequence of array components are copied from the source array referenced - * by x to the destination array referenced by y. - * The number of components copied is equal to the length argument. - * The components at positions x_offset through x_offset+length-1 in the source - * array are copied into positions 0 through length-1, - * respectively, of the destination array. - * - * @param x (i) : input vector - * @param x_offset (i) : input vector offset - * @param y (o) : output vector - * @param L (i) : vector length - */ -static void copy(float[] x, int x_offset, float[] y, int L) -{ - copy(x, x_offset, y, 0, L); -} - -/** - * Copies an array from the specified source array, - * beginning at the specified position, - * to the specified position of the destination array. - * A subsequence of array components are copied from the source array referenced - * by x to the destination array referenced by y. - * The number of components copied is equal to the length argument. - * The components at positions x_offset through x_offset+length-1 in the source - * array are copied into positions y_offset through y_offset+length-1, - * respectively, of the destination array. - * - * @param x (i) : input vector - * @param x_offset (i) : input vector offset - * @param y (o) : output vector - * @param y_offset (i) : output vector offset - * @param L (i) : vector length - */ -static void copy(float[] x, int x_offset, float[] y, int y_offset, int L) -{ - int i; - - for (i = 0; i < L; i++) - y[y_offset + i] = x[x_offset + i]; -} - -/* Random generator */ -private static short seed = 21845; - -/** - * Return random short. - * - * @return random short - */ -static short random_g729() -{ - seed = (short) (seed * 31821L + 13849L); - - return(seed); -} - -/** - * Write data in fp - * - * @param data - * @param length - * @param fp - * @throws java.io.IOException - */ -static void fwrite(short[] data, int length, OutputStream fp) - throws IOException -{ - byte[] bytes = new byte[2]; - - for (int i = 0; i < length; i++) - { - int value = data[i]; - bytes[0] = (byte) (value & 0xFF); - bytes[1] = (byte) (value >> 8); - fp.write(bytes); - } -} - -/** - * Read data from fp. - * - * @param data - * @param length - * @param fp - * @return length of resulting data array - * @throws java.io.IOException - */ -static int fread(short[] data, int length, InputStream fp) - throws IOException -{ - byte[] bytes = new byte[2]; - int readLength = 0; - - for (int i = 0; i < length; i++) - { - if (fp.read(bytes) != 2) - break; - data[i] = (short) ((bytes[1] << 8) | (bytes[0] & 0x00FF)); - readLength++; - } - return readLength; -} -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/DePacketizer.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/DePacketizer.java deleted file mode 100644 index c56885dfe..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/DePacketizer.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.gsm; - -import javax.media.*; -import javax.media.format.*; - -import net.sf.fmj.media.*; - -/** - * - * DePacketizer for GSM/RTP. Doesn't have to do much, just copies input - * to output. Uses buffer-swapping observed in debugging - * and seen in other open-source DePacketizer implementations. - * @author Martin Harvan - * @author Damian Minkov - */ -public class DePacketizer - extends AbstractDePacketizer -{ - @Override - public String getName() - { - return "GSM DePacketizer"; - } - - /** - * Constructs a new DePacketizer. - */ - public DePacketizer() - { - super(); - this.inputFormats = new Format[] { - new AudioFormat( - AudioFormat.GSM_RTP, - 8000, - 8, - 1, - Format.NOT_SPECIFIED, - AudioFormat.SIGNED, - 264, - Format.NOT_SPECIFIED, - Format.byteArray)}; - } - - // TODO: move to base class? - protected Format[] outputFormats = new Format[] { - new AudioFormat( - AudioFormat.GSM, - 8000, - 8, - 1, - -1, - AudioFormat.SIGNED, - 264, - -1.0, - Format.byteArray)}; - - @Override - public Format[] getSupportedOutputFormats(Format input) - { - if (input == null) - return outputFormats; - else - { - if (!(input instanceof AudioFormat)) - { - return new Format[] {null}; - } - final AudioFormat inputCast = (AudioFormat) input; - if (!inputCast.getEncoding().equals(AudioFormat.GSM_RTP)) - { - return new Format[] {null}; - } - final AudioFormat result = - new AudioFormat( - AudioFormat.GSM, - inputCast.getSampleRate(), - inputCast.getSampleSizeInBits(), - inputCast.getChannels(), - inputCast.getEndian(), - inputCast.getSigned(), - inputCast.getFrameSizeInBits(), - inputCast.getFrameRate(), - inputCast.getDataType()); - - return new Format[] {result}; - } - } - - @Override - public void open() - { - } - - @Override - public void close() - { - } - - @Override - public Format setInputFormat(Format f) - { - return super.setInputFormat(f); - } - - @Override - public Format setOutputFormat(Format f) - { - return super.setOutputFormat(f); - } - - -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/Decoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/Decoder.java deleted file mode 100644 index 94090b273..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/Decoder.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.gsm; - -import javax.media.*; -import javax.media.format.*; - -import net.sf.fmj.media.*; - -/** - * GSM to PCM java decoder. - * Decodes GSM frame (33 bytes long) into 160 16-bit PCM samples (320 bytes). - * - * @author Martin Harvan - * @author Damian Minkov - */ -public class Decoder - extends AbstractCodec -{ - private Buffer innerBuffer = new Buffer(); - private static final int PCM_BYTES = 320; - private static final int GSM_BYTES = 33; - private int innerDataLength = 0; - - byte[] innerContent; - - @Override - public String getName() - { - return "GSM Decoder"; - } - - /** - * Constructs a new Decoder. - */ - public Decoder() - { - super(); - this.inputFormats = new Format[] - { - new AudioFormat( - AudioFormat.GSM, - 8000, - 8, - 1, - Format.NOT_SPECIFIED, - AudioFormat.SIGNED, - 264, - Format.NOT_SPECIFIED, - Format.byteArray) - }; - } - - // TODO: move to base class? - protected Format[] outputFormats = new Format[] - { - new AudioFormat( - AudioFormat.LINEAR, - 8000, - 16, - 1, - Format.NOT_SPECIFIED, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED, - Format.byteArray) - }; - - @Override - public Format setOutputFormat(Format format) - { - if (!(format instanceof AudioFormat)) - return null; - - final AudioFormat audioFormat = (AudioFormat) format; - return super.setOutputFormat( - AudioFormatCompleter.complete(audioFormat)); - } - - @Override - public Format[] getSupportedOutputFormats(Format input) - { - if (input == null) - return outputFormats; - else - { - if (!(input instanceof AudioFormat)) - { - return new Format[]{null}; - } - - final AudioFormat inputCast = (AudioFormat) input; - if (!inputCast.getEncoding().equals(AudioFormat.GSM) - || (inputCast.getSampleSizeInBits() != 8 - && inputCast.getSampleSizeInBits() != Format.NOT_SPECIFIED) - || (inputCast.getChannels() != 1 - && inputCast.getChannels() != Format.NOT_SPECIFIED) - || (inputCast.getSigned() != AudioFormat.SIGNED - && inputCast.getSigned() != Format.NOT_SPECIFIED) - || (inputCast.getFrameSizeInBits() != 264 - && inputCast.getFrameSizeInBits() != Format.NOT_SPECIFIED) - || (inputCast.getDataType() != null - && inputCast.getDataType() != Format.byteArray)) - { - return new Format[] {null}; - } - - final AudioFormat result = new AudioFormat( - AudioFormat.LINEAR, - inputCast.getSampleRate(), - 16, - 1, - inputCast.getEndian(), - AudioFormat.SIGNED, - 16, - Format.NOT_SPECIFIED, - Format.byteArray); - - return new Format[]{result}; - } - } - - @Override - public void open() - { - - } - - @Override - public void close() - { - - } - - private static final boolean TRACE = false; - - @Override - public int process(Buffer inputBuffer, Buffer outputBuffer) - { - byte [] inputContent=new byte[inputBuffer.getLength()]; - - System.arraycopy( - inputBuffer.getData(), - inputBuffer.getOffset(), - inputContent, - 0, - inputContent.length); - - - byte[] mergedContent = - mergeArrays((byte[]) innerBuffer.getData(), inputContent); - innerBuffer.setData(mergedContent); - innerBuffer.setLength(mergedContent.length); - innerDataLength = innerBuffer.getLength(); - - if (TRACE) dump("input ", inputBuffer); - - if (!checkInputBuffer(inputBuffer)) - { - return BUFFER_PROCESSED_FAILED; - } - - if (isEOM(inputBuffer)) - { - propagateEOM(outputBuffer); - return BUFFER_PROCESSED_OK; - } - - if (TRACE) dump("input ", inputBuffer); - - if (!checkInputBuffer(inputBuffer)) - { - return BUFFER_PROCESSED_FAILED; - } - - if (isEOM(inputBuffer)) { - propagateEOM(outputBuffer); - return BUFFER_PROCESSED_OK; - } - - final int result; - byte[] outputBufferData = (byte[]) outputBuffer.getData(); - - if (outputBufferData == null - || outputBufferData.length < - PCM_BYTES * innerBuffer.getLength() / GSM_BYTES) - { - outputBufferData = new byte[ - PCM_BYTES * (innerBuffer.getLength() / GSM_BYTES)]; - outputBuffer.setData(outputBufferData); - } - - if (innerBuffer.getLength() < GSM_BYTES) - { - result = OUTPUT_BUFFER_NOT_FILLED; - } else - { - final boolean bigEndian = - ((AudioFormat) outputFormat).getEndian() - == AudioFormat.BIG_ENDIAN; - - outputBufferData = new byte[ - PCM_BYTES * (innerBuffer.getLength() / GSM_BYTES)]; - outputBuffer.setData(outputBufferData); - outputBuffer.setLength( - PCM_BYTES * (innerBuffer.getLength() / GSM_BYTES)); - - GSMDecoderUtil.gsmDecode( - bigEndian, - (byte[]) innerBuffer.getData(), - inputBuffer.getOffset(), - innerBuffer.getLength(), - outputBufferData); - - outputBuffer.setFormat(outputFormat); - result = BUFFER_PROCESSED_OK; - byte[] temp = new byte[ - innerDataLength - (innerDataLength / GSM_BYTES) * GSM_BYTES]; - innerContent = (byte[]) innerBuffer.getData(); - System.arraycopy( - innerContent, - (innerDataLength / GSM_BYTES) * GSM_BYTES, - temp, - 0, - temp.length); - outputBuffer.setOffset(0); - - innerBuffer.setLength(temp.length); - innerBuffer.setData(temp); - } - - if (TRACE) - { - dump("input ", inputBuffer); - dump("output", outputBuffer); - } - return result; - } - - private byte[] mergeArrays(byte[] arr1, byte[] arr2) - { - if (arr1 == null) return arr2; - if (arr2 == null) return arr1; - byte[] merged = new byte[arr1.length + arr2.length]; - System.arraycopy(arr1, 0, merged, 0, arr1.length); - System.arraycopy(arr2, 0, merged, arr1.length, arr2.length); - return merged; - } - - @Override - public Format setInputFormat(Format arg0) - { - // TODO: force sample size, etc - return super.setInputFormat(arg0); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/Encoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/Encoder.java deleted file mode 100644 index fff44b246..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/Encoder.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.gsm; - -import net.sf.fmj.media.*; - -import javax.media.*; -import javax.media.Format; -import javax.media.format.*; - -/** - * GSM encoder Codec. Encodes 160 16-bit PCM samples into array of - * 33 bytes (GSM frame). - * - * @author Martin Harvan - * @author Damian Minkov - */ -public class Encoder - extends AbstractCodec -{ - private Buffer innerBuffer = new Buffer(); - private static final int PCM_BYTES = 320; - private static final int GSM_BYTES = 33; - private int innerDataLength = 0; - byte[] innerContent; - - @Override - public String getName() - { - return "GSM Encoder"; - } - - /** - * Constructs a new Encoder. - */ - public Encoder() - { - super(); - this.inputFormats = new Format[]{ - new AudioFormat( - AudioFormat.LINEAR, - 8000, - 16, - 1, - AudioFormat.BIG_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED, - Format.byteArray) - }; - - } - - // TODO: move to base class? - protected Format[] outputFormats = new Format[]{ - new AudioFormat( - AudioFormat.GSM, - 8000, - 8, - 1, - Format.NOT_SPECIFIED, - AudioFormat.SIGNED, - 264, - Format.NOT_SPECIFIED, - Format.byteArray)}; - - @Override - public Format[] getSupportedOutputFormats(Format input) - { - if (input == null) - { - return outputFormats; - } else - { - if (!(input instanceof AudioFormat)) - { - return new Format[]{null}; - } - final AudioFormat inputCast = (AudioFormat) input; - final AudioFormat result = new AudioFormat( - AudioFormat.GSM, - inputCast.getSampleRate(), - 8, - 1, - inputCast.getEndian(), - AudioFormat.SIGNED, - 264, - inputCast.getFrameRate(), - Format.byteArray); - - return new Format[]{result}; - } - } - - @Override - public void open() - { - } - - @Override - public void close() - { - } - - private static final boolean TRACE = false; - - @Override - public int process(Buffer inputBuffer, Buffer outputBuffer) - { - byte [] inputContent=new byte[inputBuffer.getLength()]; - - System.arraycopy( - inputBuffer.getData(), - inputBuffer.getOffset(), - inputContent, - 0, - inputContent.length); - - byte[] mergedContent = mergeArrays( - (byte[]) innerBuffer.getData(), inputContent); - innerBuffer.setData(mergedContent); - innerBuffer.setLength(mergedContent.length); - innerDataLength = innerBuffer.getLength(); - - if (TRACE) dump("input ", inputBuffer); - - if (!checkInputBuffer(inputBuffer)) - { - return BUFFER_PROCESSED_FAILED; - } - - if (isEOM(inputBuffer)) - { - propagateEOM(outputBuffer); - return BUFFER_PROCESSED_OK; - } - - final int result; - byte[] outputBufferData = (byte[]) outputBuffer.getData(); - - if (outputBufferData == null - || outputBufferData.length < - GSM_BYTES * innerDataLength / PCM_BYTES) - { - outputBufferData = new byte[ - GSM_BYTES * (innerDataLength / PCM_BYTES)]; - outputBuffer.setData(outputBufferData); - } - - if (innerDataLength < PCM_BYTES) - { - result = OUTPUT_BUFFER_NOT_FILLED; - System.out.println("Not filled"); - } else - { - final boolean bigEndian = ((AudioFormat) outputFormat).getEndian() - == AudioFormat.BIG_ENDIAN; - - outputBufferData = new byte[ - GSM_BYTES * (innerDataLength / PCM_BYTES)]; - outputBuffer.setData(outputBufferData); - outputBuffer.setLength(GSM_BYTES * (innerDataLength / PCM_BYTES)); - - GSMEncoderUtil.gsmEncode( - bigEndian, - (byte[])innerBuffer.getData(), - innerBuffer.getOffset(), - innerDataLength, - outputBufferData); - - outputBuffer.setFormat(outputFormat); - outputBuffer.setData(outputBufferData); - result = BUFFER_PROCESSED_OK; - byte[] temp = new byte[ - innerDataLength - (innerDataLength / PCM_BYTES) * PCM_BYTES]; - innerContent = (byte[]) innerBuffer.getData(); - System.arraycopy( - innerContent, - (innerDataLength / PCM_BYTES) * PCM_BYTES, - temp, - 0, - temp.length); - - outputBuffer.setOffset(0); - innerBuffer.setLength(temp.length); - innerBuffer.setData(temp); - } - - if (TRACE) - { - dump("input ", inputBuffer); - dump("output", outputBuffer); - } - return result; - } - - private byte[] mergeArrays(byte[] arr1, byte[] arr2) - { - if (arr1 == null) return arr2; - if (arr2 == null) return arr1; - byte[] merged = new byte[arr1.length + arr2.length]; - System.arraycopy(arr1, 0, merged, 0, arr1.length); - System.arraycopy(arr2, 0, merged, arr1.length, arr2.length); - return merged; - } - - - @Override - public Format setInputFormat(Format f) - { - //TODO: force sample size, etc - return super.setInputFormat(f); - } - - @Override - public Format setOutputFormat(Format f) - { - return super.setOutputFormat(f); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/GSMDecoderUtil.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/GSMDecoderUtil.java deleted file mode 100644 index 56eb32f0b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/GSMDecoderUtil.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.gsm; - -import org.rubycoder.gsm.*; - - -/** - * GSMDecoderUtil class - * - * @author Martin Harvan - * @author Damian Minkov - */ -public class GSMDecoderUtil -{ - private static GSMDecoder decoder = new GSMDecoder(); - private static final int GSM_BYTES = 33; - private static final int PCM_INTS = 160; - private static final int PCM_BYTES = 320; - - /** - * Decode GSM data. - * - * @param bigEndian if the data are in big endian format - * @param data the GSM data - * @param offset offset - * @param length length of the data - * @param decoded decoded data array - */ - public static void gsmDecode(boolean bigEndian, - byte[] data, - int offset, - int length, - byte[] decoded) - { - for (int i = 0; i < length / GSM_BYTES; i++) - { - int[] output = new int[PCM_INTS]; - byte[] input = new byte[GSM_BYTES]; - System.arraycopy(data, i * GSM_BYTES, input, 0, GSM_BYTES); - try - { - decoder.decode(input, output); - } catch (InvalidGSMFrameException e) - { - e.printStackTrace(); - } - for (int j = 0; j < PCM_INTS; j++) - { - int index = j << 1; - if (bigEndian) - { - decoded[index + i * PCM_BYTES] - = (byte) ((output[j] & 0xff00) >> 8); - decoded[++index + (i * PCM_BYTES)] - = (byte) ((output[j] & 0x00ff)); - } else - { - decoded[index + i * PCM_BYTES] - = (byte) ((output[j] & 0x00ff)); - decoded[++index + (i * PCM_BYTES)] - = (byte) ((output[j] & 0xff00) >> 8); - } - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/GSMEncoderUtil.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/GSMEncoderUtil.java deleted file mode 100644 index 701094602..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/GSMEncoderUtil.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.gsm; - -import org.rubycoder.gsm.*; - -/** - * GSMEncoderUtil class - * - * @author Martin Harvan - * @author Damian Minkov - */ -public class GSMEncoderUtil { - - private static GSMEncoder encoder = new GSMEncoder(); - /** - * number of bytes in GSM frame - */ - private static final int GSM_BYTES = 33; - - /** - * number of PCM bytes needed to encode - */ - private static final int PCM_BYTES = 320; - - /** - * number of PCM ints needed to encode - */ - private static final int PCM_INTS = 160; - - /** - * Encode data to GSM. - * - * @param bigEndian if the data is in big endian format - * @param data data to encode - * @param offset offset - * @param length length of data - * @param decoded array of encoded data. - */ - public static void gsmEncode( - boolean bigEndian, - byte[] data, - int offset, - int length, - byte[] decoded) - { - for (int i = offset; i < length / PCM_BYTES; i++) - { - int[] input = new int[PCM_INTS]; - byte[] output = new byte[GSM_BYTES]; - - for (int j = 0; j < PCM_INTS; j++) { - int index = j << 1; - - input[j] = data[i * PCM_BYTES + index++]; - - input[j] <<= 8; - input[j] |= data[i * PCM_BYTES + index++] & 0xFF; - } - encoder.encode(output, input); - System.arraycopy(output, 0, decoded, i * GSM_BYTES, GSM_BYTES); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/Packetizer.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/Packetizer.java deleted file mode 100644 index 5e34d4b47..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/gsm/Packetizer.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.gsm; - -import javax.media.*; -import javax.media.format.*; - -import net.sf.fmj.media.*; - -/** - * GSM/RTP packetizer Codec. - * - * @author Martin Harvan - * @author Damian Minkov - */ -public class Packetizer - extends AbstractPacketizer -{ - private static final int PACKET_SIZE = 33; - - @Override - public String getName() - { - return "GSM Packetizer"; - } - - /** - * Constructs a new Packetizer. - */ - public Packetizer() - { - super(); - this.inputFormats = new Format[]{ - new AudioFormat( - AudioFormat.GSM, - 8000, - 8, - 1, - Format.NOT_SPECIFIED, - AudioFormat.SIGNED, - 264, - Format.NOT_SPECIFIED, - Format.byteArray)}; - } - - // TODO: move to base class? - protected Format[] outputFormats = new Format[]{ - new AudioFormat( - AudioFormat.GSM_RTP, - 8000, - 8, - 1, - Format.NOT_SPECIFIED, - AudioFormat.SIGNED, - 264, - Format.NOT_SPECIFIED, - Format.byteArray)}; - - @Override - public Format[] getSupportedOutputFormats(Format input) - { - if (input == null) - return outputFormats; - else - { - if (!(input instanceof AudioFormat)) - { - return new Format[]{null}; - } - final AudioFormat inputCast = (AudioFormat) input; - if (!inputCast.getEncoding().equals(AudioFormat.GSM) - || (inputCast.getSampleSizeInBits() != 8 - && inputCast.getSampleSizeInBits() != Format.NOT_SPECIFIED) - || (inputCast.getChannels() != 1 - && inputCast.getChannels() != Format.NOT_SPECIFIED) - || (inputCast.getFrameSizeInBits() != 264 - && inputCast.getFrameSizeInBits() != Format.NOT_SPECIFIED) - ) - { - return new Format[]{null}; - } - final AudioFormat result = - new AudioFormat( - AudioFormat.GSM_RTP, - inputCast.getSampleRate(), - 8, - 1, - inputCast.getEndian(), - inputCast.getSigned(), - 264, - inputCast.getFrameRate(), - inputCast.getDataType()); - - return new Format[]{result}; - } - } - - @Override - public void open() - { - setPacketSize(PACKET_SIZE); - } - - @Override - public void close() - { - } - - @Override - public Format setInputFormat(Format f) - { - return super.setInputFormat(f); - } - - @Override - public Format setOutputFormat(Format f) - { - return super.setOutputFormat(f); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/JavaDecoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/JavaDecoder.java deleted file mode 100644 index 1943b9c8c..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/JavaDecoder.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.ilbc; - -import java.util.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; - -/** - * Implements an iLBC decoder and RTP depacketizer as a {@link Codec}. - * - * @author Damian Minkov - * @author Lyubomir Marinov - */ -public class JavaDecoder - extends AbstractCodecExt -{ - - /** - * The ilbc_decoder adapted to Codec by this instance. - */ - private ilbc_decoder dec; - - /** - * The input length in bytes with which {@link #dec} has been initialized. - */ - private int inputLength; - - /** - * List of offsets for a "more than one" iLBC frame per RTP packet. - */ - private List offsets = new ArrayList(); - - /** - * Initializes a new iLBC JavaDecoder instance. - */ - public JavaDecoder() - { - super( - "iLBC Decoder", - AudioFormat.class, - new Format[] { new AudioFormat(AudioFormat.LINEAR) }); - - inputFormats - = new Format[] - { - new AudioFormat( - Constants.ILBC_RTP, - 8000, - 16, - 1, - Format.NOT_SPECIFIED /* endian */, - Format.NOT_SPECIFIED /* signed */) - }; - - addControl( - new com.sun.media.controls.SilenceSuppressionAdapter( - this, - false, - false)); - } - - /** - * Implements {@link AbstractCodecExt#doClose()}. - * - * @see AbstractCodecExt#doClose() - */ - protected void doClose() - { - dec = null; - inputLength = 0; - } - - /** - * Implements {@link AbstractCodecExt#doOpen()}. - * - * @see AbstractCodecExt#doOpen() - */ - protected void doOpen() - { - } - - /** - * Implements {@link AbstractCodecExt#doProcess(Buffer, Buffer)}. - * - * @param inputBuffer - * @param outputBuffer - * @return - * @see AbstractCodecExt#doProcess(Buffer, Buffer) - */ - protected int doProcess(Buffer inputBuffer, Buffer outputBuffer) - { - byte[] input = (byte[]) inputBuffer.getData(); - int inputLength = inputBuffer.getLength(); - - if(offsets.size() == 0 && - ((inputLength > ilbc_constants.NO_OF_BYTES_20MS && - inputLength != ilbc_constants.NO_OF_BYTES_30MS) || - inputLength > ilbc_constants.NO_OF_BYTES_30MS)) - { - int nb = 0; - int len = 0; - - if((inputLength % ilbc_constants.NO_OF_BYTES_20MS) == 0) - { - nb = (inputLength % ilbc_constants.NO_OF_BYTES_20MS); - len = ilbc_constants.NO_OF_BYTES_20MS; - } - else if((inputLength % ilbc_constants.NO_OF_BYTES_30MS) == 0) - { - nb = (inputLength % ilbc_constants.NO_OF_BYTES_30MS); - len = ilbc_constants.NO_OF_BYTES_30MS; - } - - if (this.inputLength != len) - initDec(len); - - for(int i = 0 ; i < nb ; i++) - { - offsets.add(new Integer(inputLength + (i * len))); - } - } - else - if (this.inputLength != inputLength) - initDec(inputLength); - - int outputLength = dec.ULP_inst.blockl * 2; - byte[] output = validateByteArraySize(outputBuffer, outputLength); - int outputOffset = 0; - - int offsetToAdd = 0; - - if(offsets.size() > 0) - offsetToAdd = offsets.remove(0).intValue(); - - dec.decode( - output, outputOffset, - input, inputBuffer.getOffset() + offsetToAdd, - (short) 1); - - updateOutput( - outputBuffer, - getOutputFormat(), outputLength, outputOffset); - int flags = BUFFER_PROCESSED_OK; - - if(offsets.size() > 0) - { - flags |= INPUT_BUFFER_NOT_CONSUMED; - } - - return flags; - } - - @Override - protected Format[] getMatchingOutputFormats(Format inputFormat) - { - AudioFormat inputAudioFormat = (AudioFormat) inputFormat; - - return - new AudioFormat[] - { - new AudioFormat( - AudioFormat.LINEAR, - inputAudioFormat.getSampleRate(), - 16, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED) - }; - } - - /** - * Initializes {@link #dec} so that it processes a specific number of bytes - * as input. - * - * @param inputLength the number of bytes of input to be processed by - * {@link #dec} - */ - private void initDec(int inputLength) - { - int mode; - - switch (inputLength) - { - case ilbc_constants.NO_OF_BYTES_20MS: - mode = 20; - break; - case ilbc_constants.NO_OF_BYTES_30MS: - mode = 30; - break; - default: - throw new IllegalArgumentException("inputLength"); - } - - dec = new ilbc_decoder(mode, 1); - this.inputLength = inputLength; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/JavaEncoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/JavaEncoder.java deleted file mode 100644 index 6e50fd48c..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/JavaEncoder.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.ilbc; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; - -/** - * Implements an iLBC encoder and RTP packetizer as a {@link Codec}. - * - * @author Damian Minkov - * @author Lyubomir Marinov - */ -public class JavaEncoder - extends AbstractCodecExt -{ - /** - * The ilbc_encoder adapted to Codec by this instance. - */ - private ilbc_encoder enc; - - /** - * The input length in bytes with which {@link #enc} has been initialized. - */ - private int inputLength; - - /** - * The output length in bytes with which {@link #enc} has been initialized. - */ - private int outputLength; - - /** - * The input from previous calls to {@link #doProcess(Buffer, Buffer)} which - * has not been consumed yet. - */ - private byte[] prevInput; - - /** - * The number of bytes in {@link #prevInput} which have not been consumed - * yet. - */ - private int prevInputLength; - - /** - * The duration an output Buffer produced by this Codec. - */ - private int duration = 0; - - /** - * Initializes a new iLBC JavaEncoder instance. - */ - public JavaEncoder() - { - super( - "iLBC Encoder", - AudioFormat.class, - new Format[] - { - new AudioFormat( - Constants.ILBC_RTP, - 8000, - 16, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED) - }); - - inputFormats - = new Format[] - { - new AudioFormat( - AudioFormat.LINEAR, - 8000, - 16, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED) - }; - - addControl( - new com.sun.media.controls.SilenceSuppressionAdapter( - this, - false, - false)); - } - - /** - * Implements {@link AbstractCodecExt#doClose()}. - * - * @see AbstractCodecExt#doClose() - */ - protected void doClose() - { - enc = null; - outputLength = 0; - inputLength = 0; - prevInput = null; - prevInputLength = 0; - duration = 0; - } - - /** - * Implements {@link AbstractCodecExt#doOpen()}. - * - * @see AbstractCodecExt#doOpen() - */ - protected void doOpen() - { - int mode = Constants.ILBC_MODE; - - enc = new ilbc_encoder(mode); - - switch (mode) - { - case 20: - outputLength = ilbc_constants.NO_OF_BYTES_20MS; - break; - case 30: - outputLength = ilbc_constants.NO_OF_BYTES_30MS; - break; - default: - throw new IllegalStateException("mode"); - } - /* mode is 20 or 30 ms, duration must be in nanoseconds */ - duration = mode * 1000000; - inputLength = enc.ULP_inst.blockl * 2; - prevInput = new byte[inputLength]; - prevInputLength = 0; - } - - /** - * Get the output format. - * - * @return output format - * @see net.sf.fmj.media.AbstractCodec#getOutputFormat() - */ - @Override - public Format getOutputFormat() - { - Format outputFormat = super.getOutputFormat(); - - if ((outputFormat != null) - && (outputFormat.getClass() == AudioFormat.class)) - { - AudioFormat outputAudioFormat = (AudioFormat) outputFormat; - - outputFormat = setOutputFormat( - new AudioFormat( - outputAudioFormat.getEncoding(), - outputAudioFormat.getSampleRate(), - outputAudioFormat.getSampleSizeInBits(), - outputAudioFormat.getChannels(), - outputAudioFormat.getEndian(), - outputAudioFormat.getSigned(), - outputAudioFormat.getFrameSizeInBits(), - outputAudioFormat.getFrameRate(), - outputAudioFormat.getDataType()) - { - private static final long serialVersionUID = 0L; - - @Override - public long computeDuration(long length) - { - return JavaEncoder.this.duration; - } - }); - } - return outputFormat; - } - - /** - * Implements {@link AbstractCodecExt#doProcess(Buffer, Buffer)}. - * - * @param inputBuffer - * @param outputBuffer - * @return - * @see AbstractCodecExt#doProcess(Buffer, Buffer) - */ - protected int doProcess(Buffer inputBuffer, Buffer outputBuffer) - { - int inputLength = inputBuffer.getLength(); - byte[] input = (byte[]) inputBuffer.getData(); - int inputOffset = inputBuffer.getOffset(); - - if ((prevInputLength != 0) || (inputLength < this.inputLength)) - { - int bytesToCopy = this.inputLength - prevInputLength; - - if (bytesToCopy > inputLength) - bytesToCopy = inputLength; - System.arraycopy( - input, inputOffset, - prevInput, prevInputLength, - bytesToCopy); - prevInputLength += bytesToCopy; - - inputBuffer.setLength(inputLength - bytesToCopy); - inputBuffer.setOffset(inputOffset + bytesToCopy); - - inputLength = prevInputLength; - input = prevInput; - inputOffset = 0; - } - else - { - inputBuffer.setLength(inputLength - this.inputLength); - inputBuffer.setOffset(inputOffset + this.inputLength); - } - - int ret; - - if (inputLength >= this.inputLength) - { - /* - * If we are about to encode from prevInput, we already have - * prevInputLength taken into consideration by using prevInput in - * the first place and we have to make sure that we will not use the - * same prevInput more than once. - */ - prevInputLength = 0; - - int outputOffset = 0; - byte[] output - = validateByteArraySize( - outputBuffer, - outputOffset + outputLength); - - enc.encode(output, outputOffset, input, inputOffset); - - updateOutput( - outputBuffer, - getOutputFormat(), outputLength, outputOffset); - outputBuffer.setDuration(duration); - ret = BUFFER_PROCESSED_OK; - } - else - ret = OUTPUT_BUFFER_NOT_FILLED; - - if (inputBuffer.getLength() > 0) - ret |= INPUT_BUFFER_NOT_CONSUMED; - return ret; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/bitpack.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/bitpack.java deleted file mode 100644 index 92b17e6f5..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/bitpack.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.ilbc; - -/** - * @author Jean Lorchat - */ -class bitpack { - - int firstpart; - int rest; - - public bitpack() { - firstpart = 0; - rest = 0; - } - - public bitpack(int fp, int r) { - firstpart = fp; - rest = r; - } - - public int get_firstpart() { - return firstpart; - } - - public void set_firstpart(int fp) { - firstpart = fp; - } - - public int get_rest() { - return rest; - } - - public void set_rest(int r) { - rest = r; - } - -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/bitstream.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/bitstream.java deleted file mode 100644 index 0eb7fe0be..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/bitstream.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.ilbc; - -/** - * - * @author Jean Lorchat - * @author Lyubomir Marinov - */ -class bitstream { - - int bitcount; - - int pos; - - final byte [] buffer; - - /** - * The offset in {@link #buffer} of the first octet of this - * bitstream. - */ - final int buffer_off; - - /** - * The length in {@link #buffer} which is available to octets of this - * bitstream. - */ - final int buffer_len; - private int buffer_pos; - - public bitstream(byte[] buffer, int offset, int length) - { - pos = 0; - - this.buffer = buffer; - buffer_off = offset; - buffer_len = length; - - buffer_pos = buffer_off; - bitcount = 0; - } - - /*----------------------------------------------------------------* - * splitting an integer into first most significant bits and - * remaining least significant bits - *---------------------------------------------------------------*/ - - public bitpack packsplit( - int index, /* (i) the value to split */ - int bitno_firstpart, /* (i) number of bits in most - significant part */ - int bitno_total) /* (i) number of bits in full range - of value */ - { - int bitno_rest = bitno_total - bitno_firstpart; - bitpack rval = new bitpack (); - - int fp = index >>> bitno_rest; - - rval.set_firstpart(fp); - // *firstpart = *index>>(bitno_rest); - rval.set_rest(index - (rval.get_firstpart() << bitno_rest)); - // *rest = *index-(*firstpart<<(bitno_rest)); - return rval; - } - - /*----------------------------------------------------------------* - * combining a value corresponding to msb's with a value - * corresponding to lsb's - *---------------------------------------------------------------*/ - - int packcombine( - int index, /* (i/o) the msb value in the - combined value out */ - int rest, /* (i) the lsb value */ - int bitno_rest /* (i) the number of bits in the - lsb part */ - ){ - index = index << bitno_rest; - index += rest; - return index; - } - - /*----------------------------------------------------------------* - * packing of bits into bitstream, i.e., vector of bytes - *---------------------------------------------------------------*/ - - void dopack( -// unsigned char **bitstream, /* (i/o) on entrance pointer to -// place in bitstream to pack -// new data, on exit pointer -// to place in bitstream to -// pack future data */ - int index, /* (i) the value to pack */ - int bitno /* (i) the number of bits that the - value will fit within */ - ){ - int posLeft; - - // System.out.println("packing " + bitno + " bits (" + index + "), total packed : " + (bitcount+bitno) + " bits to date"); - bitcount += bitno; - - // System.out.println("packing tag " + index + " of length " + bitno + "bits from byte " + buffer_pos + "/" + buffer.length + " at " + pos + "th bit"); - - /* Clear the bits before starting in a new byte */ - - if (pos == 0) { - buffer[buffer_pos] = 0; - } - - while (bitno > 0) { - - /* Jump to the next byte if end of this byte is reached*/ - - if (pos == 8) { - pos = 0; - buffer_pos++; - buffer[buffer_pos] = 0; - } - - posLeft = 8 - pos; - - /* Insert index into the bitstream */ - - if (bitno <= posLeft) { - buffer[buffer_pos] |= (byte) (index << (posLeft - bitno)); - pos += bitno; - bitno = 0; - } else { - buffer[buffer_pos] |= (byte) (index >>> (bitno - posLeft)); - - pos = 8; - index -= ((index >>> (bitno - posLeft)) << (bitno - posLeft)); - - bitno -= posLeft; - } - } - } - - /*----------------------------------------------------------------* - * unpacking of bits from bitstream, i.e., vector of bytes - *---------------------------------------------------------------*/ - - public int unpack( - int bitno /* (i) number of bits used to - represent the value */ - ) - { - int BitsLeft; - int index=0; - - while (bitno > 0) { - - /* move forward in bitstream when the end of the - byte is reached */ - - if (pos == 8) { - pos = 0; - buffer_pos++; - } - - BitsLeft = 8 - pos; - - /* Extract bits to index */ - - if (BitsLeft >= bitno) { - index += ((((buffer[buffer_pos]) << (pos)) & 0xFF) >>> (8 - bitno)); - pos += bitno; - bitno = 0; - } else { - - if ((8 - bitno) > 0) { - index+=((((buffer[buffer_pos]) << (pos)) & 0xFF) >>> (8 - bitno)); - pos=8; - } else { - index+=(((buffer[buffer_pos] << pos) & 0xFF) << (bitno - 8)); - pos=8; - } - bitno -= BitsLeft; - } - } - - return index; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/ilbc_common.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/ilbc_common.java deleted file mode 100644 index 0774e4d10..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/ilbc_common.java +++ /dev/null @@ -1,722 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.ilbc; - -/** - * @author Jean Lorchat - */ -class ilbc_common { - - /*----------------------------------------------------------------* - * check for stability of lsf coefficients - *---------------------------------------------------------------*/ - - public static int LSF_check( /* (o) 1 for stable lsf vectors and 0 for - nonstable ones */ - float lsf[], /* (i) a table of lsf vectors */ - int dim, /* (i) the dimension of each lsf vector */ - int NoAn) /* (i) the number of lsf vectors in the - table */ - { - int k,n,m, Nit=2, change=0,pos; - float eps=(float)0.039; /* 50 Hz */ - float eps2=(float)0.0195; - float maxlsf=(float)3.14; /* 4000 Hz */ - float minlsf=(float)0.01; /* 0 Hz */ - - /* LSF separation check*/ - - for (n=0; nmaxlsf) { - lsf[pos]=maxlsf; - change=1; - } - } - } - } - - return change; - } - - /*----------------------------------------------------------------* - * decoding of the start state - *---------------------------------------------------------------*/ - - public static void StateConstructW( - int idxForMax, /* (i) 6-bit index for the quantization of - max amplitude */ - int idxVec[], /* (i) vector of quantization indexes */ - float syntDenum[], /* (i) synthesis filter denumerator */ - int syntDenum_idx, - float out[], /* (o) the decoded state vector */ - int out_idx, - int len /* (i) length of a state vector */ - ){ - float maxVal; - float [] tmpbuf = new float[ilbc_constants.LPC_FILTERORDER+2*ilbc_constants.STATE_LEN]; - //, *tmp, - int tmp; - float [] numerator = new float[ilbc_constants.LPC_FILTERORDER+1]; - float [] foutbuf = new float[ilbc_constants.LPC_FILTERORDER+2*ilbc_constants.STATE_LEN]; - //, *fout; - int fout; - int k,tmpi; - - /* decoding of the maximum value */ - - maxVal = ilbc_constants.state_frgqTbl[idxForMax]; - //System.out.println("idxForMax : " + idxForMax + "maxVal : " + maxVal); - maxVal = (float)Math.pow(10,maxVal) / 4.5f; - //System.out.println("maxVal : " + maxVal); - - /* initialization of buffers and coefficients */ - - for (int li = 0; li < ilbc_constants.LPC_FILTERORDER; li++) { - tmpbuf[li] = 0.0f; - foutbuf[li] = 0.0f; - } - // memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float)); - // memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float)); - - for (k=0; k < ilbc_constants.LPC_FILTERORDER; k++) { - numerator[k]=syntDenum[syntDenum_idx + ilbc_constants.LPC_FILTERORDER - k]; - //System.out.println("numerator-" + k + " = " + numerator[k] + " (( " + syntDenum[syntDenum_idx + ilbc_constants.LPC_FILTERORDER - k]); - } - - numerator[ilbc_constants.LPC_FILTERORDER]=syntDenum[syntDenum_idx]; - // tmp = &tmpbuf[LPC_FILTERORDER]; - tmp = ilbc_constants.LPC_FILTERORDER; - // fout = &foutbuf[LPC_FILTERORDER]; - fout = ilbc_constants.LPC_FILTERORDER; - - /* decoding of the sample values */ - - // for (int li = 0; li < idxVec.length; li++) - //System.out.println("idxVec["+li+"] = " + idxVec[li]); - - for (k=0; k= 0.5)){ - - - if (freq[0] <= 0.0f) { - freq[0] = (float)0.022; - } - - - if (freq[ilbc_constants.LPC_FILTERORDER - 1] >= 0.5) { - freq[ilbc_constants.LPC_FILTERORDER - 1] = (float)0.499; - } - - hlp = (freq[ilbc_constants.LPC_FILTERORDER - 1] - freq[0]) / - (float) (ilbc_constants.LPC_FILTERORDER - 1); - - for (i=1; i < ilbc_constants.LPC_FILTERORDER; i++) { - freq[i] = freq[i - 1] + hlp; - } - } - - for (int li = 0; li < ilbc_constants.LPC_HALFORDER; li++) { - a1[li] = 0.0f; - a2[li] = 0.0f; - b1[li] = 0.0f; - b2[li] = 0.0f; - } -// memset(a1, 0, LPC_HALFORDER*sizeof(float)); -// memset(a2, 0, LPC_HALFORDER*sizeof(float)); -// memset(b1, 0, LPC_HALFORDER*sizeof(float)); -// memset(b2, 0, LPC_HALFORDER*sizeof(float)); - for (int li = 0; li < ilbc_constants.LPC_HALFORDER + 1; li++) { - a[li] = 0.0f; - b[li] = 0.0f; - } -// memset(a, 0, (LPC_HALFORDER+1)*sizeof(float)); -// memset(b, 0, (LPC_HALFORDER+1)*sizeof(float)); - - /* p[i] and q[i] compute cos(2*pi*omega_{2j}) and - cos(2*pi*omega_{2j-1} in eqs. 4.2.2.2-1 and 4.2.2.2-2. - Note that for this code p[i] specifies the coefficients - used in .Q_A(z) while q[i] specifies the coefficients used - in .P_A(z) */ - - for (i = 0; i < ilbc_constants.LPC_HALFORDER; i++) { - p[i] = (float)Math.cos(ilbc_constants.TWO_PI * freq[2 * i]); - q[i] = (float)Math.cos(ilbc_constants.TWO_PI * freq[2 * i + 1]); - } - - a[0] = 0.25f; - b[0] = 0.25f; - - for (i= 0; i < ilbc_constants.LPC_HALFORDER; i++) { - a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i]; - b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i]; - a2[i] = a1[i]; - a1[i] = a[i]; - b2[i] = b1[i]; - b1[i] = b[i]; - } - - for (j=0; j < ilbc_constants.LPC_FILTERORDER; j++) { - - if (j == 0) { - a[0] = 0.25f; - b[0] = -0.25f; - } else { - a[0] = b[0] = 0.0f; - } - - for (i=0; i < ilbc_constants.LPC_HALFORDER; i++) { - a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i]; - b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i]; - a2[i] = a1[i]; - a1[i] = a[i]; - b2[i] = b1[i]; - b1[i] = b[i]; - } - - a_coef[j + 1] = 2 * (a[ilbc_constants.LPC_HALFORDER] + - b[ilbc_constants.LPC_HALFORDER]); - } - - a_coef[0] = 1.0f; - } - - /*----------------------------------------------------------------* - * Construct decoded vector from codebook and gains. - *---------------------------------------------------------------*/ - - /*----------------------------------------------------------------* - * interpolation between vectors - *---------------------------------------------------------------*/ - - public static void interpolate( - float out[], /* (o) the interpolated vector */ - float in1[], /* (i) the first vector for the - interpolation */ - float in2[], /* (i) the second vector for the - interpolation */ - int in2_idx, - float coef, /* (i) interpolation weights */ - int length) /* (i) length of all vectors */ - { - int i; - float invcoef; - - invcoef = 1.0f - coef; - for (i = 0; i < length; i++) { - out[i] = coef * in1[i] + invcoef * in2[i + in2_idx]; - // System.out.println("out["+i+"] devient " + out[i] + ", par " + - // coef + " * " + in1[i] + " + " + invcoef + " * " + in2[i + in2_idx]); - } - } - - /*----------------------------------------------------------------* - * lpc bandwidth expansion - *---------------------------------------------------------------*/ - - public static void bwexpand( - float out[], /* (o) the bandwidth expanded lpc - coefficients */ - int out_idx, - float in[], /* (i) the lpc coefficients before bandwidth - expansion */ - float coef, /* (i) the bandwidth expansion factor */ - int length) /* (i) the length of lpc coefficient vectors */ - { - int i; - float chirp; - - chirp = coef; - - out[out_idx] = in[0]; - for (i = 1; i < length; i++) { - out[i + out_idx] = chirp * in[i]; - chirp *= coef; - } - } - - public static void getCBvec( - float cbvec[], /* (o) Constructed codebook vector */ - float mem[], /* (i) Codebook buffer */ - int mem_idx, - int index, /* (i) Codebook index */ - int lMem, /* (i) Length of codebook buffer */ - int cbveclen) /* (i) Codebook vector length */ - { - int j, k, n, memInd, sFilt; - float [] tmpbuf = new float[ilbc_constants.CB_MEML]; - int base_size; - int ilow, ihigh; - float alfa, alfa1; - - /* Determine size of codebook sections */ - - base_size=lMem-cbveclen+1; - - if (cbveclen==ilbc_constants.SUBL) { - base_size+=cbveclen/2; - } - - /* No filter -> First codebook section */ - - if (index 1) { - gain[1] = gaindequant(gain_index[gain_index_idx + 1], - Math.abs(gain[0]), 16); - } - if (nStages > 2) { - gain[2] = gaindequant(gain_index[gain_index_idx + 2], - Math.abs(gain[1]), 8); - } - - /* codebook vector construction and construction of - total vector */ - - getCBvec(cbvec, mem, mem_idx, index[index_idx + 0], lMem, veclen); - for (j=0;j 1) { - for (k=1; k " + (pi - Out_idx)); - Out[po] -= a[pa] * Out[pi]; -// System.out.println("Pour un resultat de " + Out[po]); - pa++; - pi--; - } - for (j=i+1; j < ilbc_constants.LPC_FILTERORDER+1; j++) { - // *po-=(*pa++)*(*pm--); -// System.out.println("2 Soustraction a " + Out[po] + " de " + a[pa] + " * " + mem[pm]); - Out[po] -= a[pa] * mem[pm]; -// System.out.println("Pour un resultat de " + Out[po]); - pa++; - pm--; - } - po++; - } - - /* Filter last part where the state is entirely in - the output vector */ - - for (i = ilbc_constants.LPC_FILTERORDER; i < len; i++) { - // pi=&Out[i-1]; - pi = Out_idx + i - 1; - // pa=&a[1]; - pa = a_idx + 1; - for (j=1; j < ilbc_constants.LPC_FILTERORDER+1; j++) { - // *po-=(*pa++)*(*pi--); -// System.out.println("3 Soustraction a " + Out[po] + " de " + a[pa] + " * " + Out[pi]); - Out[po] -= a[pa] * Out[pi]; -// System.out.println("Pour un resultat de " + Out[po]); - pa++; - pi--; - } - po++; - } - - /* Update state vector */ - - System.arraycopy(Out, Out_idx + len - ilbc_constants.LPC_FILTERORDER, - mem, 0, ilbc_constants.LPC_FILTERORDER); -// memcpy(mem, &Out[len-LPC_FILTERORDER], -// LPC_FILTERORDER*sizeof(float)); - } - - /*---------------------------------------------------------------* - * interpolation of lsf coefficients for the decoder - *--------------------------------------------------------------*/ - - public void LSFinterpolate2a_dec( - float a[], /* (o) lpc coefficients for a sub-frame */ - float lsf1[], /* (i) first lsf coefficient vector */ - float lsf2[], /* (i) second lsf coefficient vector */ - int lsf2_idx, - float coef, /* (i) interpolation weight */ - int length /* (i) length of lsf vectors */ - ){ - float [] lsftmp = new float[ilbc_constants.LPC_FILTERORDER]; - - ilbc_common.interpolate(lsftmp, lsf1, lsf2, lsf2_idx, coef, length); - ilbc_common.lsf2a(a, lsftmp); - } - - /*---------------------------------------------------------------* - * obtain dequantized lsf coefficients from quantization index - *--------------------------------------------------------------*/ - - void SimplelsfDEQ( - float lsfdeq[], /* (o) dequantized lsf coefficients */ - int index[], /* (i) quantization index */ - int lpc_n /* (i) number of LPCs */ - ){ - int i, j, pos, cb_pos; - - /* decode first LSF */ - - pos = 0; - cb_pos = 0; - for (i = 0; i < ilbc_constants.LSF_NSPLIT; i++) { - for (j = 0; j < ilbc_constants.dim_lsfCbTbl[i]; j++) { - lsfdeq[pos + j] = ilbc_constants.lsfCbTbl[cb_pos + (int) - ((long)(index[i])*ilbc_constants.dim_lsfCbTbl[i] + j)]; - } - pos += ilbc_constants.dim_lsfCbTbl[i]; - cb_pos += ilbc_constants.size_lsfCbTbl[i]*ilbc_constants.dim_lsfCbTbl[i]; - } - - if (lpc_n>1) { - - /* decode last LSF */ - - pos = 0; - cb_pos = 0; - for (i = 0; i < ilbc_constants.LSF_NSPLIT; i++) { - for (j = 0; j < ilbc_constants.dim_lsfCbTbl[i]; j++) { - lsfdeq[ilbc_constants.LPC_FILTERORDER + pos + j] = - ilbc_constants.lsfCbTbl[cb_pos + (int) - ((long)(index[ilbc_constants.LSF_NSPLIT + i])* - ilbc_constants.dim_lsfCbTbl[i]) + j]; - } - pos += ilbc_constants.dim_lsfCbTbl[i]; - cb_pos += ilbc_constants.size_lsfCbTbl[i]*ilbc_constants.dim_lsfCbTbl[i]; - } - } - } - - /*----------------------------------------------------------------* - * obtain synthesis and weighting filters form lsf coefficients - *---------------------------------------------------------------*/ - - void DecoderInterpolateLSF( - float syntdenum[], /* (o) synthesis filter coefficients */ - float weightdenum[], /* (o) weighting denumerator - coefficients */ - float lsfdeq[], /* (i) dequantized lsf coefficients */ - int length) /* (i) length of lsf coefficient vector */ - { - int i, pos, lp_length; - float [] lp = new float[ilbc_constants.LPC_FILTERORDER + 1]; - int lsfdeq2; - - lsfdeq2 = length; -// lsfdeq2 = lsfdeq + length; - lp_length = length + 1; - - if (this.ULP_inst.mode==30) { - /* sub-frame 1: Interpolation between old and first */ - - LSFinterpolate2a_dec(lp, this.lsfdeqold, lsfdeq, 0, - ilbc_constants.lsf_weightTbl_30ms[0], length); - System.arraycopy(lp, 0, syntdenum, 0, lp_length); -// memcpy(syntdenum,lp,lp_length*sizeof(float)); - ilbc_common.bwexpand(weightdenum, 0, lp, ilbc_constants.LPC_CHIRP_WEIGHTDENUM, lp_length); - - /* sub-frames 2 to 6: interpolation between first - and last LSF */ - - pos = lp_length; - for (i = 1; i < 6; i++) { - LSFinterpolate2a_dec(lp, lsfdeq, lsfdeq, lsfdeq2, - ilbc_constants.lsf_weightTbl_30ms[i], length); - System.arraycopy(lp, 0, syntdenum, pos, lp_length); -// memcpy(syntdenum + pos,lp,lp_length*sizeof(float)); - ilbc_common.bwexpand(weightdenum, pos, lp, - ilbc_constants.LPC_CHIRP_WEIGHTDENUM, lp_length); - pos += lp_length; - } - } - else { - pos = 0; - for (i = 0; i < this.ULP_inst.nsub; i++) { - LSFinterpolate2a_dec(lp, this.lsfdeqold, - lsfdeq, 0, ilbc_constants.lsf_weightTbl_20ms[i], length); - System.arraycopy(lp, 0, syntdenum, pos, lp_length); -// memcpy(syntdenum+pos,lp,lp_length*sizeof(float)); - ilbc_common.bwexpand(weightdenum, pos, lp, ilbc_constants.LPC_CHIRP_WEIGHTDENUM, - lp_length); - pos += lp_length; - } - } - - /* update memory */ - - if (this.ULP_inst.mode==30) { - System.arraycopy(lsfdeq, lsfdeq2, this.lsfdeqold, 0, length); -// memcpy(iLBCdec_inst->lsfdeqold, lsfdeq2, length*sizeof(float)); - } else { - System.arraycopy(lsfdeq, 0, this.lsfdeqold, 0, length); -// memcpy(iLBCdec_inst->lsfdeqold, lsfdeq, length*sizeof(float)); - } - } - - - public void index_conv_dec(int index[]) /* (i/o) Codebook indexes */ - { - int k; - - for (k=1; k=44)&&(index[k]<108)) { - index[k]+=64; - } else if ((index[k]>=108)&&(index[k]<128)) { - index[k]+=128; - } else { - /* ERROR */ - } - } - } - - public void hpOutput( - float In[], /* (i) vector to filter */ - int len,/* (i) length of vector to filter */ - float Out[], /* (o) the resulting filtered vector */ - float mem[]) /* (i/o) the filter state */ - { - int i; - // float *pi, *po; - int pi, po; - - /* all-zero section*/ - -// pi = &In[0]; -// po = &Out[0]; - pi = 0; - po = 0; - - for (i=0; i dim1 ) { - hfl2=(dim1/2); - for (j=0; j= idatal) { - searchSegEndPos=idatal-ilbc_constants.ENH_BLOCKL-1; - } - corrdim=searchSegEndPos-searchSegStartPos+1; - - /* compute upsampled correlation (corr33) and find - location of max */ -// System.out.println("appel 1"); - mycorr1(corrVec, 0, idata, searchSegStartPos, - corrdim+ilbc_constants.ENH_BLOCKL-1, - idata,centerStartPos,ilbc_constants.ENH_BLOCKL); - enh_upsample(corrVecUps,corrVec,corrdim,ilbc_constants.ENH_FL0); - tloc=0; maxv=corrVecUps[0]; - for (i=1; imaxv) { - tloc=i; - maxv=corrVecUps[i]; - } - } - - /* make vector can be upsampled without ever running outside - bounds */ - - updStartPos= searchSegStartPos + - (float)tloc/(float)ilbc_constants.ENH_UPS0+1.0f; - tloc2=tloc/ilbc_constants.ENH_UPS0; - - if (tloc>tloc2*ilbc_constants.ENH_UPS0) { - tloc2++; - } - st=searchSegStartPos+tloc2-ilbc_constants.ENH_FL0; - - if (st<0) { - for (int li = 0; li < -st; li++) - vect[li] = 0.0f; -// memset(vect,0,-st*sizeof(float)); - System.arraycopy(idata, 0, vect, -st, (ilbc_constants.ENH_VECTL+st)); -// memcpy(&vect[-st],idata, (ilbc_constants.ENH_VECTL+st)*sizeof(float)); - } - else { - en=st+ilbc_constants.ENH_VECTL; - - if (en>idatal) { - System.arraycopy(idata, st, vect, 0, (ilbc_constants.ENH_VECTL-(en-idatal))); -// memcpy(vect, &idata[st], -// (ilbc_constants.ENH_VECTL-(en-idatal))*sizeof(float)); - for (int li = 0; li < en-idatal; li++) - vect[ilbc_constants.ENH_VECTL-(en-idatal)+li] = 0.0f; -// memset(&vect[ilbc_constants.ENH_VECTL-(en-idatal)], 0, -// (en-idatal)*sizeof(float)); - } - else { - System.arraycopy(idata, st, vect, 0, ilbc_constants.ENH_VECTL); -// memcpy(vect, &idata[st], ilbc_constants.ENH_VECTL*sizeof(float)); - } - } - fraction=tloc2*ilbc_constants.ENH_UPS0-tloc; - - /* compute the segment (this is actually a convolution) */ - -// System.out.println("appel 2"); -// System.out.println("longueur 1 : " + vect.length); -// System.out.println("distance 1 : " + 0); -// System.out.println("longueur 2 : " + ilbc_constants.polyphaserTbl.length); -// System.out.println("distance 2 : " + (2*ilbc_constants.ENH_FL0+1)*fraction); -// System.out.println("dimension 1 : " + ilbc_constants.ENH_VECTL); -// System.out.println("dimension 2 : " + (2 * ilbc_constants.ENH_FL0+1)); -// System.out.println("correlations de dimension " + seg.length); - mycorr1(seg, seg_idx, vect, 0, ilbc_constants.ENH_VECTL, - ilbc_constants.polyphaserTbl, - (2*ilbc_constants.ENH_FL0+1)*fraction, - 2*ilbc_constants.ENH_FL0+1); - - return updStartPos; - } - - /*----------------------------------------------------------------* - * find the smoothed output data - *---------------------------------------------------------------*/ - - public void smath( - float odata[], /* (o) smoothed output */ - int odata_idx, - float sseq[],/* (i) said second sequence of waveforms */ - int hl, /* (i) 2*hl+1 is sseq dimension */ - float alpha0)/* (i) max smoothing energy fraction */ - { - int i,k; - float w00,w10,w11,A,B,C,err,errs; - float [] surround = new float[ilbc_constants.BLOCKL_MAX]; /* shape contributed by other than - current */ - float [] wt = new float[2*ilbc_constants.ENH_HL+1]; /* waveform weighting to get - surround shape */ - float denom; - int psseq; - - /* create shape of contribution from all waveforms except the - current one */ - - for (i=1; i<=2*hl+1; i++) { - wt[i-1] = (float)0.5*(1 - (float)Math.cos(2*ilbc_constants.PI*i/(2*hl+2))); - } - wt[hl]=0.0f; /* for clarity, not used */ - for (i=0; i alpha0 * w00) { - if ( w00 < 1) { - w00=1; - } - denom = (w11*w00-w10*w10)/(w00*w00); - - if (denom > 0.0001f) { /* eliminates numerical problems - for if smooth */ - A = (float)Math.sqrt( (alpha0- alpha0*alpha0/4)/denom); - B = -alpha0/2 - A * w10/w00; - B = B+1; - } - else { /* essentially no difference between cycles; - smoothing not needed */ - A= 0.0f; - B= 1.0f; - } - - /* create smoothed sequence */ - - psseq=hl*ilbc_constants.ENH_BLOCKL; - for (i=0; i=0; q--) { - blockStartPos[q]=blockStartPos[q+1]-period[lagBlock[q+1]]; - lagBlock[q] = NearestNeighbor(plocs, - blockStartPos[q]+ - ilbc_constants.ENH_BLOCKL_HALF-period[lagBlock[q+1]], - periodl); - - - if (blockStartPos[q]-ilbc_constants.ENH_OVERHANG>=0) { - blockStartPos[q] = refiner(sseq,q*ilbc_constants.ENH_BLOCKL, idata, - idatal, centerStartPos, - blockStartPos[q], - period[lagBlock[q+1]]); - } else { - psseq=q*ilbc_constants.ENH_BLOCKL; -// psseq=sseq+q*ENH_BLOCKL; - for (int li = 0; li < ilbc_constants.ENH_BLOCKL; li++) - sseq[psseq+li] = 0.0f; -// memset(psseq, 0, ENH_BLOCKL*sizeof(float)); - } - } - - /* future */ - - for (i=0; i 0.0f) { - return (ftmp1*ftmp1/ftmp2); - } - else { - return 0.0f; - } - } - - /*----------------------------------------------------------------* - * interface for enhancer - *---------------------------------------------------------------*/ - - int enhancerInterface( - float out[], /* (o) enhanced signal */ - float in[]) /* (i) unenhanced signal */ - { - // float *enh_buf, *enh_period; (definis en global pour la classe) - int iblock, isample; - int lag=0, ilag, i, ioffset; - float cc, maxcc; - float ftmp1, ftmp2; - // float *inPtr, *enh_bufPtr1, *enh_bufPtr2; - int inPtr, enh_bufPtr1, enh_bufPtr2; - float [] plc_pred = new float[ilbc_constants.ENH_BLOCKL]; - - float [] lpState = new float[6]; - float [] downsampled = new float[(ilbc_constants.ENH_NBLOCKS*ilbc_constants.ENH_BLOCKL+120)/2]; - int inLen=ilbc_constants.ENH_NBLOCKS*ilbc_constants.ENH_BLOCKL+120; - int start, plc_blockl, inlag; - - // enh_buf=iLBCdec_inst->enh_buf; - // enh_period=iLBCdec_inst->enh_period; - - System.arraycopy(enh_buf, this.ULP_inst.blockl, - enh_buf, 0, - ilbc_constants.ENH_BUFL-this.ULP_inst.blockl); -// memmove(enh_buf, &enh_buf[iLBCdec_inst->blockl], -// (ENH_BUFL-iLBCdec_inst->blockl)*sizeof(float)); - - - System.arraycopy(in, 0, enh_buf, ilbc_constants.ENH_BUFL-this.ULP_inst.blockl, - this.ULP_inst.blockl); -// memcpy(&enh_buf[ENH_BUFL-this.ULP_inst.blockl], in, -// this.ULP_inst.blockl*sizeof(float)); - - if (this.ULP_inst.mode==30) - plc_blockl=ilbc_constants.ENH_BLOCKL; - else - plc_blockl=40; - - /* when 20 ms frame, move processing one block */ - ioffset=0; - if (this.ULP_inst.mode==20) ioffset=1; - - i=3-ioffset; - System.arraycopy(enh_period, i, enh_period, 0, ilbc_constants.ENH_NBLOCKS_TOT-i); -// memmove(enh_period, &enh_period[i], -// (ENH_NBLOCKS_TOT-i)*sizeof(float)); - - /* Set state information to the 6 samples right before - the samples to be downsampled. */ - - System.arraycopy(enh_buf, (ilbc_constants.ENH_NBLOCKS_EXTRA+ioffset)*ilbc_constants.ENH_BLOCKL-126, - lpState, 0, 6); -// memcpy(lpState, -// enh_buf+(ENH_NBLOCKS_EXTRA+ioffset)*ENH_BLOCKL-126, -// 6*sizeof(float)); - - /* Down sample a factor 2 to save computations */ - - DownSample(enh_buf, - (ilbc_constants.ENH_NBLOCKS_EXTRA+ioffset)*ilbc_constants.ENH_BLOCKL-120, - ilbc_constants.lpFilt_coefsTbl, inLen-ioffset*ilbc_constants.ENH_BLOCKL, - lpState, downsampled); - - /* Estimate the pitch in the down sampled domain. */ - for (iblock = 0; iblock maxcc) { - maxcc = cc; - lag = ilag; - } - } - - /* Store the estimated lag in the non-downsampled domain */ - enh_period[iblock+ilbc_constants.ENH_NBLOCKS_EXTRA+ioffset] = (float)lag*2; - - - } - - - /* PLC was performed on the previous packet */ - if (this.prev_enh_pl==1) { - - inlag=(int)enh_period[ilbc_constants.ENH_NBLOCKS_EXTRA+ioffset]; - - lag = inlag-1; - maxcc = xCorrCoef(in, 0, in, lag, plc_blockl); - for (ilag=inlag; ilag<=inlag+1; ilag++) { - cc = xCorrCoef(in, 0, in, ilag, plc_blockl); - if (cc > maxcc) { - maxcc = cc; - lag = ilag; - } - } - - enh_period[ilbc_constants.ENH_NBLOCKS_EXTRA+ioffset-1]=lag; - - /* compute new concealed residual for the old lookahead, - mix the forward PLC with a backward PLC from - the new frame */ - - // inPtr=&in[lag-1]; - inPtr = lag - 1; - - // enh_bufPtr1=&plc_pred[plc_blockl-1]; - enh_bufPtr1 = plc_blockl - 1; - - if (lag>plc_blockl) { - start=plc_blockl; - } else { - start=lag; - } - - for (isample = start; isample>0; isample--) { - // *enh_bufPtr1-- = *inPtr--; - plc_pred[enh_bufPtr1] = in[inPtr]; - enh_bufPtr1--; - inPtr--; - } - - // enh_bufPtr2=&enh_buf[ENH_BUFL-1-this.ULP_inst.blockl]; - enh_bufPtr2 = ilbc_constants.ENH_BUFL - 1 - this.ULP_inst.blockl; - for (isample = (plc_blockl-1-lag); isample>=0; isample--) { - // *enh_bufPtr1-- = *enh_bufPtr2--; - plc_pred[enh_bufPtr1] = enh_buf[enh_bufPtr2]; - enh_bufPtr1--; - enh_bufPtr2--; - } - - /* limit energy change */ - ftmp2=0.0f; - ftmp1=0.0f; - for (i=0;i 2.0f*ftmp2 && ftmp1 > 0.0) { - for (i=0;i 0.0f) { - cc[0] = ftmp1*ftmp1/ftmp2; - gc[0] = Math.abs(ftmp1 / ftmp2); - pm[0] = Math.abs(ftmp1) / - ((float)Math.sqrt(ftmp2)*(float)Math.sqrt(ftmp3)); - } - else { - cc[0] = 0.0f; - gc[0] = 0.0f; - pm[0] = 0.0f; - } - } - - public void doThePLC( - float PLCresidual[], /* (o) concealed residual */ - float PLClpc[], /* (o) concealed LP parameters */ - int PLI, /* (i) packet loss indicator - 0 - no PL, 1 = PL */ - float decresidual[], /* (i) decoded residual */ - float lpc[], /* (i) decoded LPC (only used for no PL) */ - int lpc_idx, - int inlag) /* (i) pitch lag */ - { - int lag = 20, randlag = 0; - float gain = 0.0f, maxcc = 0.0f; - float use_gain = 0.0f; - float gain_comp = 0.0f, maxcc_comp = 0.0f, per = 0.0f, max_per = 0.0f; - int i, pick, use_lag; - float ftmp, randvec[], pitchfact, energy; - float [] a_gain, a_comp, a_per; - - randvec = new float [ilbc_constants.BLOCKL_MAX]; - - a_gain = new float[1]; - a_comp = new float[1]; - a_per = new float[1]; - - /* Packet Loss */ - - if (PLI == 1) { - - this.consPLICount += 1; - - /* if previous frame not lost, - determine pitch pred. gain */ - - if (this.prevPLI != 1) { - - /* Search around the previous lag to find the - best pitch period */ - - lag=inlag-3; - - a_comp[0] = maxcc; - a_gain[0] = gain; - a_per[0] = max_per; - compCorr(a_comp, a_gain, a_per, - this.prevResidual, - lag, this.ULP_inst.blockl, 60); - maxcc = a_comp[0]; - gain = a_gain[0]; - max_per = a_per[0]; - - for (i=inlag-2;i<=inlag+3;i++) { - - a_comp[0] = maxcc_comp; - a_gain[0] = gain_comp; - a_per[0] = per; - compCorr(a_comp, a_gain, a_per, - this.prevResidual, - i, this.ULP_inst.blockl, 60); - maxcc_comp = a_comp[0]; - gain_comp = a_gain[0]; - per = a_per[0]; - - if (maxcc_comp>maxcc) { - maxcc=maxcc_comp; - gain=gain_comp; - lag=i; - max_per=per; - } - } - } - - /* previous frame lost, use recorded lag and periodicity */ - - else { - lag=this.prevLag; - max_per=this.per; - } - - /* downscaling */ - - use_gain=1.0f; - if (this.consPLICount*this.ULP_inst.blockl>320) - use_gain=0.9f; - else if (this.consPLICount*this.ULP_inst.blockl>2*320) - use_gain=0.7f; - else if (this.consPLICount*this.ULP_inst.blockl>3*320) - use_gain=0.5f; - else if (this.consPLICount*this.ULP_inst.blockl>4*320) - use_gain=0.0f; - - /* mix noise and pitch repeatition */ - ftmp=(float)Math.sqrt(max_per); - if (ftmp > 0.7f) - pitchfact=1.0f; - else if (ftmp>(float)0.4) - pitchfact=(ftmp-(float)0.4)/((float)0.7-(float)0.4); - else - pitchfact=0.0f; - - - /* avoid repetition of same pitch cycle */ - use_lag=lag; - if (lag<80) { - use_lag=2*lag; - } - - /* compute concealed residual */ - energy = 0.0f; - for (i=0; i 1)) { - System.out.println("\nERROR - Wrong mode - 0, 1 allowed\n"); - } - - /* do actual decoding of block */ - iLBC_decode(decblock, en_data, mode); - - /* convert to short */ - for (k = 0; k < this.ULP_inst.blockl; k++, decodedOffset += 2) { - dtmp=decblock[k]; -// System.out.println("on a eu : " + dtmp); - if (dtmp < ilbc_constants.MIN_SAMPLE) - dtmp = ilbc_constants.MIN_SAMPLE; - else if (dtmp > ilbc_constants.MAX_SAMPLE) - dtmp = ilbc_constants.MAX_SAMPLE; - - ArrayIOUtils.writeShort((short) dtmp, decoded, decodedOffset); - } - - return ((short) this.ULP_inst.blockl); - } - - /*----------------------------------------------------------------* - * frame residual decoder function (subrutine to iLBC_decode) - *---------------------------------------------------------------*/ - - public void Decode( - float decresidual[], /* (o) decoded residual frame */ - int start, /* (i) location of start - state */ - int idxForMax, /* (i) codebook index for the - maximum value */ - int idxVec[], /* (i) codebook indexes for the - samples in the start - state */ - float syntdenum[], /* (i) the decoded synthesis - filter coefficients */ - int cb_index[], /* (i) the indexes for the - adaptive codebook */ - int gain_index[], /* (i) the indexes for the - corresponding gains */ - int extra_cb_index[], /* (i) the indexes for the - adaptive codebook part - of start state */ - int extra_gain_index[], /* (i) the indexes for the - corresponding gains */ - int state_first) /* (i) 1 if non adaptive part - of start state comes - first 0 if that part - comes last */ - { - float [] reverseDecresidual = new float[ilbc_constants.BLOCKL_MAX]; - float [] mem = new float[ilbc_constants.CB_MEML]; - int k, meml_gotten, Nfor, Nback, i; - int diff, start_pos; - int subcount, subframe; - - diff = ilbc_constants.STATE_LEN - this.ULP_inst.state_short_len; - - if (state_first == 1) { - start_pos = (start-1) * ilbc_constants.SUBL; - } else { - start_pos = (start-1) * ilbc_constants.SUBL + diff; - } - - /* decode scalar part of start state */ - - ilbc_common.StateConstructW(idxForMax, idxVec, - syntdenum, (start-1)*(ilbc_constants.LPC_FILTERORDER+1), - decresidual, start_pos, this.ULP_inst.state_short_len); - - - if (state_first != 0) { /* put adaptive part in the end */ - - /* setup memory */ - - for (int li = 0; li < (ilbc_constants.CB_MEML-this.ULP_inst.state_short_len); li++) - mem[li] = 0.0f; -// memset(mem, 0, -// (CB_MEML-this.ULP_inst.state_short_len)*sizeof(float)); - System.arraycopy(decresidual, start_pos, - mem, ilbc_constants.CB_MEML - this.ULP_inst.state_short_len, - this.ULP_inst.state_short_len); -// memcpy(mem+CB_MEML-this.ULP_inst.state_short_len, -// decresidual+start_pos, -// this.ULP_inst.state_short_len*sizeof(float)); - - /* construct decoded vector */ - - ilbc_common.iCBConstruct(decresidual, start_pos+this.ULP_inst.state_short_len, - extra_cb_index, 0, extra_gain_index, 0, - mem, ilbc_constants.CB_MEML - ilbc_constants.stMemLTbl, - ilbc_constants.stMemLTbl, diff, ilbc_constants.CB_NSTAGES); - - } - else {/* put adaptive part in the beginning */ - - /* create reversed vectors for prediction */ - - for (k=0; k 0 ){ - - /* setup memory */ - - for (int li = 0; li < ilbc_constants.CB_MEML - ilbc_constants.STATE_LEN; li++) - mem[li] = 0.0f; - // memset(mem, 0, (CB_MEML-STATE_LEN)*sizeof(float)); - System.arraycopy(decresidual, (start - 1) * ilbc_constants.SUBL, - mem, ilbc_constants.CB_MEML - ilbc_constants.STATE_LEN, - ilbc_constants.STATE_LEN); - // memcpy(mem+CB_MEML-STATE_LEN, decresidual+(start-1)*SUBL, - // STATE_LEN*sizeof(float)); - - /* loop over sub-frames to encode */ - - for (subframe=0; subframe 0 ) { - - /* setup memory */ - - meml_gotten = ilbc_constants.SUBL*(this.ULP_inst.nsub+1-start); - - if ( meml_gotten > ilbc_constants.CB_MEML ) { - meml_gotten = ilbc_constants.CB_MEML; - } - for (k=0; k 0) { /* the data are good */ - - /* decode data */ - - // pbytes=bytes; - // pos=0; - - /* Set everything to zero before decoding */ - - for (k=0; k maxcc) { - maxcc = cc; - lag = ilag; - } - } - this.last_lag = lag; - - /* copy data and run synthesis filter */ - - System.arraycopy(decresidual, 0, data, 0, this.ULP_inst.blockl); -// memcpy(data, decresidual, -// this.ULP_inst.blockl*sizeof(float)); -// System.out.println("runs 5"); - for (i=0; i < this.ULP_inst.nsub; i++) { - syntFilter(data, i * ilbc_constants.SUBL, - syntdenum, i * (ilbc_constants.LPC_FILTERORDER + 1), - ilbc_constants.SUBL, this.syntMem); - } - - } - - /* high pass filtering on output if desired, otherwise - copy to out */ - - hpOutput(data, this.ULP_inst.blockl, decblock, this.hpomem); - - /* memcpy(decblock,data,iLBCdec_inst->blockl*sizeof(float));*/ - - System.arraycopy(syntdenum, 0, this.old_syntdenum, 0, - this.ULP_inst.nsub * (ilbc_constants.LPC_FILTERORDER+1)); -// memcpy(this.old_syntdenum, syntdenum, -// this.ULP_inst.nsub*(LPC_FILTERORDER+1)*sizeof(float)); - - this.prev_enh_pl=0; - - if (mode==0) { /* PLC was used */ - this.prev_enh_pl=1; - } - } - - - public ilbc_decoder(int init_mode, int init_enhancer) - { - ULP_inst = new ilbc_ulp(init_mode); - /* properties to initialize : */ - syntMem = new float[ilbc_constants.LPC_FILTERORDER]; - prevLpc = new float[ilbc_constants.LPC_FILTERORDER+1]; - prevResidual = new float[ilbc_constants.NSUB_MAX*ilbc_constants.SUBL]; - old_syntdenum = new float[(ilbc_constants.LPC_FILTERORDER + 1) * ilbc_constants.NSUB_MAX]; - hpomem = new float[4]; - enh_buf = new float[ilbc_constants.ENH_BUFL]; - enh_period = new float[ilbc_constants.ENH_NBLOCKS_TOT]; - lsfdeqold = new float[ilbc_constants.LPC_FILTERORDER]; - - for (int li = 0; li < syntMem.length; li++) - syntMem[li] = 0.0f; - - System.arraycopy(ilbc_constants.lsfmeanTbl, 0, lsfdeqold, 0, - ilbc_constants.LPC_FILTERORDER); -// for (int li = 0; li < lsfdeqold.length; li++) -// lsfdeqold[li] = 0.0f; - - for (int li = 0; li < old_syntdenum.length; li++) - old_syntdenum[li] = 0.0f; - - for (int li = 0; li < ilbc_constants.NSUB_MAX; li++) - old_syntdenum[li * (ilbc_constants.LPC_FILTERORDER + 1)] = 1.0f; - - last_lag = 20; - prevLag = 120; - per = 0.0f; - consPLICount = 0; - prevPLI = 0; - prevLpc[0] = 1.0f; - for (int li = 1; li < prevLpc.length; li++) - prevLpc[li] = 0.0f; - for (int li = 0; li < prevResidual.length; li++) - prevResidual[li] = 0.0f; - seed = 777; - - for (int li = 0; li < hpomem.length; li++) - hpomem[li] = 0.0f; - - use_enhancer = init_enhancer; - for (int li = 0; li < enh_buf.length; li++) - enh_buf[li] = 0.0f; - for (int li = 0; li < ilbc_constants.ENH_NBLOCKS_TOT; li++) - enh_period[li] = 40.0f; - prev_enh_pl = 0; - } -} - diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/ilbc_encoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/ilbc_encoder.java deleted file mode 100644 index e207ba3fe..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ilbc/ilbc_encoder.java +++ /dev/null @@ -1,2340 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.ilbc; - -import net.java.sip.communicator.impl.neomedia.*; - -/** - * Implements an iLBC encoder. - * - * @author Jean Lorchat - * @author Lyubomir Marinov - */ -class ilbc_encoder { - /* encoding mode, either 20 or 30 ms */ - int mode; - - /* analysis filter state */ - float anaMem[];//LPC_FILTERORDER]; - - /* old lsf parameters for interpolation */ - float lsfold[]; //LPC_FILTERORDER]; - float lsfdeqold[]; //LPC_FILTERORDER]; - - /* signal buffer for LP analysis */ - float lpc_buffer[]; //LPC_LOOKBACK + BLOCKL_MAX]; - - /* state of input HP filter */ - float hpimem[]; //4]; - - ilbc_ulp ULP_inst = null; - - /** - * @param syntDenum Currently not used - */ - /* encoder methods start here */ - - /*----------------------------------------------------------------* - * predictive noise shaping encoding of scaled start state - * (subrutine for StateSearchW) - *---------------------------------------------------------------*/ - - void AbsQuantW( - float in[], /* (i) vector to encode */ - int in_idx, - float syntDenum[], /* (i) denominator of synthesis filter */ - int syntDenum_idx, - float weightDenum[], /* (i) denominator of weighting filter */ - int weightDenum_idx, - int out[], /* (o) vector of quantizer indexes */ - int len, /* (i) length of vector to encode and - vector of quantizer indexes */ - int state_first /* (i) position of start state in the - 80 vec */ - ){ - // float *syntOut; - int syntOut; - float [] syntOutBuf = new float[ilbc_constants.LPC_FILTERORDER + - ilbc_constants.STATE_SHORT_LEN_30MS]; - float toQ; - int n; - int [] index = new int[1]; - - /* initialization of buffer for filtering */ - - for (int li = 0; li < ilbc_constants.LPC_FILTERORDER; li++) { - syntOutBuf[li] = 0.0f; - } - // memset(syntOutBuf, 0, LPC_FILTERORDER*sizeof(float)); - - /* initialization of pointer for filtering */ - - // syntOut = &syntOutBuf[LPC_FILTERORDER]; - - syntOut = ilbc_constants.LPC_FILTERORDER; - - /* synthesis and weighting filters on input */ - - if (state_first != 0) { - ilbc_common.AllPoleFilter (in, in_idx, weightDenum, weightDenum_idx, - ilbc_constants.SUBL, ilbc_constants.LPC_FILTERORDER); - } else { - ilbc_common.AllPoleFilter (in, in_idx, weightDenum, weightDenum_idx, - this.ULP_inst.state_short_len - ilbc_constants.SUBL, - ilbc_constants.LPC_FILTERORDER); - } - - /* encoding loop */ - - for (n=0; n maxVal*maxVal){ - maxVal = foutbuf[fout+k]; - } - } - maxVal=Math.abs(maxVal); - - /* encoding of the maximum amplitude value */ - - if (maxVal < 10.0f) { - maxVal = 10.0f; - } - // log10 is since 1.5 - //maxVal = (float)Math.log10(maxVal); - maxVal = (float)(Math.log(maxVal)/Math.log(10)); - sort_sq(idxForMax, 0, maxVal, ilbc_constants.state_frgqTbl, 64); - - /* decoding of the maximum amplitude representation value, - and corresponding scaling of start state */ - - maxVal = ilbc_constants.state_frgqTbl[idxForMax[0]]; - qmax = (float)Math.pow(10,maxVal); - scal = 4.5f / qmax; - for (k=0; k= 0.5)){ - - if (step_idx == (ilbc_constants.LSF_NUMBER_OF_STEPS - 1)){ - - if (Math.abs(hlp5) >= Math.abs(olds[old])) { - //System.out.println("acces index " + freq_idx + lsp_index); - freq[freq_idx+lsp_index] = omega - step; - } else { - //System.out.println("acces index " + freq_idx + lsp_index); - freq[freq_idx+lsp_index] = omega; - } - - if ((olds[old]) >= 0.0f){ - olds[old] = -1.0f * ilbc_constants.DOUBLE_MAX; - } else { - olds[old] = ilbc_constants.DOUBLE_MAX; - } - - omega = old_omega; - step_idx = 0; - - step_idx = ilbc_constants.LSF_NUMBER_OF_STEPS; - } else { - - if (step_idx == 0) { - old_omega = omega; - } - - step_idx++; - omega -= steps[step_idx]; - - /* Go back one grid step */ - - step = steps[step_idx]; - } - } else { - - /* increment omega until they are of different sign, - and we know there is at least one root between omega - and old_omega */ - olds[old] = hlp5; - omega += step; - } - } - } - - for (i = 0; i < ilbc_constants.LPC_FILTERORDER; i++) { - //System.out.println("acces index " + freq_idx + i); - freq[freq_idx+i] = freq[freq_idx+i] * ilbc_constants.TWO_PI; - } - } - - /*----------------------------------------------------------------* - * lpc analysis (subrutine to LPCencode) - *---------------------------------------------------------------*/ - - void SimpleAnalysis( - float lsf[], /* (o) lsf coefficients */ - float data[]) /* (i) new data vector */ - { - int k, is; - float [] temp = new float[ilbc_constants.BLOCKL_MAX]; - float [] lp = new float[ilbc_constants.LPC_FILTERORDER + 1]; - float [] lp2 = new float[ilbc_constants.LPC_FILTERORDER + 1]; - float [] r = new float[ilbc_constants.LPC_FILTERORDER + 1]; - - is=ilbc_constants.LPC_LOOKBACK+ilbc_constants.BLOCKL_MAX-this.ULP_inst.blockl; - // System.out.println("copie 1"); -// System.out.println("\nInformations de copie : \nbuffer source : " + data.length + " octets\n"+ -// "buffer cible : " + this.lpc_buffer.length + "octets\n" + -// " offset : " + is + "octets\n" + -// "longueur de la copie : " + this.ULP_inst.blockl); - System.arraycopy(data, 0, this.lpc_buffer, is, this.ULP_inst.blockl); -// memcpy(iLBCenc_inst->lpc_buffer+is,data,iLBCenc_inst->blockl*sizeof(float)); - - /* No lookahead, last window is asymmetric */ - - for (k = 0; k < this.ULP_inst.lpc_n; k++) { - - is = ilbc_constants.LPC_LOOKBACK; - - if (k < (this.ULP_inst.lpc_n - 1)) { - window(temp, ilbc_constants.lpc_winTbl, this.lpc_buffer, 0, - ilbc_constants.BLOCKL_MAX); - } else { - window(temp, ilbc_constants.lpc_asymwinTbl, - this.lpc_buffer, is, ilbc_constants.BLOCKL_MAX); - } - - autocorr(r, temp, ilbc_constants.BLOCKL_MAX, ilbc_constants.LPC_FILTERORDER); - window(r, r, ilbc_constants.lpc_lagwinTbl, 0, ilbc_constants.LPC_FILTERORDER + 1); - - levdurb(lp, temp, r, ilbc_constants.LPC_FILTERORDER); - ilbc_common.bwexpand(lp2, 0, lp, ilbc_constants.LPC_CHIRP_SYNTDENUM, - ilbc_constants.LPC_FILTERORDER+1); - - a2lsf(lsf, k * ilbc_constants.LPC_FILTERORDER, lp2); - } - is=ilbc_constants.LPC_LOOKBACK+ilbc_constants.BLOCKL_MAX-this.ULP_inst.blockl; -// System.out.println("copie 2"); - System.arraycopy(this.lpc_buffer, ilbc_constants.LPC_LOOKBACK + ilbc_constants.BLOCKL_MAX - is, - this.lpc_buffer, 0, is); -// memmove(iLBCenc_inst->lpc_buffer, -// iLBCenc_inst->lpc_buffer+LPC_LOOKBACK+BLOCKL_MAX-is, -// is*sizeof(float)); - } - - /*----------------------------------------------------------------* - * lsf interpolator and conversion from lsf to a coefficients - * (subrutine to SimpleInterpolateLSF) - *---------------------------------------------------------------*/ - - void LSFinterpolate2a_enc( - float a[], /* (o) lpc coefficients */ - float lsf1[],/* (i) first set of lsf coefficients */ - float lsf2[],/* (i) second set of lsf coefficients */ - int lsf2_idx, - float coef, /* (i) weighting coefficient to use between - lsf1 and lsf2 */ - long length /* (i) length of coefficient vectors */ - ){ - float [] lsftmp = new float[ilbc_constants.LPC_FILTERORDER]; - - ilbc_common.interpolate(lsftmp, lsf1, lsf2, lsf2_idx, coef, ((int)length)); - ilbc_common.lsf2a(a, lsftmp); - } - - /*----------------------------------------------------------------* - * lsf interpolator (subrutine to LPCencode) - *---------------------------------------------------------------*/ - - void SimpleInterpolateLSF( - float syntdenum[], /* (o) the synthesis filter denominator - resulting from the quantized - interpolated lsf */ - float weightdenum[], /* (o) the weighting filter denominator - resulting from the unquantized - interpolated lsf */ - float lsf[], /* (i) the unquantized lsf coefficients */ - float lsfdeq[], /* (i) the dequantized lsf coefficients */ - float lsfold[], /* (i) the unquantized lsf coefficients of - the previous signal frame */ - float lsfdeqold[], /* (i) the dequantized lsf coefficients of - the previous signal frame */ - int length) /* (i) should equate LPC_FILTERORDER */ - { - int i, pos, lp_length; - float [] lp = new float[ilbc_constants.LPC_FILTERORDER + 1]; - int lsf2, lsfdeq2; - - lsf2 = length; - lsfdeq2 = length; -// lsf2 = lsf + length; -// lsfdeq2 = lsfdeq + length; - lp_length = length + 1; - - if (this.ULP_inst.mode==30) { - /* sub-frame 1: Interpolation between old and first - - set of lsf coefficients */ - - LSFinterpolate2a_enc(lp, lsfdeqold, lsfdeq, 0, - ilbc_constants.lsf_weightTbl_30ms[0], length); - System.arraycopy(lp, 0, syntdenum, 0, lp_length); - // memcpy(syntdenum,lp,lp_length*sizeof(float)); - LSFinterpolate2a_enc(lp, lsfold, lsf, 0, - ilbc_constants.lsf_weightTbl_30ms[0], length); - ilbc_common.bwexpand(weightdenum, 0, lp, - ilbc_constants.LPC_CHIRP_WEIGHTDENUM, - lp_length); - - /* sub-frame 2 to 6: Interpolation between first - and second set of lsf coefficients */ - - pos = lp_length; - for (i = 1; i < this.ULP_inst.nsub; i++) { - LSFinterpolate2a_enc(lp, lsfdeq, lsfdeq, lsfdeq2, - ilbc_constants.lsf_weightTbl_30ms[i], length); - System.arraycopy(lp, 0, syntdenum, pos, lp_length); - // memcpy(syntdenum + pos,lp,lp_length*sizeof(float)); - - LSFinterpolate2a_enc(lp, lsf, lsf, lsf2, - ilbc_constants.lsf_weightTbl_30ms[i], length); - ilbc_common.bwexpand(weightdenum, pos, lp, - ilbc_constants.LPC_CHIRP_WEIGHTDENUM, lp_length); - pos += lp_length; - } - } - else { - pos = 0; - for (i = 0; i < this.ULP_inst.nsub; i++) { - //System.out.println("ici ?"); - LSFinterpolate2a_enc(lp, lsfdeqold, lsfdeq, 0, - ilbc_constants.lsf_weightTbl_20ms[i], length); - //System.out.println("ici !"); - System.arraycopy(lp, 0, syntdenum, pos, lp_length); - for (int li = 0; li < lp_length; li++) - //System.out.println("interpolate syntdenum [" + (li+pos) +"] is worth " + syntdenum[li+pos]); - // memcpy(syntdenum+pos,lp,lp_length*sizeof(float)); - LSFinterpolate2a_enc(lp, lsfold, lsf, 0, - ilbc_constants.lsf_weightTbl_20ms[i], length); - ilbc_common.bwexpand(weightdenum, pos, lp, - ilbc_constants.LPC_CHIRP_WEIGHTDENUM, lp_length); - pos += lp_length; - } - } - - /* update memory */ - - if (this.ULP_inst.mode==30) { - System.arraycopy(lsf, lsf2, lsfold, 0, length); -// memcpy(lsfold, lsf2, length*sizeof(float)); - System.arraycopy(lsfdeq, lsfdeq2, lsfdeqold, 0, length); -// memcpy(lsfdeqold, lsfdeq2, length*sizeof(float)); - } - else { - System.arraycopy(lsf, 0, lsfold, 0, length); -// memcpy(lsfold, lsf, length*sizeof(float)); - System.arraycopy(lsfdeq, 0, lsfdeqold, 0, length); -// memcpy(lsfdeqold, lsfdeq, length*sizeof(float)); - - } - } - - /*----------------------------------------------------------------* - * lsf quantizer (subrutine to LPCencode) - *---------------------------------------------------------------*/ - - void SimplelsfQ( - float lsfdeq[], /* (o) dequantized lsf coefficients - (dimension FILTERORDER) */ - int index[], /* (o) quantization index */ - float lsf[], /* (i) the lsf coefficient vector to be - quantized (dimension FILTERORDER ) */ - int lpc_n /* (i) number of lsf sets to quantize */ - ){ - /* Quantize first LSF with memoryless split VQ */ - SplitVQ(lsfdeq, 0, index, 0, lsf, 0, ilbc_constants.lsfCbTbl, - ilbc_constants.LSF_NSPLIT, ilbc_constants.dim_lsfCbTbl, - ilbc_constants.size_lsfCbTbl); - - if (lpc_n==2) { - /* Quantize second LSF with memoryless split VQ */ - SplitVQ(lsfdeq, ilbc_constants.LPC_FILTERORDER, - index, ilbc_constants.LSF_NSPLIT, - lsf, ilbc_constants.LPC_FILTERORDER, - ilbc_constants.lsfCbTbl, - ilbc_constants.LSF_NSPLIT, - ilbc_constants.dim_lsfCbTbl, - ilbc_constants.size_lsfCbTbl); - } - } - - /*----------------------------------------------------------------* - * lpc encoder - *---------------------------------------------------------------*/ - - void LPCencode( - float syntdenum[], /* (i/o) synthesis filter coefficients - before/after encoding */ - float weightdenum[], /* (i/o) weighting denumerator - coefficients before/after - encoding */ - int lsf_index[], /* (o) lsf quantization index */ - float data[]) /* (i) lsf coefficients to quantize */ - { - float [] lsf = new float[ilbc_constants.LPC_FILTERORDER * ilbc_constants.LPC_N_MAX]; - float [] lsfdeq= new float[ilbc_constants.LPC_FILTERORDER * ilbc_constants.LPC_N_MAX]; - - SimpleAnalysis(lsf, data); - // for (int li = 0; li < ilbc_constants.LPC_FILTERORDER * ilbc_constants.LPC_N_MAX; li++) - // System.out.println("postSA n-" + li + " is worth " + lsf[li]); - // for (int li = 0; li < ilbc_constants.BLOCKL_MAX; li++) - // System.out.println("data postSA n-" + li + " is worth " + data[li]); - SimplelsfQ(lsfdeq, lsf_index, lsf, this.ULP_inst.lpc_n); - // for (int li = 0; li < ilbc_constants.LPC_FILTERORDER * ilbc_constants.LPC_N_MAX; li++) - // System.out.println("postSlsfQ n-" + li + " is worth " + lsfdeq[li]); - // for (int li = 0; li < lsf_index.length; li++) - // System.out.println("index postSlsfQ n-" + li + " is worth " + lsf_index[li]); - - ilbc_common.LSF_check(lsfdeq, ilbc_constants.LPC_FILTERORDER, this.ULP_inst.lpc_n); - //System.out.println("check gives " + change); - SimpleInterpolateLSF(syntdenum, weightdenum, - lsf, lsfdeq, this.lsfold, - this.lsfdeqold, ilbc_constants.LPC_FILTERORDER); - // for (int li = 0; li < syntdenum.length; li++) - // System.out.println("syntdenum[" + li +"] is worth " + syntdenum[li]); - } - - public void iCBSearch( - int index[], /* (o) Codebook indices */ - int index_idx, - int gain_index[],/* (o) Gain quantization indices */ - int gain_index_idx, - - float intarget[],/* (i) Target vector for encoding */ - int intarget_idx, - float mem[], /* (i) Buffer for codebook construction */ - int mem_idx, - int lMem, /* (i) Length of buffer */ - int lTarget, /* (i) Length of vector */ - int nStages, /* (i) Number of codebook stages */ - float weightDenum[], /* (i) weighting filter coefficients */ - int weightDenum_idx, - float weightState[], /* (i) weighting filter state */ - int block) /* (i) the sub-block number */ - { - int i, j, icount, stage, best_index, range, counter; - float max_measure, gain, measure, crossDot, ftmp; - float [] gains = new float[ilbc_constants.CB_NSTAGES]; - float [] target = new float[ilbc_constants.SUBL]; - int base_index, sInd, eInd, base_size; - int sIndAug=0, eIndAug=0; - float [] buf = new float[ilbc_constants.CB_MEML+ilbc_constants.SUBL+2*ilbc_constants.LPC_FILTERORDER]; - float [] invenergy = new float[ilbc_constants.CB_EXPAND*128]; - float [] energy = new float[ilbc_constants.CB_EXPAND*128]; - // float *pp, *ppi=0, *ppo=0, *ppe=0; - int pp, ppi = 0, ppo = 0, ppe = 0; - float [] ppt; - float [] cbvectors = new float[ilbc_constants.CB_MEML]; - float tene, cene; - float [] cvec = new float[ilbc_constants.SUBL]; - float [] aug_vec = new float[ilbc_constants.SUBL]; - - float [] a = new float[1]; - int [] b = new int[1]; - float [] c = new float[1]; - - for (int li = 0; li < ilbc_constants.SUBL; li++) - cvec[li] = 0.0f; - // memset(cvec,0,SUBL*sizeof(float)); - - /* Determine size of codebook sections */ - - base_size=lMem-lTarget+1; - - if (lTarget == ilbc_constants.SUBL) { - base_size=lMem-lTarget+1+lTarget/2; - } - - /* setup buffer for weighting */ - - System.arraycopy(weightState, 0, buf, 0, ilbc_constants.LPC_FILTERORDER); -// memcpy(buf,weightState,sizeof(float)*LPC_FILTERORDER); - System.arraycopy(mem, mem_idx, buf, ilbc_constants.LPC_FILTERORDER, lMem); -// memcpy(buf+LPC_FILTERORDER,mem,lMem*sizeof(float)); - System.arraycopy(intarget, intarget_idx, buf, ilbc_constants.LPC_FILTERORDER+lMem, lTarget); -// memcpy(buf+LPC_FILTERORDER+lMem,intarget,lTarget*sizeof(float)); - - //System.out.println("beginning of mem"); -// for (int li = 0; li < lMem; li++) -// System.out.println("mem[" + li + "] = " + mem[li+mem_idx]); -// System.out.println("end of mem"); - - -// System.out.println("plages : [0-" + ilbc_constants.LPC_FILTERORDER + -// "], puis [" + ilbc_constants.LPC_FILTERORDER + "-" + (ilbc_constants.LPC_FILTERORDER + lMem) + -// "], puis [" + (ilbc_constants.LPC_FILTERORDER + lMem) + -// "-" + (ilbc_constants.LPC_FILTERORDER + lMem + lTarget) + "]"); - -// System.out.println("beginning of buffer"); - -// for (int li = 0; li < buf.length; li++) -// System.out.println("buffer[" + li + "] = " + buf[li]); - -// System.out.println("end of buffer"); - /* weighting */ - - ilbc_common.AllPoleFilter(buf, ilbc_constants.LPC_FILTERORDER, weightDenum, weightDenum_idx, - lMem+lTarget, ilbc_constants.LPC_FILTERORDER); - - /* Construct the codebook and target needed */ - - System.arraycopy(buf, ilbc_constants.LPC_FILTERORDER + lMem, target, 0, lTarget); - // memcpy(target, buf+LPC_FILTERORDER+lMem, lTarget*sizeof(float)); - - tene=0.0f; - - for (i=0; i 0.0f) { - invenergy[0] = 1.0f / (energy[ppe] + ilbc_constants.EPS); - } else { - invenergy[0] = 0.0f; - - } - ppe++; - - measure=-10000000.0f; - - if (crossDot > 0.0f) { - measure = crossDot*crossDot*invenergy[0]; - } - } - else { - measure = crossDot*crossDot*invenergy[0]; - } - - /* check if measure is better */ - ftmp = crossDot*invenergy[0]; - - if ((measure>max_measure) && (Math.abs(ftmp) < ilbc_constants.CB_MAXGAIN)) { - best_index = 0; - max_measure = measure; - gain = ftmp; - } - - /* loop over the main first codebook section, - full search */ - - for (icount=1; icount0.0f) { - invenergy[icount] = - 1.0f/(energy[icount]+ilbc_constants.EPS); - } else { - invenergy[icount] = 0.0f; - } - - measure=-10000000.0f; - - if (crossDot > 0.0f) { - measure = crossDot*crossDot*invenergy[icount]; - } - } - else { - measure = crossDot*crossDot*invenergy[icount]; - } - - /* check if measure is better */ - ftmp = crossDot*invenergy[icount]; - - if ((measure>max_measure) && (Math.abs(ftmp) < ilbc_constants.CB_MAXGAIN)) { - best_index = icount; - max_measure = measure; - gain = ftmp; - } - } - - /* Loop over augmented part in the first codebook - * section, full search. - * The vectors are interpolated. - */ - - if (lTarget == ilbc_constants.SUBL) { - - /* Search for best possible cb vector and - compute the CB-vectors' energy. */ - a[0] = max_measure; - b[0] = best_index; - c[0] = gain; - searchAugmentedCB(20, 39, stage, base_size-lTarget/2, - target, buf, ilbc_constants.LPC_FILTERORDER+lMem, - a, b, c, energy, invenergy); - max_measure = a[0]; - best_index = b[0]; - gain = c[0]; - } - - /* set search range for following codebook sections */ - - // System.out.println("best index : " + best_index); - - base_index = best_index; - - /* unrestricted search */ - - if (ilbc_constants.CB_RESRANGE == -1) { - // System.out.println("on met a 0"); - sInd = 0; - eInd = range - 1; - sIndAug = 20; - eIndAug = 39; - } - - /* restricted search around best index from first - codebook section */ - - else { - /* Initialize search indices */ - sIndAug=0; - eIndAug=0; - sInd=base_index-ilbc_constants.CB_RESRANGE/2; - // System.out.println("on met a " + base_index + " - " + ilbc_constants.CB_RESRANGE/2 + " = " + sInd); - eInd=sInd+ilbc_constants.CB_RESRANGE; - - if (lTarget==ilbc_constants.SUBL) { - - if (sInd<0) { - - sIndAug = 40 + sInd; - eIndAug = 39; - // System.out.println("On met encore a 0"); - sInd=0; - - } else if ( base_index < (base_size-20) ) { - - if (eInd > range) { - sInd -= (eInd-range); - // System.out.println("on retire " + eInd + " - " + range + " pour arriver a " + sInd); - eInd = range; - } - } else { /* base_index >= (base_size-20) */ - - if (sInd < (base_size-20)) { - sIndAug = 20; - sInd = 0; - // System.out.println("on remet encore a 0"); - eInd = 0; - eIndAug = 19 + ilbc_constants.CB_RESRANGE; - - if(eIndAug > 39) { - eInd = eIndAug-39; - eIndAug = 39; - } - } else { - sIndAug = 20 + sInd - (base_size-20); - eIndAug = 39; - sInd = 0; - // System.out.println("on remetz4 a zero"); - eInd = ilbc_constants.CB_RESRANGE - (eIndAug-sIndAug+1); - } - } - - } else { /* lTarget = 22 or 23 */ - - if (sInd < 0) { - eInd -= sInd; - - sInd = 0; - // System.out.println("on remet x5 a zero"); - } - - if(eInd > range) { - sInd -= (eInd - range); - // System.out.println("on retire " + eInd + " - " + range + " pour arriver a " + sInd); - eInd = range; - } - } - } - - /* search of higher codebook section */ - - /* index search range */ - counter = sInd; - // System.out.println("on ajoute " + base_size + " pour arriver a " + sInd); - sInd += base_size; - eInd += base_size; - - - if (stage==0) { - // ppe = energy+base_size; - ppe = base_size; - energy[ppe]=0.0f; - - pp=lMem-lTarget; - // pp=cbvectors+lMem-lTarget; - for (j=0; j0.0f) { - invenergy[icount] = 1.0f/(energy[icount]+ilbc_constants.EPS); - } else { - invenergy[icount] = 0.0f; - } - - if (stage==0) { - - measure = -10000000.0f; - - if (crossDot > 0.0f) { - measure = crossDot*crossDot* - invenergy[icount]; - } - } - else { - measure = crossDot*crossDot*invenergy[icount]; - } - - /* check if measure is better */ - ftmp = crossDot*invenergy[icount]; - - if ((measure > max_measure) && (Math.abs(ftmp) ilbc_constants.CB_MAXGAIN) { - gain = ilbc_constants.CB_MAXGAIN; - } - gain = ilbc_common.gainquant(gain, 1.0f, 32, gain_index, gain_index_idx + stage); - } - else { - if (stage==1) { - gain = ilbc_common.gainquant(gain, Math.abs(gains[stage-1]), - 16, gain_index, gain_index_idx + stage); - } else { - gain = ilbc_common.gainquant(gain, Math.abs(gains[stage-1]), - 8, gain_index, gain_index_idx + stage); - } - } - - /* Extract the best (according to measure) - codebook vector */ - - if (lTarget==(ilbc_constants.STATE_LEN - this.ULP_inst.state_short_len)) { - - if (index[index_idx+stage]=108)&&(index[k]<172)) { - index[k]-=64; - } else if (index[k]>=236) { - index[k]-=128; - } else { - /* ERROR */ - } - } - } - - public void hpInput( - float In[], /* (i) vector to filter */ - int len, /* (i) length of vector to filter */ - float Out[], /* (o) the resulting filtered vector */ - float mem[]) /* (i/o) the filter state */ - { - int i; - // float *pi, *po; - int pi, po; - - /* all-zero section*/ - - // pi = &In[0]; - pi = 0; - // po = &Out[0]; - po = 0; - - for (i=0; i0.0f) { - invenergy[tmpIndex] = 1.0f/(energy[tmpIndex] + ilbc_constants.EPS); - } else { - invenergy[tmpIndex] = 0.0f; - } - - if (stage==0) { - measure = -10000000.0f; - - if (crossDot > 0.0f) { - measure = crossDot*crossDot*invenergy[tmpIndex]; - } - } - else { - measure = crossDot*crossDot*invenergy[tmpIndex]; - } - - /* check if measure is better */ - ftmp = crossDot*invenergy[tmpIndex]; - - // System.out.println("on compare " + measure + " et " + max_measure[0]); - // System.out.println("ainsi que " + Math.abs(ftmp) + " et " + ilbc_constants.CB_MAXGAIN); - - if ((measure>max_measure[0]) && (Math.abs(ftmp) < ilbc_constants.CB_MAXGAIN)) { - // System.out.println("new best index at " + tmpIndex + ", where icount = " + icount); - best_index[0] = tmpIndex; - max_measure[0] = measure; - gain[0] = ftmp; - } - } - } - - /*----------------------------------------------------------------* - * Recreate a specific codebook vector from the augmented part. - * - *----------------------------------------------------------------*/ - - private void createAugmentedVec(int index, float buffer[], int buffer_idx, float cbVec[]) - { - int ilow, j; - int pp, ppo, ppi; - float alfa, alfa1, weighted; - - ilow = index - 5; - - /* copy the first noninterpolated part */ - - pp = buffer_idx - index; - System.arraycopy(buffer, pp, cbVec, 0, index); - // memcpy(cbVec,pp,sizeof(float)*index); - - /* interpolation */ - - alfa1 = (float)0.2; - alfa = 0.0f; - // ppo = buffer-5; - ppo = buffer_idx - 5; - // ppi = buffer-index-5; - ppi = buffer_idx - index - 5; - for (j=ilow; jno_of_bytes); - } - - // public int encode(short encoded_data[], short data[]) - // { - // for (int i = 0; i < encoded_data.length; i ++) { - // data[i%data.length] = encoded_data[i]; - // } - - // if (mode == 20) - // return ilbc_constants.BLOCKL_20MS; - // else - // return ilbc_constants.BLOCKL_30MS; - // } - public int encode( - byte[] encoded, int encodedOffset, - byte[] decoded, int decodedOffset) - { - float block[] = new float [this.ULP_inst.blockl]; - bitstream en_data - = new bitstream(encoded, encodedOffset, this.ULP_inst.no_of_bytes); - // char en_data[] = new char [this.ULP_inst.no_of_bytes]; - int k; - - /* convert signal to float */ - for (k = 0; k < this.ULP_inst.blockl; k++, decodedOffset += 2) - block[k] = ArrayIOUtils.readShort(decoded, decodedOffset); - - // for (int li = 0; li < block.length; li++) - // System.out.println("block " + li + " : " + block[li]); - - /* do the actual encoding */ - - iLBC_encode(en_data, block); - - return this.ULP_inst.no_of_bytes; - - } - - public void iLBC_encode( - bitstream bytes, /* (o) encoded data bits iLBC */ - float block[]) /* (o) speech vector to encode */ - { - int start; - int [] idxForMax = new int[1]; - int n, k, meml_gotten, Nfor, Nback, i; - // unsigned char *pbytes; - int diff, start_pos, state_first; - float en1, en2; - int index, ulp; - // int [] firstpart = new int[1]; - int firstpart; - int subcount, subframe; - - float [] data = new float[ilbc_constants.BLOCKL_MAX]; - float [] residual = new float[ilbc_constants.BLOCKL_MAX]; - float [] reverseResidual = new float[ilbc_constants.BLOCKL_MAX]; - - int [] idxVec = new int[ilbc_constants.STATE_LEN]; - float [] reverseDecresidual = new float[ilbc_constants.BLOCKL_MAX]; - float [] mem = new float[ilbc_constants.CB_MEML]; - - int [] gain_index = new int[ilbc_constants.CB_NSTAGES*ilbc_constants.NASUB_MAX]; - int [] extra_gain_index = new int[ilbc_constants.CB_NSTAGES]; - int [] cb_index = new int[ilbc_constants.CB_NSTAGES*ilbc_constants.NASUB_MAX]; - int [] extra_cb_index = new int[ilbc_constants.CB_NSTAGES]; - int [] lsf_i = new int[ilbc_constants.LSF_NSPLIT*ilbc_constants.LPC_N_MAX]; - - float [] weightState = new float[ilbc_constants.LPC_FILTERORDER]; - float [] syntdenum = new float[ilbc_constants.NSUB_MAX*(ilbc_constants.LPC_FILTERORDER+1)]; - float [] weightdenum = new float[ilbc_constants.NSUB_MAX*(ilbc_constants.LPC_FILTERORDER+1)]; - float [] decresidual = new float[ilbc_constants.BLOCKL_MAX]; - - bitpack pack; - - /* high pass filtering of input signal if such is not done - prior to calling this function */ - - // System.out.println("Data prior to hpinput call"); - // for (int li = 0; li < data.length; li++) - // System.out.println("index : " + li + " and value " + data[li]); - // System.out.println("Mem prior to hpinput call"); - // for (int li = 0; li < this.hpimem.length; li++) - // System.out.println("index : " + li + " and value " + this.hpimem[li]); - hpInput(block, this.ULP_inst.blockl, data, this.hpimem); - // System.out.println("Data after hpinput call"); - // for (int li = 0; li < data.length; li++) - // System.out.println("index : " + li + " and value " + data[li]); - // System.out.println("Mem after hpinput call"); - // for (int li = 0; li < this.hpimem.length; li++) - // System.out.println("index : " + li + " and value " + this.hpimem[li]); - - - /* otherwise simply copy */ - - /*memcpy(data,block,iLBCenc_inst->blockl*sizeof(float));*/ - - /* LPC of hp filtered input data */ - - LPCencode(syntdenum, weightdenum, lsf_i, data); - - // for (int li = 0; li < ilbc_constants.NSUB_MAX*(ilbc_constants.LPC_FILTERORDER+1); li++) - // System.out.println("postLPC n-" + li + " is worth " + syntdenum[li] + ", " + weightdenum[li]); - - /* inverse filter to get residual */ - - for (n = 0; n < this.ULP_inst.nsub; n++) { - anaFilter(data, n*ilbc_constants.SUBL, syntdenum, n*(ilbc_constants.LPC_FILTERORDER+1), - ilbc_constants.SUBL, residual, n*ilbc_constants.SUBL, this.anaMem); - } - - // for (int li = 0; li < ilbc_constants.BLOCKL_MAX; li++) - // System.out.println("block residual n-" + li + " is worth " + residual[li]); - - /* find state location */ - - start = FrameClassify(residual); - - /* check if state should be in first or last part of the - two subframes */ - - diff = ilbc_constants.STATE_LEN - this.ULP_inst.state_short_len; - en1 = 0; - index = (start-1)*ilbc_constants.SUBL; - for (i = 0; i < this.ULP_inst.state_short_len; i++) { - en1 += residual[index+i]*residual[index+i]; - } - en2 = 0; - index = (start-1)*ilbc_constants.SUBL+diff; - for (i = 0; i < this.ULP_inst.state_short_len; i++) { - en2 += residual[index+i]*residual[index+i]; - } - - - if (en1 > en2) { - state_first = 1; - start_pos = (start-1)*ilbc_constants.SUBL; - } else { - state_first = 0; - start_pos = (start-1)*ilbc_constants.SUBL + diff; - } - - /* scalar quantization of state */ - - StateSearchW(residual, start_pos, - syntdenum, (start-1)*(ilbc_constants.LPC_FILTERORDER+1), - weightdenum, (start-1)*(ilbc_constants.LPC_FILTERORDER+1), - idxForMax, idxVec, this.ULP_inst.state_short_len, state_first); - - ilbc_common.StateConstructW(idxForMax[0], idxVec, - syntdenum, (start-1)*(ilbc_constants.LPC_FILTERORDER+1), - decresidual, start_pos, this.ULP_inst.state_short_len); - - /* predictive quantization in state */ - - if (state_first != 0) { /* put adaptive part in the end */ - - /* setup memory */ - for (int li = 0; li < ilbc_constants.CB_MEML-this.ULP_inst.state_short_len; li++) - mem[li] = 0.0f; - System.arraycopy(decresidual, start_pos, - mem, ilbc_constants.CB_MEML-this.ULP_inst.state_short_len, - this.ULP_inst.state_short_len); - // memcpy(mem+ilbc_constants.CB_MEML-this.ULP_inst.state_short_len, - // decresidual+start_pos, - // this.ULP_inst.state_short_len*sizeof(float)); - for (int li = 0; li < ilbc_constants.LPC_FILTERORDER; li++) - weightState[li] = 0.0f; - // memset(weightState, 0, ilbc_constants.LPC_FILTERORDER*sizeof(float)); - - /* encode sub-frames */ - - iCBSearch(extra_cb_index, 0, extra_gain_index, 0, - residual, start_pos+this.ULP_inst.state_short_len, - mem, ilbc_constants.CB_MEML-ilbc_constants.stMemLTbl, - ilbc_constants.stMemLTbl, diff, ilbc_constants.CB_NSTAGES, - weightdenum, start*(ilbc_constants.LPC_FILTERORDER+1), - weightState, 0); - - /* construct decoded vector */ - - ilbc_common.iCBConstruct(decresidual, start_pos+this.ULP_inst.state_short_len, - extra_cb_index, 0, extra_gain_index, 0, - mem, ilbc_constants.CB_MEML-ilbc_constants.stMemLTbl, - ilbc_constants.stMemLTbl, diff, ilbc_constants.CB_NSTAGES); - - } - else { /* put adaptive part in the beginning */ - - /* create reversed vectors for prediction */ - - for (k=0; k 0 ) { - - /* setup memory */ - - for (int li = 0; li < (ilbc_constants.CB_MEML-ilbc_constants.STATE_LEN); li++) - mem[li] = 0.0f; - // memset(mem, 0, (ilbc_constants.CB_MEML-ilbc_constants.STATE_LEN)*sizeof(float)); - System.arraycopy(decresidual, (start-1)*ilbc_constants.SUBL, - mem, ilbc_constants.CB_MEML-ilbc_constants.STATE_LEN, - ilbc_constants.STATE_LEN); - // memcpy(mem+ilbc_constants.CB_MEML-ilbc_constants.STATE_LEN, - // decresidual+(start-1)*ilbc_constants.SUBL, - // ilbc_constants.STATE_LEN*sizeof(float)); - for (int li = 0; li < ilbc_constants.LPC_FILTERORDER; li++) - weightState[li] = 0.0f; - // memset(weightState, 0, ilbc_constants.LPC_FILTERORDER*sizeof(float)); - - /* loop over sub-frames to encode */ - - for (subframe=0; subframe 0 ) { - - /* create reverse order vectors */ - - for (n=0; n ilbc_constants.CB_MEML ) { - meml_gotten=ilbc_constants.CB_MEML; - } - for (k=0; kULP_inst=&ULP_20msTbl; - System.arraycopy(ilbc_constants.lsf_bits_20ms, 0, lsf_bits, 0, 6); - System.arraycopy(ilbc_constants.start_bits_20ms, 0, start_bits, 0, ilbc_constants.start_bits_20ms.length); - System.arraycopy(ilbc_constants.startfirst_bits_20ms, 0, startfirst_bits, 0, ilbc_constants.startfirst_bits_20ms.length); - System.arraycopy(ilbc_constants.scale_bits_20ms, 0, scale_bits, 0, ilbc_constants.scale_bits_20ms.length); - System.arraycopy(ilbc_constants.state_bits_20ms, 0, state_bits, 0, ilbc_constants.state_bits_20ms.length); - System.arraycopy(ilbc_constants.extra_cb_index_20ms, 0, extra_cb_index, 0, ilbc_constants.CB_NSTAGES); - System.arraycopy(ilbc_constants.extra_cb_gain_20ms, 0, extra_cb_gain, 0, ilbc_constants.CB_NSTAGES); - System.arraycopy(ilbc_constants.cb_index_20ms, 0, cb_index, 0, ilbc_constants.NSUB_20MS); - System.arraycopy(ilbc_constants.cb_gain_20ms, 0, cb_gain, 0, ilbc_constants.NSUB_20MS); - } - else if (mode == 30) - { - blockl = ilbc_constants.BLOCKL_30MS; - nsub = ilbc_constants.NSUB_30MS; - nasub = ilbc_constants.NASUB_30MS; - lpc_n = ilbc_constants.LPC_N_30MS; - no_of_bytes = ilbc_constants.NO_OF_BYTES_30MS; - no_of_words = ilbc_constants.NO_OF_WORDS_30MS; - state_short_len = ilbc_constants.STATE_SHORT_LEN_30MS; - /* ULP init */ - // ULP_inst=&ULP_30msTbl; - System.arraycopy(ilbc_constants.lsf_bits_30ms, 0, lsf_bits, 0, 6); - System.arraycopy(ilbc_constants.start_bits_30ms, 0, start_bits, 0, ilbc_constants.start_bits_30ms.length); - System.arraycopy(ilbc_constants.startfirst_bits_30ms, 0, startfirst_bits, 0, ilbc_constants.startfirst_bits_30ms.length); - System.arraycopy(ilbc_constants.scale_bits_30ms, 0, scale_bits, 0, ilbc_constants.scale_bits_30ms.length); - System.arraycopy(ilbc_constants.state_bits_30ms, 0, state_bits, 0, ilbc_constants.state_bits_30ms.length); - System.arraycopy(ilbc_constants.extra_cb_index_30ms, 0, extra_cb_index, 0, ilbc_constants.CB_NSTAGES); - System.arraycopy(ilbc_constants.extra_cb_gain_30ms, 0, extra_cb_gain, 0, ilbc_constants.CB_NSTAGES); - // System.out.println("nsubmax vaut: " + NSUB_MAX + " vs " + NSUB_30MS + ", alors que la taille de la table est: " + cb_index_30ms.length + " vs " + cb_index.length); - System.arraycopy(ilbc_constants.cb_index_30ms, 0, cb_index, 0, ilbc_constants.NSUB_30MS); - System.arraycopy(ilbc_constants.cb_gain_30ms, 0, cb_gain, 0, ilbc_constants.NSUB_30MS); - } - - // for (int i = 0; i < NSUB_MAX; i++) { - // for (int j = 0; j < CB_NSTAGES; j++) { - // for (int k = 0; k < ULP_CLASSES+2; k++) { - // System.out.print(" " + cb_gain[i][j][k]); - // } - // System.out.print(" | "); - // } - // System.out.println(""); - // } - } -} - diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/mp3/JNIEncoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/mp3/JNIEncoder.java deleted file mode 100644 index d4adfe817..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/mp3/JNIEncoder.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.mp3; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.util.*; -import net.sf.fmj.media.*; - -/** - * Implements a MP3 encoder using the native FFmpeg library. - * - * @author Lyubomir Marinov - */ -public class JNIEncoder - extends AbstractCodecExt -{ - /** - * The Logger used by the JNIEncoder class and its - * instances for logging output. - */ - private static final Logger logger = Logger.getLogger(JNIEncoder.class); - - /** - * The list of Formats of audio data supported as input by - * JNIEncoder instances. - */ - private static final Format[] SUPPORTED_INPUT_FORMATS - = new Format[] - { - new AudioFormat( - AudioFormat.LINEAR, - /* sampleRate */ Format.NOT_SPECIFIED, - 16, - /* channels */ Format.NOT_SPECIFIED, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - /* frameSizeInBits */ Format.NOT_SPECIFIED, - /* frameRate */ Format.NOT_SPECIFIED, - Format.byteArray) - }; - - /** - * The list of Formats of audio data supported as output by - * JNIEncoder instances. - */ - private static final Format[] SUPPORTED_OUTPUT_FORMATS - = new Format[] { new AudioFormat(AudioFormat.MPEGLAYER3) }; - - static - { - if (FFmpeg.avcodec_find_encoder(FFmpeg.CODEC_ID_MP3) == 0) - { - throw new RuntimeException( - "Could not find FFmpeg encoder CODEC_ID_MP3"); - } - } - - /** - * The AVCodecContext which performs the actual encoding and which - * is the native counterpart of this open JNIEncoder. - */ - private long avctx; - - /** - * The number of bytes of audio data to be encoded with a single call to - * {@link FFmpeg#avcodec_encode_audio(long, byte[], int, int, byte[], int)} - * based on the frame_size of {@link #avctx}. - */ - private int frameSizeInBytes; - - /** - * The audio data which was given to this JNIEncoder in a previous - * call to {@link #doProcess(Buffer, Buffer)} but was less than - * {@link #frameSizeInBytes} in length and was thus left to be prepended to - * the audio data in a next call to doProcess. - */ - private byte[] prevInput; - - /** - * The length of the valid audio data in {@link #prevInput}. - */ - private int prevInputLength; - - /** - * Initializes a new JNIEncoder instance. - */ - public JNIEncoder() - { - super("MP3 JNI Encoder", AudioFormat.class, SUPPORTED_OUTPUT_FORMATS); - - inputFormats = SUPPORTED_INPUT_FORMATS; - } - - /** - * Implements {@link AbstractCodecExt#doClose()}. - * - * @see AbstractCodecExt#doClose() - */ - protected synchronized void doClose() - { - if (avctx != 0) - { - FFmpeg.avcodec_close(avctx); - FFmpeg.av_free(avctx); - avctx = 0; - } - - prevInput = null; - prevInputLength = 0; - } - - /** - * Opens this Codec and acquires the resources that it needs to - * operate. A call to {@link PlugIn#open()} on this instance will result in - * a call to doOpen only if {@link AbstractCodec#opened} is - * false. All required input and/or output formats are assumed to - * have been set on this Codec before doOpen is called. - * - * @throws ResourceUnavailableException if any of the resources that this - * Codec needs to operate cannot be acquired - * @see AbstractCodecExt#doOpen() - */ - protected synchronized void doOpen() - throws ResourceUnavailableException - { - long encoder = FFmpeg.avcodec_find_encoder(FFmpeg.CODEC_ID_MP3); - - if (encoder == 0) - { - throw new ResourceUnavailableException( - "Could not find FFmpeg encoder CODEC_ID_MP3"); - } - - avctx = FFmpeg.avcodec_alloc_context(); - if (avctx == 0) - { - throw new ResourceUnavailableException( - "Could not allocate AVCodecContext" - + " for FFmpeg encoder CODEC_ID_MP3"); - } - - int avcodec_open = -1; - - try - { - AudioFormat inputFormat = (AudioFormat) getInputFormat(); - int channels = inputFormat.getChannels(); - int sampleRate = (int) inputFormat.getSampleRate(); - - if (channels == Format.NOT_SPECIFIED) - channels = 1; - - FFmpeg.avcodeccontext_set_bit_rate(avctx, 128000); - FFmpeg.avcodeccontext_set_channels(avctx, channels); - - // FIXME - try - { - FFmpeg.avcodeccontext_set_sample_fmt(avctx, - FFmpeg.AV_SAMPLE_FMT_S16); - } - catch (UnsatisfiedLinkError ule) - { - logger.warn("The FFmpeg JNI library is out-of-date."); - } - - if (sampleRate != Format.NOT_SPECIFIED) - FFmpeg.avcodeccontext_set_sample_rate(avctx, sampleRate); - - avcodec_open = FFmpeg.avcodec_open(avctx, encoder); - - frameSizeInBytes - = FFmpeg.avcodeccontext_get_frame_size(avctx) - * (inputFormat.getSampleSizeInBits() / 8) - * channels; - } - finally - { - if (avcodec_open < 0) - { - FFmpeg.av_free(avctx); - avctx = 0; - } - } - if (avctx == 0) - { - throw new ResourceUnavailableException( - "Could not open FFmpeg encoder CODEC_ID_MP3"); - } - } - - /** - * Implements {@link AbstractCodecExt#doProcess(Buffer, Buffer)}. - * - * @param inputBuffer - * @param outputBuffer - * @see AbstractCodecExt#doProcess(Buffer, Buffer) - */ - protected synchronized int doProcess( - Buffer inputBuffer, - Buffer outputBuffer) - { - byte[] input = (byte[]) inputBuffer.getData(); - int inputLength = inputBuffer.getLength(); - int inputOffset = inputBuffer.getOffset(); - - if ((prevInputLength > 0) || (inputLength < frameSizeInBytes)) - { - int newPrevInputLength - = Math.min(frameSizeInBytes - prevInputLength, inputLength); - - if (newPrevInputLength > 0) - { - if (prevInput == null) - { - prevInput = new byte[frameSizeInBytes]; - prevInputLength = 0; - } - - System.arraycopy( - input, inputOffset, - prevInput, prevInputLength, - newPrevInputLength); - - inputBuffer.setLength(inputLength - newPrevInputLength); - inputBuffer.setOffset(inputOffset + newPrevInputLength); - - prevInputLength += newPrevInputLength; - if (prevInputLength == frameSizeInBytes) - { - input = prevInput; - inputLength = prevInputLength; - inputOffset = 0; - - prevInputLength = 0; - } - else - return OUTPUT_BUFFER_NOT_FILLED; - } - } - else - { - inputBuffer.setLength(inputLength - frameSizeInBytes); - inputBuffer.setOffset(inputOffset + frameSizeInBytes); - } - - Object outputData = outputBuffer.getData(); - byte[] output - = (outputData instanceof byte[]) ? (byte[]) outputData : null; - int outputOffset = outputBuffer.getOffset(); - int minOutputLength - = Math.max(FFmpeg.FF_MIN_BUFFER_SIZE, inputLength); - - if ((output == null) - || ((output.length - outputOffset) < minOutputLength)) - { - output = new byte[minOutputLength]; - outputBuffer.setData(output); - outputOffset = 0; - outputBuffer.setOffset(outputOffset); - } - - int outputLength - = FFmpeg.avcodec_encode_audio( - avctx, - output, outputOffset, output.length - outputOffset, - input, inputOffset); - - if (outputLength < 0) - return BUFFER_PROCESSED_FAILED; - else - { - outputBuffer.setLength(outputLength); - - if (inputBuffer.getLength() > 0) - return BUFFER_PROCESSED_OK | INPUT_BUFFER_NOT_CONSUMED; - else - return BUFFER_PROCESSED_OK; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/JavaDecoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/JavaDecoder.java deleted file mode 100644 index b42d460a3..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/JavaDecoder.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; - -/** - * Implements the SILK decoder as an FMJ/JMF Codec. - * - * @author Dingxin Xu - */ -public class JavaDecoder - extends AbstractCodecExt -{ - /** - * The duration of a frame in milliseconds as defined by the SILK standard. - */ - static final int FRAME_DURATION = 20; - - /** - * The maximum number of frames encoded into a single payload as defined by - * the SILK standard. - */ - private static final int MAX_FRAMES_PER_PAYLOAD = 5; - /** - * The list of Formats of audio data supported as input by - * JavaDecoder instances. - */ - private static final Format[] SUPPORTED_INPUT_FORMATS - = JavaEncoder.SUPPORTED_OUTPUT_FORMATS; - - /** - * The list of Formats of audio data supported as output by - * JavaDecoder instances. - */ - private static final Format[] SUPPORTED_OUTPUT_FORMATS - = JavaEncoder.SUPPORTED_INPUT_FORMATS; - - /** - * The SILK decoder control (structure). - */ - private SKP_SILK_SDK_DecControlStruct decControl; - - /** - * The SILK decoder state. - */ - private SKP_Silk_decoder_state decState; - - /** - * The length of an output frame as determined by {@link #FRAME_DURATION} - * and the inputFormat of this JavaDecoder. - */ - private short frameLength; - - /** - * The number of frames decoded from the last input Buffer which - * has not been consumed yet. - */ - private int framesPerPayload; - - /** - * The length of an output frame as reported by - * {@link Silk_dec_API#SKP_Silk_SDK_Decode(Object, SKP_SILK_SDK_DecControlStruct, int, byte[], int, int, short[], int, short[])}. - */ - private final short[] outputLength = new short[1]; - - /** - * Initializes a new JavaDecoder instance. - */ - public JavaDecoder() - { - super("SILK Decoder", AudioFormat.class, SUPPORTED_OUTPUT_FORMATS); - - inputFormats = SUPPORTED_INPUT_FORMATS; - } - - protected void doClose() - { - decState = null; - decControl = null; - } - - protected void doOpen() - throws ResourceUnavailableException - { - decState = new SKP_Silk_decoder_state(); - if (Silk_dec_API.SKP_Silk_SDK_InitDecoder(decState) != 0) - throw - new ResourceUnavailableException( - "Silk_dec_API.SKP_Silk_SDK_InitDecoder"); - - AudioFormat inputFormat = (AudioFormat) getInputFormat(); - double sampleRate = inputFormat.getSampleRate(); - int channels = inputFormat.getChannels(); - - decControl = new SKP_SILK_SDK_DecControlStruct(); - decControl.API_sampleRate = (int) sampleRate; - - frameLength = (short) ((FRAME_DURATION * sampleRate * channels) / 1000); - } - - protected int doProcess(Buffer inputBuffer, Buffer outputBuffer) - { - byte[] inputData = (byte[]) inputBuffer.getData(); - int inputOffset = inputBuffer.getOffset(); - int inputLength = inputBuffer.getLength(); - - short[] outputData = validateShortArraySize(outputBuffer, frameLength); - int outputOffset = 0; - - int processed; - - outputLength[0] = frameLength; - if (Silk_dec_API.SKP_Silk_SDK_Decode( - decState, decControl, - 0, - inputData, inputOffset, inputLength, - outputData, outputOffset, outputLength) - == 0) - { - outputBuffer.setDuration(FRAME_DURATION * 1000000); - outputBuffer.setLength(outputLength[0]); - outputBuffer.setOffset(outputOffset); - - if (decControl.moreInternalDecoderFrames == 0) - processed = BUFFER_PROCESSED_OK; - else - { - framesPerPayload++; - processed - = (framesPerPayload >= MAX_FRAMES_PER_PAYLOAD) - ? BUFFER_PROCESSED_OK - : INPUT_BUFFER_NOT_CONSUMED; - } - } - else - processed = BUFFER_PROCESSED_FAILED; - - if ((processed & INPUT_BUFFER_NOT_CONSUMED) - != INPUT_BUFFER_NOT_CONSUMED) - framesPerPayload = 0; - - return processed; - } - - /** - * Get the output formats matching a specific input format. - * - * @param inputFormat the input format to get the matching output formats of - * @return the output formats matching the specified input format - * @see AbstractCodecExt#getMatchingOutputFormats(Format) - */ - @Override - protected Format[] getMatchingOutputFormats(Format inputFormat) - { - return - JavaEncoder.getMatchingOutputFormats( - inputFormat, - SUPPORTED_INPUT_FORMATS, - SUPPORTED_OUTPUT_FORMATS); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/JavaEncoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/JavaEncoder.java deleted file mode 100644 index 79c8e83d6..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/JavaEncoder.java +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; - -/** - * Implements the SILK encoder as an FMJ/JMF Codec. - * - * @author Dingxin Xu - */ -public class JavaEncoder - extends AbstractCodecExt -{ - private static final int BITRATE = 40000; - - private static final int COMPLEXITY = 2; - - /** - * The maximum number of output payload bytes per input frame. Equals peak - * bitrate of 100 kbps. - */ - private static final int MAX_BYTES_PER_FRAME = 250; - - private static final int PACKET_LOSS_PERCENTAGE = 0; - - /** - * The list of Formats of audio data supported as input by - * JavaEncoder instances. - */ - static final Format[] SUPPORTED_INPUT_FORMATS; - - /** - * The list of Formats of audio data supported as output by - * JavaEncoder instances. - */ - static final Format[] SUPPORTED_OUTPUT_FORMATS; - - /** - * The list of sample rates of audio data supported as input and output by - * JavaEncoder instances. - */ - private static final double[] SUPPORTED_SAMPLE_RATES - = new double[] { 8000, 12000, 16000, 24000 }; - - private static final boolean USE_DTX = false; - - private static final boolean USE_IN_BAND_FEC = false; - - /** - * The duration an output Buffer produced by this Codec - * in nanosecond. - */ - private int duration = JavaDecoder.FRAME_DURATION * 1000000; - - static - { - int supportedCount = SUPPORTED_SAMPLE_RATES.length; - - SUPPORTED_INPUT_FORMATS = new Format[supportedCount]; - SUPPORTED_OUTPUT_FORMATS = new Format[supportedCount]; - for (int i = 0; i < supportedCount; i++) - { - double supportedSampleRate = SUPPORTED_SAMPLE_RATES[i]; - - SUPPORTED_INPUT_FORMATS[i] - = new AudioFormat( - AudioFormat.LINEAR, - supportedSampleRate, - 16, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED /* frameSizeInBits */, - Format.NOT_SPECIFIED /* frameRate */, - Format.shortArray); - SUPPORTED_OUTPUT_FORMATS[i] - = new AudioFormat( - Constants.SILK_RTP, - supportedSampleRate, - Format.NOT_SPECIFIED /* sampleSizeInBits */, - 1, - Format.NOT_SPECIFIED /* endian */, - Format.NOT_SPECIFIED /* signed */, - Format.NOT_SPECIFIED /* frameSizeInBits */, - Format.NOT_SPECIFIED /* frameRate */, - Format.byteArray); - } - } - - /** - * The SILK encoder control (structure). - */ - private SKP_SILK_SDK_EncControlStruct encControl; - - /** - * The SILK encoder state. - */ - private SKP_Silk_encoder_state_FLP encState; - - /** - * The length of an output payload as reported by - * {@link Silk_enc_API#SKP_Silk_SDK_Encode(Object, SKP_SILK_SDK_EncControlStruct, short[], int, int, byte[], int, short[])}. - */ - private final short[] outputLength = new short[1]; - - /** - * Initializes a new JavaEncoder instance. - */ - public JavaEncoder() - { - super("SILK Encoder", AudioFormat.class, SUPPORTED_OUTPUT_FORMATS); - - inputFormats = SUPPORTED_INPUT_FORMATS; - } - - protected void doClose() - { - encState = null; - encControl = null; - } - - protected void doOpen() - throws ResourceUnavailableException - { - encState = new SKP_Silk_encoder_state_FLP(); - encControl = new SKP_SILK_SDK_EncControlStruct(); - if (Silk_enc_API.SKP_Silk_SDK_InitEncoder(encState, encControl) != 0) - throw - new ResourceUnavailableException( - "Silk_enc_API.SKP_Silk_SDK_InitEncoder"); - - AudioFormat inputFormat = (AudioFormat) getInputFormat(); - double sampleRate = inputFormat.getSampleRate(); - int channels = inputFormat.getChannels(); - - encControl.API_sampleRate = (int) sampleRate; - encControl.bitRate = BITRATE; - encControl.complexity = COMPLEXITY; - encControl.maxInternalSampleRate = encControl.API_sampleRate; - encControl.packetLossPercentage = PACKET_LOSS_PERCENTAGE; - encControl.packetSize - = (int) - ((JavaDecoder.FRAME_DURATION * sampleRate * channels) / 1000); - encControl.useDTX = USE_DTX ? 1 : 0; - encControl.useInBandFEC = USE_IN_BAND_FEC ? 1 : 0; - } - - protected int doProcess(Buffer inputBuffer, Buffer outputBuffer) - { - short[] inputData = (short[]) inputBuffer.getData(); - int inputLength = inputBuffer.getLength(); - int inputOffset = inputBuffer.getOffset(); - - if (inputLength > encControl.packetSize) - inputLength = encControl.packetSize; - - byte[] outputData - = validateByteArraySize(outputBuffer, MAX_BYTES_PER_FRAME); - int outputOffset = 0; - - int processed; - - outputLength[0] = MAX_BYTES_PER_FRAME; - if (Silk_enc_API.SKP_Silk_SDK_Encode( - encState, encControl, - inputData, inputOffset, inputLength, - outputData, outputOffset, outputLength) - == 0) - { - outputBuffer.setLength(outputLength[0]); - outputBuffer.setOffset(outputOffset); - processed = BUFFER_PROCESSED_OK; - } - else - processed = BUFFER_PROCESSED_FAILED; - - inputBuffer.setLength(inputBuffer.getLength() - inputLength); - inputBuffer.setOffset(inputBuffer.getOffset() + inputLength); - - if (processed != BUFFER_PROCESSED_FAILED) - { - if(processed == BUFFER_PROCESSED_OK) - { - updateOutput( - outputBuffer, - getOutputFormat(), outputBuffer.getLength(), - outputBuffer.getOffset()); - outputBuffer.setDuration(duration); - } - - if (inputBuffer.getLength() > 0) - processed |= INPUT_BUFFER_NOT_CONSUMED; - } - - return processed; - } - - /** - * Get the output formats matching a specific input format. - * - * @param inputFormat the input format to get the matching output formats of - * @return the output formats matching the specified input format - * @see AbstractCodecExt#getMatchingOutputFormats(Format) - */ - @Override - protected Format[] getMatchingOutputFormats(Format inputFormat) - { - return - getMatchingOutputFormats( - inputFormat, - SUPPORTED_INPUT_FORMATS, - SUPPORTED_OUTPUT_FORMATS); - } - - static Format[] getMatchingOutputFormats( - Format inputFormat, - Format[] supportedInputFormats, - Format[] supportedOutputFormats) - { - if (inputFormat == null) - return supportedOutputFormats; - else - { - Format matchingInputFormat - = matches(inputFormat, supportedInputFormats); - - if (matchingInputFormat == null) - return new Format[0]; - else - { - AudioFormat matchingInputAudioFormat - = (AudioFormat) matchingInputFormat.intersects(inputFormat); - Format outputFormat - = new AudioFormat( - null /* encoding */, - matchingInputAudioFormat.getSampleRate(), - Format.NOT_SPECIFIED /* sampleSizeInBits */, - Format.NOT_SPECIFIED /* channels */, - Format.NOT_SPECIFIED /* endian */, - Format.NOT_SPECIFIED /* signed */, - Format.NOT_SPECIFIED /* frameSizeInBits */, - Format.NOT_SPECIFIED /* frameRate */, - null /* dataType */); - Format matchingOutputFormat - = matches(outputFormat, supportedOutputFormats); - - if (matchingOutputFormat == null) - return new Format[0]; - else - return - new Format[] - { - matchingOutputFormat.intersects(outputFormat) - }; - } - } - } - - /** - * Get the output format. - * - * @return output format - * @see net.sf.fmj.media.AbstractCodec#getOutputFormat() - */ - @Override - public Format getOutputFormat() - { - Format outputFormat = super.getOutputFormat(); - - if ((outputFormat != null) - && (outputFormat.getClass() == AudioFormat.class)) - { - AudioFormat outputAudioFormat = (AudioFormat) outputFormat; - - outputFormat = setOutputFormat( - new AudioFormat( - outputAudioFormat.getEncoding(), - outputAudioFormat.getSampleRate(), - outputAudioFormat.getSampleSizeInBits(), - outputAudioFormat.getChannels(), - outputAudioFormat.getEndian(), - outputAudioFormat.getSigned(), - outputAudioFormat.getFrameSizeInBits(), - outputAudioFormat.getFrameRate(), - outputAudioFormat.getDataType()) - { - private static final long serialVersionUID = 0L; - - @Override - public long computeDuration(long length) - { - return JavaEncoder.this.duration; - } - }); - } - return outputFormat; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_A2NLSF.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_A2NLSF.java deleted file mode 100644 index 258ef0d34..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_A2NLSF.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -class Silk_A2NLSF_constants -{ - /* Number of binary divisions, when not in low complexity mode */ - static final int BIN_DIV_STEPS_A2NLSF_FIX = 2; /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */ - static final int QPoly = 16; - static final int MAX_ITERATIONS_A2NLSF_FIX = 50; - - /* Flag for using 2x as many cosine sampling points, reduces the risk of missing a root */ - static final int OVERSAMPLE_COSINE_TABLE = 0; -} - -/** - * Conversion between prediction filter coefficients and NLSFs. - * Requires the order to be an even number. - * A piecewise linear approximation maps LSF <-> cos(LSF). - * Therefore the result is not accurate NLSFs, but the two. - * function are accurate inverses of each other. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_A2NLSF - extends Silk_A2NLSF_constants -{ - /** - * Helper function for A2NLSF(..). - * Transforms polynomials from cos(n*f) to cos(f)^n. - * @param p Polynomial - * @param dd Polynomial order (= filter order / 2 ) - */ - static void SKP_Silk_A2NLSF_trans_poly( - int[] p, /* I/O Polynomial */ - final int dd /* I Polynomial order (= filter order / 2 ) */ - ) - { - int k, n; - - for( k = 2; k <= dd; k++ ) - { - for( n = dd; n > k; n-- ) - { - p[ n - 2 ] -= p[ n ]; - } - p[ k - 2 ] -= p[ k ] << 1 ; - } - } - - /** - * Helper function for A2NLSF(..). - * Polynomial evaluation. - * @param p Polynomial, QPoly - * @param x Evaluation point, Q12 - * @param dd Order - * @return return the polynomial evaluation, in QPoly - */ - static int SKP_Silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in QPoly */ - int[] p, /* I Polynomial, QPoly */ - final int x, /* I Evaluation point, Q12 */ - final int dd /* I Order */ - ) - { - int n; - int x_Q16, y32; - - y32 = p[ dd ]; /* QPoly */ - x_Q16 = x << 4; - for( n = dd - 1; n >= 0; n-- ) - { - y32 = Silk_macros.SKP_SMLAWW( p[ n ], y32, x_Q16 ); /* QPoly */ - } - return y32; - } - - static void SKP_Silk_A2NLSF_init( - int[] a_Q16, - int[] P, - int[] Q, - final int dd - ) - { - int k; - - /* Convert filter coefs to even and odd polynomials */ - P[dd] = 1 << QPoly; - Q[dd] = 1 << QPoly; - for( k = 0; k < dd; k++ ) - { - if( QPoly < 16 ) - { - P[ k ] = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ], 16 - QPoly ); /* QPoly */ - Q[ k ] = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ], 16 - QPoly ); /* QPoly */ - } - else if( QPoly == 16 ) - { - P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ]; // QPoly - Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ]; // QPoly - } - else - { - P[ k ] = ( -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ] ) << ( QPoly - 16 ); /* QPoly */ - Q[ k ] = ( -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ] ) << ( QPoly - 16 ); /* QPoly */ - } - } - - /* Divide out zeros as we have that for even filter orders, */ - /* z = 1 is always a root in Q, and */ - /* z = -1 is always a root in P */ - for( k = dd; k > 0; k-- ) - { - P[ k - 1 ] -= P[ k ]; - Q[ k - 1 ] += Q[ k ]; - } - - /* Transform polynomials from cos(n*f) to cos(f)^n */ - SKP_Silk_A2NLSF_trans_poly( P, dd ); - SKP_Silk_A2NLSF_trans_poly( Q, dd ); - } - - /** - * Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients. - * If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. - * @param NLSF Normalized Line Spectral Frequencies, Q15 (0 - (2^15-1)), [d] - * @param a_Q16 Monic whitening filter coefficients in Q16 [d] - * @param d Filter order (must be even) - */ - static void SKP_Silk_A2NLSF( - int[] NLSF, /* O Normalized Line Spectral Frequencies, Q15 (0 - (2^15-1)), [d] */ - int[] a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */ - final int d /* I Filter order (must be even) */ - ) - { - int i, k, m, dd, root_ix, ffrac; - int xlo, xhi, xmid; - int ylo, yhi, ymid; - int nom, den; - int[] P = new int[ Silk_SigProc_FIX.SKP_Silk_MAX_ORDER_LPC / 2 + 1 ]; - int[] Q = new int[ Silk_SigProc_FIX.SKP_Silk_MAX_ORDER_LPC / 2 + 1 ]; - int[][] PQ = new int[ 2 ][ ]; - int[] p; - - /* Store pointers to array */ - PQ[ 0 ] = P; - PQ[ 1 ] = Q; - - dd = d >> 1; - - SKP_Silk_A2NLSF_init( a_Q16, P, Q, dd ); - - /* Find roots, alternating between P and Q */ - p = P; /* Pointer to polynomial */ - - xlo = Silk_LSF_cos_table.SKP_Silk_LSFCosTab_FIX_Q12[ 0 ]; // Q12 - ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd ); - - if( ylo < 0 ) - { - /* Set the first NLSF to zero and move on to the next */ - NLSF[ 0 ] = 0; - p = Q; /* Pointer to polynomial */ - ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd ); - root_ix = 1; /* Index of current root */ - } - else - { - root_ix = 0; /* Index of current root */ - } - k = 1; /* Loop counter */ - i = 0; /* Counter for bandwidth expansions applied */ - while( true ) - { - /* Evaluate polynomial */ - if(OVERSAMPLE_COSINE_TABLE!=0) - { - xhi = Silk_LSF_cos_table.SKP_Silk_LSFCosTab_FIX_Q12[ k >> 1 ] + - ( ( Silk_LSF_cos_table.SKP_Silk_LSFCosTab_FIX_Q12[ ( k + 1 ) >> 1 ] - - Silk_LSF_cos_table.SKP_Silk_LSFCosTab_FIX_Q12[ k >> 1 ] ) >> 1 ); /* Q12 */ - } - else - { - xhi = Silk_LSF_cos_table.SKP_Silk_LSFCosTab_FIX_Q12[ k ]; /* Q12 */ - } - - yhi = SKP_Silk_A2NLSF_eval_poly( p, xhi, dd ); - - /* Detect zero crossing */ - if( ( ylo <= 0 && yhi >= 0 ) || ( ylo >= 0 && yhi <= 0 ) ) - { - /* Binary division */ - if(OVERSAMPLE_COSINE_TABLE!=0) - ffrac = -128; - else - ffrac = -256; - - for( m = 0; m < BIN_DIV_STEPS_A2NLSF_FIX; m++ ) - { - /* Evaluate polynomial */ - xmid = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( xlo + xhi, 1 ); - ymid = SKP_Silk_A2NLSF_eval_poly( p, xmid, dd ); - - /* Detect zero crossing */ - if( ( ylo <= 0 && ymid >= 0 ) || ( ylo >= 0 && ymid <= 0 ) ) - { - /* Reduce frequency */ - xhi = xmid; - yhi = ymid; - } - else - { - /* Increase frequency */ - xlo = xmid; - ylo = ymid; - if(OVERSAMPLE_COSINE_TABLE!=0) - ffrac = ffrac + (64>>m); - else - ffrac = ffrac + (128>>m); - } - } - - /* Interpolate */ - if( Math.abs( ylo ) < 65536 ) - { - /* Avoid dividing by zero */ - den = ylo - yhi; - nom = ( ylo << ( 8 - BIN_DIV_STEPS_A2NLSF_FIX ) ) + ( den >> 1 ); - if( den != 0 ) - { - ffrac += nom / den; - } - } - else - { - /* No risk of dividing by zero because abs(ylo - yhi) >= abs(ylo) >= 65536 */ - ffrac += ylo / ( ( ylo - yhi ) >> ( 8 - BIN_DIV_STEPS_A2NLSF_FIX ) ); - } - if(OVERSAMPLE_COSINE_TABLE!=0) - NLSF[ root_ix ] = Math.min( ( k << 7 ) + ffrac, Silk_typedef.SKP_int16_MAX ); - else - NLSF[ root_ix ] = Math.min( ( k << 8 ) + ffrac, Silk_typedef.SKP_int16_MAX ); - - assert( NLSF[ root_ix ] >= 0 ); - assert( NLSF[ root_ix ] <= 32767 ); - - root_ix++; /* Next root */ - if( root_ix >= d ) - { - /* Found all roots */ - break; - } - /* Alternate pointer to polynomial */ - p = PQ[ root_ix & 1 ]; - - /* Evaluate polynomial */ - if(OVERSAMPLE_COSINE_TABLE!=0) - xlo = Silk_LSF_cos_table.SKP_Silk_LSFCosTab_FIX_Q12[ ( k - 1 ) >> 1 ] + - ( ( Silk_LSF_cos_table.SKP_Silk_LSFCosTab_FIX_Q12[ k >> 1 ] - - Silk_LSF_cos_table.SKP_Silk_LSFCosTab_FIX_Q12[ ( k - 1 ) >> 1 ] ) >> 1 ); // Q12 - else - xlo = Silk_LSF_cos_table.SKP_Silk_LSFCosTab_FIX_Q12[ k - 1 ]; // Q12 - - ylo = ( 1 - ( root_ix & 2 ) ) << 12; - } - else - { - /* Increment loop counter */ - k++; - xlo = xhi; - ylo = yhi; - - if (OVERSAMPLE_COSINE_TABLE != 0) - { - if( k > 2 * Silk_SigProc_FIX.LSF_COS_TAB_SZ_FIX ) - { - i++; - if( i > MAX_ITERATIONS_A2NLSF_FIX ) - { - /* Set NLSFs to white spectrum and exit */ - NLSF[ 0 ] = ( 1 << 15 ) / ( d + 1 ); - for( k = 1; k < d; k++ ) - { - NLSF[ k ] = Silk_macros.SKP_SMULBB( k + 1, NLSF[ 0 ] ); - } - return; - } - - /* Error: Apply progressively more bandwidth expansion and run again */ - Silk_bwexpander_32.SKP_Silk_bwexpander_32( a_Q16, d, 65536 - Silk_macros.SKP_SMULBB( 66, i ) ); // 66_Q16 = 0.001 - - SKP_Silk_A2NLSF_init( a_Q16, P, Q, dd ); - p = P; /* Pointer to polynomial */ - xlo = Silk_LSF_cos_table.SKP_Silk_LSFCosTab_FIX_Q12[ 0 ]; // Q12 - ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd ); - if( ylo < 0 ) - { - /* Set the first NLSF to zero and move on to the next */ - NLSF[ 0 ] = 0; - p = Q; /* Pointer to polynomial */ - ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd ); - root_ix = 1; /* Index of current root */ - } - else - { - root_ix = 0; /* Index of current root */ - } - k = 1; /* Reset loop counter */ - } - } - else - { - if( k > Silk_SigProc_FIX.LSF_COS_TAB_SZ_FIX ) - { - i++; - if( i > MAX_ITERATIONS_A2NLSF_FIX ) - { - /* Set NLSFs to white spectrum and exit */ - NLSF[ 0 ] = ( 1 << 15 ) / ( d + 1 ); - for( k = 1; k < d; k++ ) - { - NLSF[ k ] = Silk_macros.SKP_SMULBB( k + 1, NLSF[ 0 ] ); - } - return; - } - - /* Error: Apply progressively more bandwidth expansion and run again */ - Silk_bwexpander_32.SKP_Silk_bwexpander_32( a_Q16, d, 65536 - Silk_macros.SKP_SMULBB( 66, i ) ); // 66_Q16 = 0.001 - - SKP_Silk_A2NLSF_init( a_Q16, P, Q, dd ); - p = P; /* Pointer to polynomial */ - xlo = Silk_LSF_cos_table.SKP_Silk_LSFCosTab_FIX_Q12[ 0 ]; // Q12 - ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd ); - if( ylo < 0 ) - { - /* Set the first NLSF to zero and move on to the next */ - NLSF[ 0 ] = 0; - p = Q; /* Pointer to polynomial */ - ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd ); - root_ix = 1; /* Index of current root */ - } - else - { - root_ix = 0; /* Index of current root */ - } - k = 1; /* Reset loop counter */ - } - } - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_CNG.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_CNG.java deleted file mode 100644 index afb65fcc9..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_CNG.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -import java.util.*; - -/** - * SILK CNG. - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_CNG -{ - /** - * Generates excitation for CNG LPC synthesis. - * @param residual CNG residual signal Q0. - * @param residual_offset offset of the valid data. - * @param exc_buf_Q10 Random samples buffer Q10. - * @param exc_buf_Q10_offset offset of the valid data. - * @param Gain_Q16 Gain to apply - * @param length Length - * @param rand_seed Seed to random index generator - * - */ - static void SKP_Silk_CNG_exc( - short residual[], /* O CNG residual signal Q0 */ - int residual_offset, - int exc_buf_Q10[], /* I Random samples buffer Q10 */ - int exc_buf_Q10_offset, - int Gain_Q16, /* I Gain to apply */ - int length, /* I Length */ - int[] rand_seed /* I/O Seed to random index generator */ - ) - { - int seed; - int i, idx, exc_mask; - - exc_mask = Silk_define.CNG_BUF_MASK_MAX; - while( exc_mask > length ) { - exc_mask = ( exc_mask >> 1 ); - } - - seed = rand_seed[0]; - - for( i = 0; i < length; i++ ) { - seed = Silk_SigProc_FIX.SKP_RAND( seed ); - idx = ( ( seed >> 24 ) & exc_mask ); - Silk_typedef.SKP_assert( idx >= 0 ); - Silk_typedef.SKP_assert( idx <= Silk_define.CNG_BUF_MASK_MAX ); - residual[ residual_offset+i ] = ( short )Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( Silk_macros.SKP_SMULWW( exc_buf_Q10[ idx ], Gain_Q16 ), 10 ) ); - } - rand_seed[0] = seed; - } - - /** - * Reset CNG. - * @param psDec Decoder state. - */ - static void SKP_Silk_CNG_Reset( - SKP_Silk_decoder_state psDec /* I/O Decoder state */ - ) - { - int i, NLSF_step_Q15, NLSF_acc_Q15; - - NLSF_step_Q15 = ( Silk_typedef.SKP_int16_MAX / (psDec.LPC_order + 1) ); - NLSF_acc_Q15 = 0; - for( i = 0; i < psDec.LPC_order; i++ ) { - NLSF_acc_Q15 += NLSF_step_Q15; - psDec.sCNG.CNG_smth_NLSF_Q15[ i ] = NLSF_acc_Q15; - } - psDec.sCNG.CNG_smth_Gain_Q16 = 0; - psDec.sCNG.rand_seed = 3176576; - } - - /** - * Updates CNG estimate, and applies the CNG when packet was lost. - * @param psDec Decoder state. - * @param psDecCtrl Decoder control. - * @param signal Signal. - * @param signal_offset offset of the valid data. - * @param length Length of residual. - */ - static void SKP_Silk_CNG( - SKP_Silk_decoder_state psDec, /* I/O Decoder state */ - SKP_Silk_decoder_control psDecCtrl, /* I/O Decoder control */ - short signal[], /* I/O Signal */ - int signal_offset, - int length /* I Length of residual */ - ) - { - int i, subfr; - int tmp_32, Gain_Q26, max_Gain_Q16; - short[] LPC_buf = new short[Silk_define.MAX_LPC_ORDER]; - short[] CNG_sig = new short[Silk_define.MAX_FRAME_LENGTH]; - - SKP_Silk_CNG_struct psCNG; - - psCNG = psDec.sCNG; - - if( psDec.fs_kHz != psCNG.fs_kHz ) { - /* Reset state */ - SKP_Silk_CNG_Reset( psDec ); - - psCNG.fs_kHz = psDec.fs_kHz; - } - if( psDec.lossCnt == 0 && psDec.vadFlag == Silk_define.NO_VOICE_ACTIVITY ) { - /* Update CNG parameters */ - - /* Smoothing of LSF's */ - for( i = 0; i < psDec.LPC_order; i++ ) { - psCNG.CNG_smth_NLSF_Q15[ i ] += Silk_macros.SKP_SMULWB( psDec.prevNLSF_Q15[ i ] - psCNG.CNG_smth_NLSF_Q15[ i ], Silk_define.CNG_NLSF_SMTH_Q16 ); - } - /* Find the subframe with the highest gain */ - max_Gain_Q16 = 0; - subfr = 0; - for( i = 0; i < Silk_define.NB_SUBFR; i++ ) { - if( psDecCtrl.Gains_Q16[ i ] > max_Gain_Q16 ) { - max_Gain_Q16 = psDecCtrl.Gains_Q16[ i ]; - subfr = i; - } - } - /* Update CNG excitation buffer with excitation from this subframe */ - System.arraycopy(psCNG.CNG_exc_buf_Q10, 0, psCNG.CNG_exc_buf_Q10, psDec.subfr_length, ( Silk_define.NB_SUBFR - 1 ) * psDec.subfr_length); - System.arraycopy(psDec.exc_Q10, subfr * psDec.subfr_length , psCNG.CNG_exc_buf_Q10, 0, psDec.subfr_length); - /* Smooth gains */ - for( i = 0; i < Silk_define.NB_SUBFR; i++ ) { - psCNG.CNG_smth_Gain_Q16 += Silk_macros.SKP_SMULWB( psDecCtrl.Gains_Q16[ i ] - psCNG.CNG_smth_Gain_Q16, Silk_define.CNG_GAIN_SMTH_Q16 ); - } - } - - /* Add CNG when packet is lost and / or when low speech activity */ - if( psDec.lossCnt != 0 ) {//|| psDec.vadFlag == NO_VOICE_ACTIVITY ) { - - /* Generate CNG excitation */ - int[] psCNG_rand_seed_ptr = new int[1]; - psCNG_rand_seed_ptr[0] = psCNG.rand_seed; - - SKP_Silk_CNG_exc( CNG_sig, 0, psCNG.CNG_exc_buf_Q10, 0, - psCNG.CNG_smth_Gain_Q16, length, psCNG_rand_seed_ptr ); - psCNG.rand_seed = psCNG_rand_seed_ptr[0]; - - /* Convert CNG NLSF to filter representation */ - Silk_NLSF2A_stable.SKP_Silk_NLSF2A_stable( LPC_buf, psCNG.CNG_smth_NLSF_Q15, psDec.LPC_order ); - - Gain_Q26 = 1 << 26; /* 1.0 */ - - /* Generate CNG signal, by synthesis filtering */ - if( psDec.LPC_order == 16 ) { - Silk_LPC_synthesis_order16.SKP_Silk_LPC_synthesis_order16( CNG_sig, LPC_buf, - Gain_Q26, psCNG.CNG_synth_state, CNG_sig, length ); - } else { - Silk_LPC_synthesis_filter.SKP_Silk_LPC_synthesis_filter( CNG_sig, LPC_buf, - Gain_Q26, psCNG.CNG_synth_state, CNG_sig, length, psDec.LPC_order ); - } - /* Mix with signal */ - for( i = 0; i < length; i++ ) { - tmp_32 = signal[ signal_offset + i ] + CNG_sig[ i ]; - signal[ signal_offset+i ] = (short) Silk_SigProc_FIX.SKP_SAT16( tmp_32 ); - } - } else { - Arrays.fill(psCNG.CNG_synth_state,0, psDec.LPC_order,0); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_HP_variable_cutoff_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_HP_variable_cutoff_FLP.java deleted file mode 100644 index aae0775a3..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_HP_variable_cutoff_FLP.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_HP_variable_cutoff_FLP -{ - /** - * TODO: TEST - */ - static int frame_cnt = 0; - /** - * High-pass filter with cutoff frequency adaptation based on pitch lag statistics. - * @param psEnc Encoder state FLP - * @param psEncCtrl Encoder control FLP - * @param out High-pass filtered output signal - * @param out_offset offset of valid data. - * @param in Input signal - * @param in_offset offset of valid data. - */ - static void SKP_Silk_HP_variable_cutoff_FLP( - SKP_Silk_encoder_state_FLP psEnc, /* I/O Encoder state FLP */ - SKP_Silk_encoder_control_FLP psEncCtrl, /* I/O Encoder control FLP */ - short[] out, /* O High-pass filtered output signal */ - int out_offset, - short[] in, /* I Input signal */ - int in_offset - ) - { - float pitch_freq_Hz, pitch_freq_log, quality, delta_freq, smth_coef, Fc, r; - int[] B_Q28 = new int[ 3 ], A_Q28 = new int[ 2 ]; - - /*********************************************/ - /* Estimate low end of pitch frequency range */ - /*********************************************/ - if( psEnc.sCmn.prev_sigtype == Silk_define.SIG_TYPE_VOICED ) - { - - /* Difference, in log domain */ - pitch_freq_Hz = 1e3f * psEnc.sCmn.fs_kHz / psEnc.sCmn.prevLag; - pitch_freq_log = Silk_main_FLP.SKP_Silk_log2( pitch_freq_Hz ); - - /* Adjustment based on quality */ - quality = psEncCtrl.input_quality_bands[ 0 ]; - pitch_freq_log -= quality * quality * ( pitch_freq_log - Silk_main_FLP.SKP_Silk_log2( Silk_define_FLP.VARIABLE_HP_MIN_FREQ ) ); - pitch_freq_log += 0.5f * ( 0.6f - quality ); - - delta_freq = pitch_freq_log - psEnc.variable_HP_smth1; - if( delta_freq < 0.0 ) - { - /* Less smoothing for decreasing pitch frequency, to track something close to the minimum */ - delta_freq *= 3.0f; - } - - /* Limit delta, to reduce impact of outliers */ - delta_freq = Silk_SigProc_FLP.SKP_LIMIT_float( delta_freq, -Silk_define_FLP.VARIABLE_HP_MAX_DELTA_FREQ, Silk_define_FLP.VARIABLE_HP_MAX_DELTA_FREQ ); - - /* Update smoother */ - smth_coef = Silk_define_FLP.VARIABLE_HP_SMTH_COEF1 * psEnc.speech_activity; - psEnc.variable_HP_smth1 += smth_coef * delta_freq; - } - - /* Second smoother */ - psEnc.variable_HP_smth2 += Silk_define_FLP.VARIABLE_HP_SMTH_COEF2 * ( psEnc.variable_HP_smth1 - psEnc.variable_HP_smth2 ); - - /* Convert from log scale to Hertz */ - psEncCtrl.pitch_freq_low_Hz = ( float )Math.pow( 2.0, psEnc.variable_HP_smth2 ); - - /* Limit frequency range */ - psEncCtrl.pitch_freq_low_Hz = Silk_SigProc_FLP.SKP_LIMIT_float( psEncCtrl.pitch_freq_low_Hz, Silk_define_FLP.VARIABLE_HP_MIN_FREQ, Silk_define_FLP.VARIABLE_HP_MAX_FREQ ); - - /*******************************/ - /* Compute filter coefficients */ - /*******************************/ - /* Compute cut-off frequency, in radians */ - Fc = ( float )( 0.45f * 2.0f * 3.14159265359 * psEncCtrl.pitch_freq_low_Hz / ( 1e3f * psEnc.sCmn.fs_kHz ) ); - - /* 2nd order ARMA coefficients */ - r = 1.0f - 0.92f * Fc; - - /* b = r * [1; -2; 1]; */ - /* a = [1; -2 * r * (1 - 0.5 * Fc^2); r^2]; */ - B_Q28[ 0 ] = Silk_SigProc_FLP.SKP_float2int( ( 1 << 28 ) * r ); - B_Q28[ 1 ] = Silk_SigProc_FLP.SKP_float2int( ( 1 << 28 ) * -2.0f * r ); - B_Q28[ 2 ] = B_Q28[ 0 ]; - A_Q28[ 0 ] = Silk_SigProc_FLP.SKP_float2int( ( 1 << 28 ) * -2.0f * r * ( 1.0f - 0.5f * Fc * Fc ) ); - A_Q28[ 1 ] = Silk_SigProc_FLP.SKP_float2int( ( 1 << 28 ) * r * r ); - - /********************/ - /* High-pass filter */ - /********************/ - -// /*TEST****************************************************************************/ -// /** -// * test for B_Q28 -// */ -// int[] b_q28 = B_Q28; -// String b_q28_filename = "D:/gsoc/b_q28/b_q28"; -// b_q28_filename += frame_cnt; -// DataInputStream b_q28_datain = null; -// try -// { -// b_q28_datain = new DataInputStream( -// new FileInputStream( -// new File(b_q28_filename))); -// byte[] buffer = new byte[4]; -// for(int ii = 0; ii < b_q28.length; ii++ ) -// { -// try -// { -// -// int res = b_q28_datain.read(buffer); -// if(res != buffer.length) -// { -// throw new IOException("Unexpected End of Stream"); -// } -// b_q28[ii] = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).getInt(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// catch (FileNotFoundException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// finally -// { -// if(b_q28_datain != null) -// { -// try -// { -// b_q28_datain.close(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -//// frame_cnt++; -///*TEST END****************************************************************************/ -// -///*TEST****************************************************************************/ -// /** -// * test for psEnc.x_buf -// */ -// int[] a_q28 = A_Q28; -// String a_q28_filename = "D:/gsoc/a_q28/a_q28"; -// a_q28_filename += frame_cnt; -// DataInputStream a_q28_datain = null; -// try -// { -// a_q28_datain = new DataInputStream( -// new FileInputStream( -// new File(a_q28_filename))); -// byte[] buffer = new byte[4]; -// for(int ii = 0; ii < a_q28.length; ii++ ) -// { -// try -// { -// -// int res = a_q28_datain.read(buffer); -// if(res != buffer.length) -// { -// throw new IOException("Unexpected End of Stream"); -// } -// a_q28[ii] = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).getInt(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// catch (FileNotFoundException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// finally -// { -// if(a_q28_datain != null) -// { -// try -// { -// a_q28_datain.close(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -//// frame_cnt++; -///*TEST END****************************************************************************/ -// -// /*TEST****************************************************************************/ -// /** -// * test for psEnc.sCmn.In_HP_State -// */ -// int[] in_hp_state = psEnc.sCmn.In_HP_State; -// String in_hp_state_filename = "D:/gsoc/in_hp_state/in_hp_state"; -// in_hp_state_filename += frame_cnt; -// DataInputStream in_hp_state_datain = null; -// try -// { -// in_hp_state_datain = new DataInputStream( -// new FileInputStream( -// new File(in_hp_state_filename))); -// byte[] buffer = new byte[4]; -// for(int ii = 0; ii < in_hp_state.length; ii++ ) -// { -// try -// { -// -// int res = in_hp_state_datain.read(buffer); -// if(res != buffer.length) -// { -// throw new IOException("Unexpected End of Stream"); -// } -// in_hp_state[ii] = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).getInt(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// catch (FileNotFoundException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// finally -// { -// if(in_hp_state_datain != null) -// { -// try -// { -// in_hp_state_datain.close(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -//// frame_cnt++; -///*TEST END****************************************************************************/ - -// /*TEST****************************************************************************/ -// /** -// * test for in -// */ -// short[] in_test = in; -// String in_test_filename = "D:/gsoc/in_test/in_test"; -// in_test_filename += frame_cnt; -// DataInputStream in_test_datain = null; -// try -// { -// in_test_datain = new DataInputStream( -// new FileInputStream( -// new File(in_test_filename))); -// byte[] buffer = new byte[2]; -// for(int ii = 0; ii < in_test.length; ii++ ) -// { -// try -// { -// -// int res = in_test_datain.read(buffer); -// if(res != buffer.length) -// { -// throw new IOException("Unexpected End of Stream"); -// } -// in_test[ii] = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).getShort(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// catch (FileNotFoundException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// finally -// { -// if(in_test_datain != null) -// { -// try -// { -// in_test_datain.close(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// frame_cnt++; -///*TEST END****************************************************************************/ - - Silk_biquad_alt.SKP_Silk_biquad_alt( in,in_offset, B_Q28, A_Q28, psEnc.sCmn.In_HP_State, out,out_offset, psEnc.sCmn.frame_length ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_Inlines.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_Inlines.java deleted file mode 100644 index ad77e31be..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_Inlines.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -class Silk_Inlines_constants -{ - static final int SKP_SIN_APPROX_CONST0 = 1073735400; - static final int SKP_SIN_APPROX_CONST1 = -82778932; - static final int SKP_SIN_APPROX_CONST2 = 1059577; - static final int SKP_SIN_APPROX_CONST3 = -5013; -} - -public class Silk_Inlines - extends Silk_Inlines_constants -{ - /** - * count leading zeros of long. - * @param in. input - * @return - */ - static int SKP_Silk_CLZ64(long in) - { - return Long.numberOfLeadingZeros(in); - } - - /** - * get number of leading zeros and fractional part (the bits right after the leading one). - * @param in - * @param lz - * @param frac_Q7 - */ - static void SKP_Silk_CLZ_FRAC(int in, /* I: input */ - int[] lz, /* O: number of leading zeros */ - int[] frac_Q7) /* O: the 7 bits right after the leading one */ - { - int lzeros = Integer.numberOfLeadingZeros(in); - - lz[0] = lzeros; - frac_Q7[0] = Silk_SigProc_FIX.SKP_ROR32(in, 24 - lzeros) & 0x7f; - } - - /** - * Approximation of square root - * Accuracy: < +/- 10% for output values > 15 - < +/- 2.5% for output values > 120 - * @param x - * @return - */ - static int SKP_Silk_SQRT_APPROX(int x) - { - int y; - int[] lz = new int[1], frac_Q7 = new int[1]; - - if( x <= 0 ) - { - return 0; - } - - SKP_Silk_CLZ_FRAC(x, lz, frac_Q7); - - if( (lz[0] & 1) != 0 ) - { - y = 32768; - } - else - { - y = 46214; /* 46214 = sqrt(2) * 32768 */ - } - - /* get scaling right */ - y >>= (lz[0]>>1); - - /* increment using fractional part of input */ - y = Silk_macros.SKP_SMLAWB(y, y, Silk_macros.SKP_SMULBB(213, frac_Q7[0])); - - return y; - } - - /** - * returns the number of left shifts before overflow for a 16 bit - * number (ITU definition with norm(0)=0). - * @param a - * @return - */ - static int SKP_Silk_norm16(short a) - { - int a32; - - /* if ((a == 0) || (a == SKP_int16_MIN)) return(0); */ - if ((a << 1) == 0) - return(0); - - a32 = a; - /* if (a32 < 0) a32 = -a32 - 1; */ - a32 ^= (a32>>31); - - return Integer.numberOfLeadingZeros(a32) - 17; - } - - /** - * returns the number of left shifts before overflow for a 32 bit - * number (ITU definition with norm(0)=0) - * @param a - * @return - */ - static int SKP_Silk_norm32(int a) - { - - /* if ((a == 0) || (a == Interger.MIN_VALUE)) return(0); */ - if ((a << 1) == 0) - return(0); - - /* if (a < 0) a = -a - 1; */ - a ^= (a>>31); - - return Integer.numberOfLeadingZeros(a) - 1; - } - - /** - * Divide two int32 values and return result as int32 in a given Q-domain. - * @param a32 numerator (Q0) - * @param b32 denominator (Q0) - * @param Qres Q-domain of result (>= 0) - * @return returns a good approximation of "(a32 << Qres) / b32" - */ - static int SKP_DIV32_varQ /* O returns a good approximation of "(a32 << Qres) / b32" */ - ( - final int a32, /* I numerator (Q0) */ - final int b32, /* I denominator (Q0) */ - final int Qres /* I Q-domain of result (>= 0) */ - ) - { - int a_headrm, b_headrm, lshift; - int b32_inv, a32_nrm, b32_nrm, result; - - assert( b32 != 0 ); - assert( Qres >= 0 ); - - /* Compute number of bits head room and normalize inputs */ - a_headrm = Integer.numberOfLeadingZeros( Math.abs(a32) ) - 1; - a32_nrm = a32<> 2) / (b32_nrm>>16) ; /* Q: 29 + 16 - b_headrm */ - - /* First approximation */ - result = Silk_macros.SKP_SMULWB(a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */ - - /* Compute residual by subtracting product of denominator and first approximation */ - a32_nrm -= Silk_SigProc_FIX.SKP_SMMUL(b32_nrm, result)<<3; /* Q: a_headrm */ - - /* Refinement */ - result = Silk_macros.SKP_SMLAWB(result, a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */ - - /* Convert to Qres domain */ - lshift = 29 + a_headrm - b_headrm - Qres; - if( lshift <= 0 ) - { - return Silk_SigProc_FIX.SKP_LSHIFT_SAT32(result, -lshift); - } - else - { - if( lshift < 32) - { - return result>>lshift; - } - else - { - /* Avoid undefined result */ - return 0; - } - } - } - - /** - * Invert int32 value and return result as int32 in a given Q-domain. - * @param b32 denominator (Q0) - * @param Qres Q-domain of result (> 0) - * @return returns a good approximation of "(1 << Qres) / b32" - */ - static int SKP_INVERSE32_varQ /* O returns a good approximation of "(1 << Qres) / b32" */ - ( - final int b32, /* I denominator (Q0) */ - final int Qres /* I Q-domain of result (> 0) */ - ) - { - int b_headrm, lshift; - int b32_inv, b32_nrm, err_Q32, result; - - assert( b32 != 0 ); - assert( Qres > 0 ); - - /* Compute number of bits head room and normalize input */ - b_headrm = Integer.numberOfLeadingZeros( Math.abs(b32) ) - 1; - b32_nrm = b32<> 2) / (b32_nrm>>16); /* Q: 29 + 16 - b_headrm */ - - /* First approximation */ - result = b32_inv<<16; /* Q: 61 - b_headrm */ - - /* Compute residual by subtracting product of denominator and first approximation from one */ - err_Q32 = -Silk_macros.SKP_SMULWB(b32_nrm, b32_inv)<<3; /* Q32 */ - - /* Refinement */ - result = Silk_macros.SKP_SMLAWW(result, err_Q32, b32_inv); /* Q: 61 - b_headrm */ - - /* Convert to Qres domain */ - lshift = 61 - b_headrm - Qres; - if( lshift <= 0 ) - { - return Silk_SigProc_FIX.SKP_LSHIFT_SAT32(result, -lshift); - } - else - { - if( lshift < 32) - { - return result>>lshift; - } - else - { - /* Avoid undefined result */ - return 0; - } - } - } - - /** - * Sine approximation; an input of 65536 corresponds to 2 * pi - * Uses polynomial expansion of the input to the power 0, 2, 4 and 6 - * The relative error is below 1e-5 - * - * @param x - * @return returns approximately 2^24 * sin(x * 2 * pi / 65536). - */ - static int SKP_Silk_SIN_APPROX_Q24( /* O returns approximately 2^24 * sin(x * 2 * pi / 65536) */ - int x) - { - int y_Q30; - - /* Keep only bottom 16 bits (the function repeats itself with period 65536) */ - x &= 65535; - - /* Split range in four quadrants */ - if( x <= 32768 ) - { - if( x < 16384 ) - { - /* Return cos(pi/2 - x) */ - x = 16384 - x; - } - else - { - /* Return cos(x - pi/2) */ - x -= 16384; - } - if( x < 1100 ) - { - /* Special case: high accuracy */ - return Silk_macros.SKP_SMLAWB( 1 << 24, x*x, -5053 ); - } - x = Silk_macros.SKP_SMULWB( x<<8 , x ); /* contains x^2 in Q20 */ - y_Q30 = Silk_macros.SKP_SMLAWB( SKP_SIN_APPROX_CONST2, x, SKP_SIN_APPROX_CONST3 ); - y_Q30 = Silk_macros.SKP_SMLAWW( SKP_SIN_APPROX_CONST1, x, y_Q30 ); - y_Q30 = Silk_macros.SKP_SMLAWW( SKP_SIN_APPROX_CONST0 + 66, x, y_Q30 ); - } - else - { - if( x < 49152 ) - { - /* Return -cos(3*pi/2 - x) */ - x = 49152 - x; - } - else - { - /* Return -cos(x - 3*pi/2) */ - x -= 49152; - } - if( x < 1100 ) - { - /* Special case: high accuracy */ - return Silk_macros.SKP_SMLAWB( -1 << 24, x*x , 5053 ); - } - x = Silk_macros.SKP_SMULWB( x<<8 , x ); /* contains x^2 in Q20 */ - y_Q30 = Silk_macros.SKP_SMLAWB( -SKP_SIN_APPROX_CONST2, x, -SKP_SIN_APPROX_CONST3 ); - y_Q30 = Silk_macros.SKP_SMLAWW( -SKP_SIN_APPROX_CONST1, x, y_Q30 ); - y_Q30 = Silk_macros.SKP_SMLAWW( -SKP_SIN_APPROX_CONST0, x, y_Q30 ); - } - return Silk_SigProc_FIX.SKP_RSHIFT_ROUND( y_Q30, 6 ); - } - - /** - * Cosine approximation; an input of 65536 corresponds to 2 * pi - * The relative error is below 1e-5 - * @param x - * @return returns approximately 2^24 * cos(x * 2 * pi / 65536). - */ - static int SKP_Silk_COS_APPROX_Q24( /* O returns approximately 2^24 * cos(x * 2 * pi / 65536) */ - int x) - { - return SKP_Silk_SIN_APPROX_Q24( x + 16384 ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LBRR_reset.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LBRR_reset.java deleted file mode 100644 index c8f0edcaf..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LBRR_reset.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_LBRR_reset -{ - /** - * Resets LBRR buffer, used if packet size changes. - * - * @param psEncC state - */ - static void SKP_Silk_LBRR_reset( - SKP_Silk_encoder_state psEncC /* I/O state */ - ) - { - int i; - - for( i = 0; i < Silk_define.MAX_LBRR_DELAY; i++ ) { - psEncC.LBRR_buffer[ i ].usage = Silk_define.SKP_SILK_NO_LBRR; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_analysis_filter_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_analysis_filter_FLP.java deleted file mode 100644 index 037c6e157..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_analysis_filter_FLP.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * LPC analysis filter - * NB! State is kept internally and the - * filter always starts with zero state - * first Order output samples are not set - * - * @author Jing Dai - * @author Dignxin Xu - */ -public class Silk_LPC_analysis_filter_FLP -{ - /** - * - * @param r_LPC LPC residual signal - * @param PredCoef LPC coefficients - * @param s Input signal - * @param s_offset offset of valid data. - * @param length Length of input signal - * @param Order LPC order - */ - static void SKP_Silk_LPC_analysis_filter_FLP( - float r_LPC[], /* O LPC residual signal */ - float PredCoef[], /* I LPC coefficients */ - float s[], /* I Input signal */ - int s_offset, - final int length, /* I Length of input signal */ - final int Order /* I LPC order */ - ) - { - assert( Order <= length ); - - switch( Order ) - { - case 8: - SKP_Silk_LPC_analysis_filter8_FLP( r_LPC, PredCoef, s, s_offset, length ); - break; - - case 10: - SKP_Silk_LPC_analysis_filter10_FLP( r_LPC, PredCoef, s, s_offset, length ); - break; - - case 12: - SKP_Silk_LPC_analysis_filter12_FLP( r_LPC, PredCoef, s, s_offset, length ); - break; - - case 16: - SKP_Silk_LPC_analysis_filter16_FLP( r_LPC, PredCoef, s, s_offset, length ); - break; - - default: - assert( false ); - break; - } - - /* Set first LPC Order samples to zero instead of undefined */ - for(int i=0; i 0; k-- ) { - /* Check for stability */ - if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) { - return 1; - } - - /* Set RC equal to negated AR coef */ - rc_Q31 = -( Anew_QA[ k ] << (31 - QA) ); - - /* rc_mult1_Q30 range: [ 1 : 2^30-1 ] */ - rc_mult1_Q30 = ( Silk_typedef.SKP_int32_MAX >> 1 ) - Silk_SigProc_FIX.SKP_SMMUL( rc_Q31, rc_Q31 ); - Silk_typedef.SKP_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */ - Silk_typedef.SKP_assert( rc_mult1_Q30 < ( 1 << 30 ) ); - - /* rc_mult2_Q16 range: [ 2^16 : SKP_int32_MAX ] */ - rc_mult2_Q16 = Silk_Inlines.SKP_INVERSE32_varQ( rc_mult1_Q30, 46 ); /* 16 = 46 - 30 */ - - /* Update inverse gain */ - /* invGain_Q30 range: [ 0 : 2^30 ] */ - invGain_Q30[0] = ( Silk_SigProc_FIX.SKP_SMMUL( invGain_Q30[0], rc_mult1_Q30 ) << 2 ); - - Silk_typedef.SKP_assert( invGain_Q30[0] >= 0 ); - Silk_typedef.SKP_assert( invGain_Q30[0] <= ( 1 << 30 ) ); - - /* Swap pointers */ - Aold_QA = Anew_QA; - Anew_QA = Atmp_QA[ k & 1 ]; - - /* Update AR coefficient */ - headrm = Silk_macros.SKP_Silk_CLZ32( rc_mult2_Q16 ) - 1; - rc_mult2_Q16 = ( rc_mult2_Q16 << headrm ); /* Q: 16 + headrm */ - for( n = 0; n < k; n++ ) { - tmp_QA = Aold_QA[ n ] - ( Silk_SigProc_FIX.SKP_SMMUL( Aold_QA[ k - n - 1 ], rc_Q31 ) << 1 ); - Anew_QA[ n ] = ( Silk_SigProc_FIX.SKP_SMMUL( tmp_QA, rc_mult2_Q16 ) << (16 - headrm) ); - } - } - - /* Check for stability */ - if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) { - return 1; - } - - /* Set RC equal to negated AR coef */ - rc_Q31 = -( Anew_QA[ 0 ] <<( 31 - QA )); - - /* Range: [ 1 : 2^30 ] */ - rc_mult1_Q30 = ( Silk_typedef.SKP_int32_MAX >> 1 ) - Silk_SigProc_FIX.SKP_SMMUL( rc_Q31, rc_Q31 ); - - /* Update inverse gain */ - /* Range: [ 0 : 2^30 ] */ - invGain_Q30[0] = ( Silk_SigProc_FIX.SKP_SMMUL( invGain_Q30[0], rc_mult1_Q30 ) << 2 ); - Silk_typedef.SKP_assert( invGain_Q30[0] >= 0 ); - Silk_typedef.SKP_assert( invGain_Q30[0] <= 1<<30 ); - - return 0; - } - - /** - * For input in Q13 domain. - * @param invGain_Q30 Inverse prediction gain, Q30 energy domain. - * @param A_Q13 Prediction coefficients, Q13 [order]. - * @param order Prediction order. - * @return Returns 1 if unstable, otherwise 0. - */ - static int SKP_Silk_LPC_inverse_pred_gain_Q13( /* O: Returns 1 if unstable, otherwise 0 */ - int []invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */ - short []A_Q13, /* I: Prediction coefficients, Q13 [order] */ - final int order /* I: Prediction order */ - ) - { - int k, n, headrm; - int rc_Q31, rc_mult1_Q30, rc_mult2_Q16; - int[][] Atmp_QA = new int[ 2 ][ Silk_SigProc_FIX.SKP_Silk_MAX_ORDER_LPC ]; - int tmp_QA; - - int []Aold_QA, Anew_QA; - - Anew_QA = Atmp_QA[ order & 1 ]; - /* Increase Q domain of the AR coefficients */ - for( k = 0; k < order; k++ ) { - Anew_QA[ k ] = ( A_Q13[ k ] <<( QA - 13 )); - } - - invGain_Q30[0] = ( 1 << 30 ); - for( k = order - 1; k > 0; k-- ) { - /* Check for stability */ - if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) { - return 1; - } - - /* Set RC equal to negated AR coef */ - rc_Q31 = -( Anew_QA[ k ] <<(31 - QA) ); - - /* rc_mult1_Q30 range: [ 1 : 2^30-1 ] */ - rc_mult1_Q30 = ( Silk_typedef.SKP_int32_MAX >> 1 ) - Silk_SigProc_FIX.SKP_SMMUL( rc_Q31, rc_Q31 ); - assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */ - assert( rc_mult1_Q30 < ( 1 << 30 ) ); - - /* rc_mult2_Q16 range: [ 2^16 : SKP_int32_MAX ] */ - rc_mult2_Q16 = Silk_Inlines.SKP_INVERSE32_varQ( rc_mult1_Q30, 46 ); /* 16 = 46 - 30 */ - - /* Update inverse gain */ - /* invGain_Q30 range: [ 0 : 2^30 ] */ - invGain_Q30[0] = ( Silk_SigProc_FIX.SKP_SMMUL(invGain_Q30[0], rc_mult1_Q30 ) << 2 ); - Silk_typedef.SKP_assert( invGain_Q30[0] >= 0 ); - Silk_typedef.SKP_assert( invGain_Q30[0] <= 1<<30 ); - - /* Swap pointers */ - Aold_QA = Anew_QA; - Anew_QA = Atmp_QA[ k & 1 ]; - - /* Update AR coefficient */ - headrm = Silk_macros.SKP_Silk_CLZ32( rc_mult2_Q16 ) - 1; - rc_mult2_Q16 = ( rc_mult2_Q16 << headrm ); /* Q: 16 + headrm */ - for( n = 0; n < k; n++ ) { - tmp_QA = Aold_QA[ n ] - ( Silk_SigProc_FIX.SKP_SMMUL( Aold_QA[ k - n - 1 ], rc_Q31 ) << 1 ); - Anew_QA[ n ] = ( Silk_SigProc_FIX.SKP_SMMUL( tmp_QA, rc_mult2_Q16 ) << (16 - headrm) ); - } - } - - /* Check for stability */ - if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) { - return 1; - } - - /* Set RC equal to negated AR coef */ - rc_Q31 = -( Anew_QA[ 0 ] << (31 - QA )); - - /* Range: [ 1 : 2^30 ] */ - rc_mult1_Q30 = ( Silk_typedef.SKP_int32_MAX >> 1 ) - Silk_SigProc_FIX.SKP_SMMUL( rc_Q31, rc_Q31 ); - - /* Update inverse gain */ - /* Range: [ 0 : 2^30 ] */ - invGain_Q30[0] = ( Silk_SigProc_FIX.SKP_SMMUL( invGain_Q30[0], rc_mult1_Q30 ) << 2 ); - Silk_typedef.SKP_assert( invGain_Q30[0] >= 0 ); - Silk_typedef.SKP_assert( invGain_Q30[0] <= 1<<30 ); - - return 0; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_inv_pred_gain_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_inv_pred_gain_FLP.java deleted file mode 100644 index 470d95732..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_inv_pred_gain_FLP.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * compute inverse of LPC prediction gain, and - * test if LPC coefficients are stable (all poles within unit circle) - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_LPC_inv_pred_gain_FLP -{ - static final float RC_THRESHOLD = 0.9999f; - - /** - * compute inverse of LPC prediction gain, and - * test if LPC coefficients are stable (all poles within unit circle) - * this code is based on SKP_Silk_a2k_FLP(). - * @param invGain inverse prediction gain, energy domain - * @param A prediction coefficients [order] - * @param A_offset offset of valid data. - * @param order prediction order - * @return returns 1 if unstable, otherwise 0 - */ - static int SKP_Silk_LPC_inverse_pred_gain_FLP( /* O: returns 1 if unstable, otherwise 0 */ - float[] invGain, /* O: inverse prediction gain, energy domain */ - float[] A, /* I: prediction coefficients [order] */ - int A_offset, - int order /* I: prediction order */ - ) - { - int k, n; - double rc, rc_mult1, rc_mult2; - float[][] Atmp = new float[ 2 ][ Silk_SigProc_FIX.SKP_Silk_MAX_ORDER_LPC ]; - float[] Aold, Anew; - - Anew = Atmp[ order & 1 ]; - for(int i_djinn=0; i_djinn 0; k-- ) - { - rc = -Anew[ k ]; - if (rc > RC_THRESHOLD || rc < -RC_THRESHOLD) - { - return 1; - } - rc_mult1 = 1.0f - rc * rc; - rc_mult2 = 1.0f / rc_mult1; - invGain[0] *= (float)rc_mult1; - /* swap pointers */ - Aold = Anew; - Anew = Atmp[ k & 1 ]; - for( n = 0; n < k; n++ ) { - Anew[ n ] = (float)( ( Aold[ n ] - Aold[ k - n - 1 ] * rc ) * rc_mult2 ); - } - } - rc = -Anew[ 0 ]; - if ( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) { - return 1; - } - rc_mult1 = 1.0f - rc * rc; - invGain[0] *= (float)rc_mult1; - return 0; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_stabilize.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_stabilize.java deleted file mode 100644 index 1d9eed05f..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_stabilize.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -public class Silk_LPC_stabilize -{ - - static final int LPC_STABILIZE_LPC_MAX_ABS_VALUE_Q16 =( ( Short.MAX_VALUE ) << 4 ); - - /** - * LPC stabilizer, for a single input data vector. - * @param a_Q12 stabilized LPC vector [L] - * @param a_Q16 LPC vector [L] - * @param bwe_Q16 Bandwidth expansion factor - * @param L Number of LPC parameters in the input vector - */ - static void SKP_Silk_LPC_stabilize( - short []a_Q12, /* O stabilized LPC vector [L] */ - int []a_Q16, /* I LPC vector [L] */ - final int bwe_Q16, /* I Bandwidth expansion factor */ - final int L /* I Number of LPC parameters in the input vector */ - ) - { - int maxabs, absval, sc_Q16; - int i, idx = 0; - int invGain_Q30=0; - - Silk_bwexpander_32.SKP_Silk_bwexpander_32( a_Q16, L, bwe_Q16 ); - - /***************************/ - /* Limit range of the LPCs */ - /***************************/ - /* Limit the maximum absolute value of the prediction coefficients */ - while( true ) { - /* Find maximum absolute value and its index */ - maxabs = Integer.MIN_VALUE; - for( i = 0; i < L; i++ ) { - absval = Math.abs( a_Q16[ i ] ); - if( absval > maxabs ) { - maxabs = absval; - idx = i; - } - } - - if( maxabs >= LPC_STABILIZE_LPC_MAX_ABS_VALUE_Q16 ) { - /* Reduce magnitude of prediction coefficients */ - sc_Q16 = ( Integer.MAX_VALUE / ( maxabs >> 4 ) ); - sc_Q16 = 65536 - sc_Q16; - sc_Q16 = ( sc_Q16 /(idx + 1) ); - sc_Q16 = 65536 - sc_Q16; - sc_Q16 = ( Silk_macros.SKP_SMULWB( sc_Q16, 32604 ) << 1 ); // 0.995 in Q16 - Silk_bwexpander_32.SKP_Silk_bwexpander_32( a_Q16, L, sc_Q16 ); - } else { - break; - } - } - - /* Convert to 16 bit Q12 */ - for( i = 0; i < L; i++ ) { - a_Q12[ i ] = (short)Silk_SigProc_FIX.SKP_RSHIFT_ROUND( a_Q16[ i ], 4 ); - } - - /**********************/ - /* Ensure stable LPCs */ - /**********************/ - int invGain_Q30_ptr[] = new int[1]; - invGain_Q30_ptr[0] = invGain_Q30; - while( Silk_LPC_inv_pred_gain.SKP_Silk_LPC_inverse_pred_gain( invGain_Q30_ptr, a_Q12, L ) == 1 ) { - invGain_Q30 = invGain_Q30_ptr[0]; - Silk_bwexpander.SKP_Silk_bwexpander( a_Q12, L, 65339 ); // 0.997 in Q16 - } - } - - /** - * - * @param a_QQ Stabilized LPC vector, Q(24-rshift) [L] - * @param a_Q24 LPC vector [L] - * @param QQ Q domain of output LPC vector - * @param L Number of LPC parameters in the input vector - */ - static void SKP_Silk_LPC_fit( - short []a_QQ, /* O Stabilized LPC vector, Q(24-rshift) [L] */ - int []a_Q24, /* I LPC vector [L] */ - final int QQ, /* I Q domain of output LPC vector */ - final int L /* I Number of LPC parameters in the input vector */ - ) - { - int i, rshift, idx = 0; - int maxabs, absval, sc_Q16; - - rshift = 24 - QQ; - - /***************************/ - /* Limit range of the LPCs */ - /***************************/ - /* Limit the maximum absolute value of the prediction coefficients */ - while( true ) { - /* Find maximum absolute value and its index */ - maxabs = Integer.MIN_VALUE; - for( i = 0; i < L; i++ ) { - absval = Math.abs( a_Q24[ i ] ); - if( absval > maxabs ) { - maxabs = absval; - idx = i; - } - } - - maxabs = ( maxabs >> rshift ); - if( maxabs >= Short.MAX_VALUE ) { - /* Reduce magnitude of prediction coefficients */ - maxabs = Math.min( maxabs, 98369 ); // ( SKP_int32_MAX / ( 65470 >> 2 ) ) + SKP_int16_MAX = 98369 - sc_Q16 = 65470 - ( ( (65470 >> 2) * (maxabs - Short.MAX_VALUE) ) / - Silk_SigProc_FIX.SKP_RSHIFT32(( maxabs * (idx + 1)), 2 ) ); - Silk_bwexpander_32.SKP_Silk_bwexpander_32( a_Q24, L, sc_Q16 ); - } else { - break; - } - } - - /* Convert to 16 bit Q(24-rshift) */ - assert( rshift > 0 ); - assert( rshift < 31 ); - for( i = 0; i < L; i++ ) { - a_QQ[ i ] = (short)Silk_SigProc_FIX.SKP_RSHIFT_ROUND( a_Q24[ i ], rshift ); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_synthesis_filter.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_synthesis_filter.java deleted file mode 100644 index da836bbd5..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_synthesis_filter.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * even order AR filter. - * Coefficients are in Q12 - * - * @author Jing Dai - */ -public class Silk_LPC_synthesis_filter -{ - /** - * even order AR filter. - * @param in excitation signal - * @param A_Q12 AR coefficients [Order], between -8_Q0 and 8_Q0 - * @param Gain_Q26 gain - * @param S state vector [Order] - * @param out output signal - * @param len signal length - * @param Order filter order, must be even - */ - static void SKP_Silk_LPC_synthesis_filter - ( - short []in, /* I: excitation signal */ - short []A_Q12, /* I: AR coefficients [Order], between -8_Q0 and 8_Q0 */ - final int Gain_Q26, /* I: gain */ - int []S, /* I/O: state vector [Order] */ - short []out, /* O: output signal */ - final int len, /* I: signal length */ - final int Order /* I: filter order, must be even */ - ) - { - int k, j, idx; - int Order_half = ( Order >> 1 ); - int SA, SB, out32_Q10, out32; - - /* Order must be even */ - Silk_typedef.SKP_assert( 2 * Order_half == Order ); - - /* S[] values are in Q14 */ - for( k = 0; k < len; k++ ) { - SA = S[ Order - 1 ]; - out32_Q10 = 0; - for( j = 0; j < ( Order_half - 1 ); j++ ) { - idx = Silk_macros.SKP_SMULBB( 2, j ) + 1; - SB = S[ Order - 1 - idx ]; - S[ Order - 1 - idx ] = SA; - out32_Q10 = Silk_macros.SKP_SMLAWB( out32_Q10, SA, A_Q12[ ( j << 1 ) ] ); - out32_Q10 = Silk_macros.SKP_SMLAWB( out32_Q10, SB, A_Q12[ ( j << 1 ) + 1 ] ); - SA = S[ Order - 2 - idx ]; - S[ Order - 2 - idx ] = SB; - } - - /* unrolled loop: epilog */ - SB = S[ 0 ]; - S[ 0 ] = SA; - out32_Q10 = Silk_macros.SKP_SMLAWB( out32_Q10, SA, A_Q12[ Order - 2 ] ); - out32_Q10 = Silk_macros.SKP_SMLAWB( out32_Q10, SB, A_Q12[ Order - 1 ] ); - /* apply gain to excitation signal and add to prediction */ - out32_Q10 = Silk_macros.SKP_ADD_SAT32( out32_Q10, Silk_macros.SKP_SMULWB( Gain_Q26, in[ k ] ) ); - - /* scale to Q0 */ - out32 = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( out32_Q10, 10 ); - - /* saturate output */ - out[ k ] = ( short )Silk_SigProc_FIX.SKP_SAT16( out32 ); - - /* move result into delay line */ - S[ Order - 1 ] = Silk_SigProc_FIX.SKP_LSHIFT_SAT32( out32_Q10, 4 ); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_synthesis_order16.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_synthesis_order16.java deleted file mode 100644 index 6223a77e4..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LPC_synthesis_order16.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * 16th order AR filter. - * Coefficients are in Q12. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_LPC_synthesis_order16 -{ - /** - * 16th order AR filter - * @param in excitation signal - * @param A_Q12 AR coefficients [16], between -8_Q0 and 8_Q0 - * @param Gain_Q26 gain - * @param S state vector [16] - * @param out output signal - * @param len signal length, must be multiple of 16 - */ - static void SKP_Silk_LPC_synthesis_order16 - ( - short []in, /* I: excitation signal */ - short []A_Q12, /* I: AR coefficients [16], between -8_Q0 and 8_Q0 */ - final int Gain_Q26, /* I: gain */ - int []S, /* I/O: state vector [16] */ - short []out, /* O: output signal */ - final int len /* I: signal length, must be multiple of 16 */ - ) - { - int k; - int SA, SB, out32_Q10, out32; - for( k = 0; k < len; k++ ) { - /* unrolled loop: prolog */ - /* multiply-add two prediction coefficients per iteration */ - SA = S[ 15 ]; - SB = S[ 14 ]; - S[ 14 ] = SA; - out32_Q10 = Silk_macros.SKP_SMULWB(SA, A_Q12[ 0 ]); - out32_Q10 = Silk_SigProc_FIX.SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 1 ] ); - SA = S[ 13 ]; - S[ 13 ] = SB; - - /* unrolled loop: main loop */ - SB = S[ 12 ]; - S[ 12 ] = SA; - out32_Q10 = Silk_SigProc_FIX.SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 2 ] ); - out32_Q10 = Silk_SigProc_FIX.SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 3 ] ); - SA = S[ 11 ]; - S[ 11 ] = SB; - - SB = S[ 10 ]; - S[ 10 ] = SA; - out32_Q10 = Silk_SigProc_FIX.SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 4 ] ); - out32_Q10 = Silk_SigProc_FIX.SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 5 ] ); - - SA = S[ 9 ]; - S[ 9 ] = SB; - - SB = S[ 8 ]; - S[ 8 ] = SA; - out32_Q10 = Silk_SigProc_FIX.SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 6 ] ); - out32_Q10 = Silk_SigProc_FIX.SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 7 ] ); - SA = S[ 7 ]; - S[ 7 ] = SB; - - SB = S[ 6 ]; - S[ 6 ] = SA; - out32_Q10 = Silk_SigProc_FIX.SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 8 ] ); - out32_Q10 = Silk_SigProc_FIX.SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 9 ] ); - - SA = S[ 5 ]; - S[ 5 ] = SB; - - SB = S[ 4 ]; - S[ 4 ] = SA; - out32_Q10 = Silk_SigProc_FIX.SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 10 ] ); - out32_Q10 = Silk_SigProc_FIX.SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 11 ] ); - - SA = S[ 3 ]; - S[ 3 ] = SB; - - SB = S[ 2 ]; - S[ 2 ] = SA; - out32_Q10 = Silk_SigProc_FIX.SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 12 ] ); - out32_Q10 = Silk_SigProc_FIX.SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 13 ] ); - SA = S[ 1 ]; - S[ 1 ] = SB; - - /* unrolled loop: epilog */ - SB = S[ 0 ]; - S[ 0 ] = SA; - out32_Q10 = Silk_SigProc_FIX.SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 14 ] ); - out32_Q10 = Silk_SigProc_FIX.SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 15 ] ); - - - /* unrolled loop: end */ - /* apply gain to excitation signal and add to prediction */ - out32_Q10 = Silk_macros.SKP_ADD_SAT32( out32_Q10, Silk_macros.SKP_SMULWB( Gain_Q26, in[ k ] ) ); - - /* scale to Q0 */ - out32 = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( out32_Q10, 10 ); - - /* saturate output */ - out[ k ] = ( short )Silk_SigProc_FIX.SKP_SAT16( out32 ); - - /* move result into delay line */ - S[ 15 ] = Silk_SigProc_FIX.SKP_LSHIFT_SAT32( out32_Q10, 4 ); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LP_variable_cutoff.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LP_variable_cutoff.java deleted file mode 100644 index 841c1f4b7..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_LP_variable_cutoff.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Elliptic/Cauer filters designed with 0.1 dB passband ripple, - * 80 dB minimum stopband attenuation, and - * [0.95 : 0.15 : 0.35] normalized cut off frequencies. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_LP_variable_cutoff -{ - /** - * Helper function, that interpolates the filter taps. - * @param B_Q28 - * @param A_Q28 - * @param ind - * @param fac_Q16 - */ - static void SKP_Silk_LP_interpolate_filter_taps( - int[] B_Q28, - int[] A_Q28, - final int ind, - final int fac_Q16 - ) - { - int nb, na; - - if( ind < Silk_define.TRANSITION_INT_NUM - 1 ) - { - if( fac_Q16 > 0 ) - { - if( fac_Q16 == Silk_SigProc_FIX.SKP_SAT16( fac_Q16 ) ) - { /* fac_Q16 is in range of a 16-bit int */ - /* Piece-wise linear interpolation of B and A */ - for( nb = 0; nb < Silk_define.TRANSITION_NB; nb++ ) - { - B_Q28[ nb ] = Silk_macros.SKP_SMLAWB( - Silk_tables_other.SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ], - Silk_tables_other.SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] - - Silk_tables_other.SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ], - fac_Q16 ); - } - for( na = 0; na < Silk_define.TRANSITION_NA; na++ ) - { - A_Q28[ na ] = Silk_macros.SKP_SMLAWB( - Silk_tables_other.SKP_Silk_Transition_LP_A_Q28[ ind ][ na ], - Silk_tables_other.SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ] - - Silk_tables_other.SKP_Silk_Transition_LP_A_Q28[ ind ][ na ], - fac_Q16 ); - } - } - else if( fac_Q16 == ( 1 << 15 ) ) - { /* Neither fac_Q16 nor ( ( 1 << 16 ) - fac_Q16 ) is in range of a 16-bit int */ - - /* Piece-wise linear interpolation of B and A */ - for( nb = 0; nb < Silk_define.TRANSITION_NB; nb++ ) - { - B_Q28[ nb ] = Silk_SigProc_FIX.SKP_RSHIFT( - Silk_tables_other.SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ] + - Silk_tables_other.SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ], - 1 ); - } - for( na = 0; na < Silk_define.TRANSITION_NA; na++ ) - { - A_Q28[ na ] = Silk_SigProc_FIX.SKP_RSHIFT( - Silk_tables_other.SKP_Silk_Transition_LP_A_Q28[ ind ][ na ] + - Silk_tables_other.SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ], - 1 ); - } - } - else - { /* ( ( 1 << 16 ) - fac_Q16 ) is in range of a 16-bit int */ - - assert( ( ( 1 << 16 ) - fac_Q16 ) == Silk_SigProc_FIX.SKP_SAT16( ( ( 1 << 16 ) - fac_Q16) ) ); - /* Piece-wise linear interpolation of B and A */ - for( nb = 0; nb < Silk_define.TRANSITION_NB; nb++ ) - { - B_Q28[ nb ] = Silk_macros.SKP_SMLAWB( - Silk_tables_other.SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ], - Silk_tables_other.SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ] - - Silk_tables_other.SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ], - ( 1 << 16 ) - fac_Q16 ); - } - for( na = 0; na < Silk_define.TRANSITION_NA; na++ ) - { - A_Q28[ na ] = Silk_macros.SKP_SMLAWB( - Silk_tables_other.SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ], - Silk_tables_other.SKP_Silk_Transition_LP_A_Q28[ ind ][ na ] - - Silk_tables_other.SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ], - ( 1 << 16 ) - fac_Q16 ); - } - } - } - else - { - for(int i_djinn=0; i_djinntransition_frame_no = 1; - * Deactivate by setting psEncC->transition_frame_no = 0; - * @param psLP LP filter state - * @param out Low-pass filtered output signal - * @param out_offset offset of valid data. - * @param in Input signal - * @param in_offset offset of valid data. - * @param frame_length Frame length - */ - static void SKP_Silk_LP_variable_cutoff( - SKP_Silk_LP_state psLP, /* I/O LP filter state */ - short[] out, /* O Low-pass filtered output signal */ - int out_offset, - short[] in, /* I Input signal */ - int in_offset, - final int frame_length /* I Frame length */ - ) - { - int[] B_Q28 = new int[ Silk_define.TRANSITION_NB ], A_Q28 = new int[ Silk_define.TRANSITION_NA ]; - int fac_Q16 = 0; - int ind = 0; - - assert( psLP.transition_frame_no >= 0 ); - assert( ( ( ( psLP.transition_frame_no <= Silk_define.TRANSITION_FRAMES_DOWN ) && ( psLP.mode == 0 ) ) || - ( ( psLP.transition_frame_no <= Silk_define.TRANSITION_FRAMES_UP ) && ( psLP.mode == 1 ) ) ) ); - - /* Interpolate filter coefficients if needed */ - if( psLP.transition_frame_no > 0 ) - { - if( psLP.mode == 0 ) - { - if( psLP.transition_frame_no < Silk_define.TRANSITION_FRAMES_DOWN ) - { - /* Calculate index and interpolation factor for interpolation */ - if( Silk_define.TRANSITION_INT_STEPS_DOWN == 32 ) - fac_Q16 = psLP.transition_frame_no << ( 16 - 5 ); - else - fac_Q16 = ( psLP.transition_frame_no << 16 ) / Silk_define.TRANSITION_INT_STEPS_DOWN ; - - ind = fac_Q16 >> 16; - fac_Q16 -= ind << 16; - - assert( ind >= 0 ); - assert( ind < Silk_define.TRANSITION_INT_NUM ); - - /* Interpolate filter coefficients */ - SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 ); - - /* Increment transition frame number for next frame */ - psLP.transition_frame_no++; - - } - else if( psLP.transition_frame_no == Silk_define.TRANSITION_FRAMES_DOWN ) - { - /* End of transition phase */ - SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, Silk_define.TRANSITION_INT_NUM - 1, 0 ); - } - } - else if( psLP.mode == 1 ) - { - if( psLP.transition_frame_no < Silk_define.TRANSITION_FRAMES_UP ) - { - /* Calculate index and interpolation factor for interpolation */ - if( Silk_define.TRANSITION_INT_STEPS_UP == 64 ) - fac_Q16 = ( Silk_define.TRANSITION_FRAMES_UP - psLP.transition_frame_no ) << ( 16 - 6 ); - else - fac_Q16 = ( ( Silk_define.TRANSITION_FRAMES_UP - psLP.transition_frame_no ) << 16 ) / Silk_define.TRANSITION_INT_STEPS_UP; - - ind = fac_Q16 >> 16; - fac_Q16 -= ind << 16; - - assert( ind >= 0 ); - assert( ind < Silk_define.TRANSITION_INT_NUM ); - - /* Interpolate filter coefficients */ - SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 ); - - /* Increment transition frame number for next frame */ - psLP.transition_frame_no++; - - } - else if( psLP.transition_frame_no == Silk_define.TRANSITION_FRAMES_UP ) - { - /* End of transition phase */ - SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, 0, 0 ); - } - } - } - - if( psLP.transition_frame_no > 0 ) - { - /* ARMA low-pass filtering */ - assert( Silk_define.TRANSITION_NB == 3 && Silk_define.TRANSITION_NA == 2 ); - Silk_biquad_alt.SKP_Silk_biquad_alt( in,in_offset, B_Q28, A_Q28, psLP.In_LP_State, out,out_offset, frame_length ); - } - else - { - /* Instead of using the filter, copy input directly to output */ - for(int i_djinn=0; i_djinn round_loss ? 0 : round_loss); - - - /* Only scale if first frame in packet 0% */ - if( psEnc.sCmn.nFramesInPayloadBuf == 0 ){ - - frames_per_packet = psEnc.sCmn.PacketSize_ms / Silk_define.FRAME_LENGTH_MS; - - round_loss += ( frames_per_packet - 1 ); -// thrld1 = LTPScaleThresholds[ Math.min( round_loss, NB_THRESHOLDS - 1 ) ]; -// thrld2 = LTPScaleThresholds[ Math.min( round_loss + 1, NB_THRESHOLDS - 1 ) ]; - thrld1 = LTPScaleThresholds[ round_loss < (NB_THRESHOLDS - 1) ? round_loss : (NB_THRESHOLDS - 1)]; - thrld2 = LTPScaleThresholds[ (round_loss + 1) < (NB_THRESHOLDS - 1) ? (round_loss + 1):(NB_THRESHOLDS - 1)]; - - - if( g_limit > thrld1 ) { - /* High Scaling */ - psEncCtrl.sCmn.LTP_scaleIndex = 2; - } else if( g_limit > thrld2 ) { - /* Middle Scaling */ - psEncCtrl.sCmn.LTP_scaleIndex = 1; - } - } - psEncCtrl.LTP_scale = Silk_tables_other.SKP_Silk_LTPScales_table_Q14[ psEncCtrl.sCmn.LTP_scaleIndex ] / 16384.0f; - - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_MA.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_MA.java deleted file mode 100644 index 35a5035d8..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_MA.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Variable order MA filter. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_MA -{ - /** - * Variable order MA filter. - * @param in input signal. - * @param in_offset offset of valid data. - * @param B MA coefficients, Q13 [order+1]. - * @param S state vector [order]. - * @param out output signal. - * @param out_offset offset of valid data. - * @param len signal length. - * @param order filter order. - */ - static void SKP_Silk_MA( - short[] in, /* I: input signal */ - int in_offset, - short[] B, /* I: MA coefficients, Q13 [order+1] */ - int[] S, /* I/O: state vector [order] */ - short[] out, /* O: output signal */ - int out_offset, - final int len, /* I: signal length */ - final int order /* I: filter order */ - ) - { - int k, d, in16; - int out32; - - for( k = 0; k < len; k++ ) { - in16 = in[ in_offset + k ]; - out32 = Silk_macros.SKP_SMLABB(S[0], in16, B[ 0 ]); - out32 = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( out32, 13 ); - - for( d = 1; d < order; d++ ) { - S[ d - 1 ] = Silk_macros.SKP_SMLABB( S[ d ], in16, B[ d ] ); - } - S[ order - 1 ] = Silk_macros.SKP_SMULBB( in16, B[ order ] ); - - /* Limit */ - out[ out_offset + k ] = (short)Silk_SigProc_FIX.SKP_SAT16( out32 ); - } - } - - /** - * Variable order MA prediction error filter. - * @param in Input signal. - * @param in_offset offset of valid data. - * @param B MA prediction coefficients, Q12 [order]. - * @param B_offset - * @param S State vector [order]. - * @param out Output signal. - * @param out_offset offset of valid data. - * @param len Signal length. - * @param order Filter order. - */ - static void SKP_Silk_MA_Prediction( - short[] in, /* I: Input signal */ - int in_offset, - short[] B, /* I: MA prediction coefficients, Q12 [order] */ - int B_offset, - int[] S, /* I/O: State vector [order] */ - short[] out, /* O: Output signal */ - int out_offset, - final int len, /* I: Signal length */ - final int order /* I: Filter order */ - ) - { - int k, d, in16; - int out32; - - for( k = 0; k < len; k++ ) { - in16 = in[ in_offset + k ]; - out32 = ( in16 << 12 ) - S[ 0 ]; - out32 = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( out32, 12 ); - - for( d = 0; d < order - 1; d++ ) { - S[ d ] = Silk_SigProc_FIX.SKP_SMLABB_ovflw( S[ d + 1 ], in16, B[ B_offset + d ] ); - } - S[ order - 1 ] = Silk_macros.SKP_SMULBB( in16, B[ B_offset + order - 1 ] ); - - /* Limit */ - out[ out_offset + k ] = (short)Silk_SigProc_FIX.SKP_SAT16( out32 ); - } - } - - /** - * - * @param in input signal. - * @param in_offset offset of valid data. - * @param B MA prediction coefficients, Q13 [order]. - * @param S state vector [order]. - * @param out output signal. - * @param out_offset offset of valid data. - * @param len signal length. - * @param order filter order. - */ - static void SKP_Silk_MA_Prediction_Q13( - short []in, /* I: input signal */ - int in_offset, - short []B, /* I: MA prediction coefficients, Q13 [order] */ - int []S, /* I/O: state vector [order] */ - short []out, /* O: output signal */ - int out_offset, - int len, /* I: signal length */ - int order /* I: filter order */ - ) - { - int k, d, in16; - int out32; - for( k = 0; k < len; k++ ) { - in16 = in[ in_offset + k ]; - out32 = ( in16 << 13 ) - S[ 0 ]; - out32 = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( out32, 13 ); - - for( d = 0; d < order - 1; d++ ) { - S[ d ] = Silk_macros.SKP_SMLABB( S[ d + 1 ], in16, B[ d ] ); - } - S[ order - 1 ] = Silk_macros.SKP_SMULBB( in16, B[ order - 1 ] ); - - /* Limit */ - out[ out_offset + k ] = ( short )Silk_SigProc_FIX.SKP_SAT16( out32 ); - } - } - - /** - * - * @param in Input signal. - * @param in_offset offset of valid data. - * @param B MA prediction coefficients, Q12 [order]. - * @param S State vector [order]. - * @param out Output signal. - * @param out_offset offset of valid data. - * @param len Signal length. - * @param Order Filter order. - */ - static void SKP_Silk_LPC_analysis_filter( - short []in, /* I: Input signal */ - int in_offset, - short []B, /* I: MA prediction coefficients, Q12 [order] */ - short []S, /* I/O: State vector [order] */ - short []out, /* O: Output signal */ - int out_offset, - final int len, /* I: Signal length */ - final int Order /* I: Filter order */ - ) - { - int k, j, idx, Order_half = ( Order >> 1 ); - int out32_Q12, out32; - short SA, SB; - /* Order must be even */ - Silk_typedef.SKP_assert( 2 * Order_half == Order ); - - /* S[] values are in Q0 */ - for( k = 0; k < len; k++ ) { - SA = S[ 0 ]; - out32_Q12 = 0; - for( j = 0; j < ( Order_half - 1 ); j++ ) { - idx = Silk_macros.SKP_SMULBB( 2, j ) + 1; - /* Multiply-add two prediction coefficients for each loop */ - SB = S[ idx ]; - S[ idx ] = SA; - out32_Q12 = Silk_macros.SKP_SMLABB( out32_Q12, SA, B[ idx - 1 ] ); - out32_Q12 = Silk_macros.SKP_SMLABB( out32_Q12, SB, B[ idx ] ); - SA = S[ idx + 1 ]; - S[ idx + 1 ] = SB; - } - - /* Unrolled loop: epilog */ - SB = S[ Order - 1 ]; - S[ Order - 1 ] = SA; - out32_Q12 = Silk_macros.SKP_SMLABB( out32_Q12, SA, B[ Order - 2 ] ); - out32_Q12 = Silk_macros.SKP_SMLABB( out32_Q12, SB, B[ Order - 1 ] ); - - /* Subtract prediction */ - out32_Q12 = Silk_macros.SKP_SUB_SAT32( ( in[ in_offset + k ] << 12 ), out32_Q12 ); - - /* Scale to Q0 */ - out32 = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( out32_Q12, 12 ); - - /* Saturate output */ - out[ out_offset + k ] = ( short )Silk_SigProc_FIX.SKP_SAT16( out32 ); - - /* Move input line */ - S[ 0 ] = in[ in_offset + k ]; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF2A.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF2A.java deleted file mode 100644 index 6ebf020d6..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF2A.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * conversion between prediction filter coefficients and LSFs - * order should be even - * a piecewise linear approximation maps LSF <-> cos(LSF) - * therefore the result is not accurate LSFs, but the two - * function are accurate inverses of each other. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_NLSF2A -{ - /** - * helper function for NLSF2A(..). - * @param out intermediate polynomial, Q20. - * @param cLSF vector of interleaved 2*cos(LSFs), Q20. - * @param cLSF_offset offset of valid data. - * @param dd polynomial order (= 1/2 * filter order). - */ - static void SKP_Silk_NLSF2A_find_poly( - int []out, /* o intermediate polynomial, Q20 */ - int []cLSF, /* i vector of interleaved 2*cos(LSFs), Q20 */ - int cLSF_offset, - int dd /* i polynomial order (= 1/2 * filter order) */ - ) - { - int k, n; - int ftmp; - - out[0] = ( 1 << 20 ); - out[1] = -cLSF[ cLSF_offset + 0]; - for( k = 1; k < dd; k++ ) { - ftmp = cLSF[cLSF_offset + 2*k]; // Q20 - int test = ftmp * out[k]; - long test2 = Silk_SigProc_FIX.SKP_SMULL(ftmp, out[k]); - - out[k+1] = ( out[k-1] << 1 ) - (int)Silk_SigProc_FIX.SKP_RSHIFT_ROUND64( Silk_SigProc_FIX.SKP_SMULL( ftmp , out[k] ), 20 ); - - for( n = k; n > 1; n-- ) { - out[n] += out[n-2] - (int)Silk_SigProc_FIX.SKP_RSHIFT_ROUND64( Silk_SigProc_FIX.SKP_SMULL( ftmp , out[n-1] ), 20 ); - } - out[1] -= ftmp; - } - } - - /** - * compute whitening filter coefficients from normalized line spectral frequencies. - * @param a monic whitening filter coefficients in Q12, [d]. - * @param NLSF normalized line spectral frequencies in Q15, [d]. - * @param d filter order (should be even). - */ - static void SKP_Silk_NLSF2A( - short []a, /* o monic whitening filter coefficients in Q12, [d] */ - int []NLSF, /* i normalized line spectral frequencies in Q15, [d] */ - final int d /* i filter order (should be even) */ - ) - { - int k, i, dd; - int[] cos_LSF_Q20=new int[Silk_SigProc_FIX.SKP_Silk_MAX_ORDER_LPC]; - - int[] P = new int[Silk_SigProc_FIX.SKP_Silk_MAX_ORDER_LPC/2+1]; - int[] Q = new int[Silk_SigProc_FIX.SKP_Silk_MAX_ORDER_LPC/2+1]; - - int Ptmp, Qtmp; - int f_int; - int f_frac; - int cos_val, delta; - int[] a_int32 = new int[Silk_SigProc_FIX.SKP_Silk_MAX_ORDER_LPC]; - - int maxabs, absval, idx=0, sc_Q16; - - Silk_typedef.SKP_assert(Silk_SigProc_FIX.LSF_COS_TAB_SZ_FIX == 128); - - /* convert LSFs to 2*cos(LSF(i)), using piecewise linear curve from table */ - for( k = 0; k < d; k++ ) { - Silk_typedef.SKP_assert(NLSF[k] >= 0 ); - Silk_typedef.SKP_assert(NLSF[k] <= 32767 ); - - /* f_int on a scale 0-127 (rounded down) */ - f_int = ( NLSF[k] >> (15 - 7) ); - - /* f_frac, range: 0..255 */ - f_frac = NLSF[k] - ( f_int << (15 - 7) ); - - - Silk_typedef.SKP_assert(f_int >= 0); - Silk_typedef.SKP_assert(f_int < Silk_SigProc_FIX.LSF_COS_TAB_SZ_FIX ); - - /* Read start and end value from table */ - cos_val = Silk_LSF_cos_table.SKP_Silk_LSFCosTab_FIX_Q12[ f_int ]; /* Q12 */ - delta = Silk_LSF_cos_table.SKP_Silk_LSFCosTab_FIX_Q12[ f_int + 1 ] - cos_val; /* Q12, with a range of 0..200 */ - - /* Linear interpolation */ - cos_LSF_Q20[k] = ( cos_val << 8 ) + ( delta * f_frac ); /* Q20 */ - - } - - dd = ( d >> 1 ); - - /* generate even and odd polynomials using convolution */ - SKP_Silk_NLSF2A_find_poly( P, cos_LSF_Q20, 0, dd ); - SKP_Silk_NLSF2A_find_poly( Q, cos_LSF_Q20, 1, dd ); - - - /* convert even and odd polynomials to int Q12 filter coefs */ - for( k = 0; k < dd; k++ ) { - Ptmp = P[k+1] + P[k]; - Qtmp = Q[k+1] - Q[k]; - - /* the Ptmp and Qtmp values at this stage need to fit in int32 */ - - a_int32[k] = -Silk_SigProc_FIX.SKP_RSHIFT_ROUND( Ptmp + Qtmp, 9 ); /* Q20 -> Q12 */ - a_int32[d-k-1] = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( Qtmp - Ptmp, 9 ); /* Q20 -> Q12 */ - } - - /* Limit the maximum absolute value of the prediction coefficients */ - for( i = 0; i < 10; i++ ) { - /* Find maximum absolute value and its index */ - maxabs = 0; - for( k = 0; k < d; k++ ) { - absval = Silk_SigProc_FIX.SKP_abs( a_int32[k] ); - if( absval > maxabs ) { - maxabs = absval; - idx = k; - } - } - - if( maxabs > Silk_typedef.SKP_int16_MAX ) { - /* Reduce magnitude of prediction coefficients */ - maxabs = Silk_SigProc_FIX.SKP_min( maxabs, 98369 ); // ( SKP_int32_MAX / ( 65470 >> 2 ) ) + SKP_int16_MAX = 98369 - sc_Q16 = 65470 - ( ( (65470 >> 2) * (maxabs - Silk_typedef.SKP_int16_MAX) ) / - ( ( maxabs * (idx + 1)) >> 2 ) ); - Silk_bwexpander_32.SKP_Silk_bwexpander_32( a_int32, d, sc_Q16 ); - - } else { - break; - } - } - - /* Reached the last iteration */ - if( i == 10 ) { - Silk_typedef.SKP_assert(false); - for( k = 0; k < d; k++ ) { - a_int32[k] = Silk_SigProc_FIX.SKP_SAT16( a_int32[k] ); - } - } - - /* Return as SKP_int16 Q12 coefficients */ - for( k = 0; k < d; k++ ) { - a[k] = (short)a_int32[k]; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF2A_stable.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF2A_stable.java deleted file mode 100644 index c0a31ed7b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF2A_stable.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Convert NLSF parameters to stable AR prediction filter coefficients. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_NLSF2A_stable -{ - /** - * Convert NLSF parameters to stable AR prediction filter coefficients. - * @param pAR_Q12 Stabilized AR coefs [LPC_order]. - * @param pNLSF NLSF vector [LPC_order]. - * @param LPC_order LPC/LSF order. - */ - static void SKP_Silk_NLSF2A_stable( - short pAR_Q12[], /* O Stabilized AR coefs [LPC_order] */ - int pNLSF[], /* I NLSF vector [LPC_order] */ - final int LPC_order /* I LPC/LSF order */ - ) - { - int i; - int invGain_Q30; - int invGain_Q30_ptr[] = new int[1]; - Silk_NLSF2A.SKP_Silk_NLSF2A( pAR_Q12, pNLSF, LPC_order ); - - - /* Ensure stable LPCs */ - for( i = 0; i < Silk_define.MAX_LPC_STABILIZE_ITERATIONS; i++ ) { - if( Silk_LPC_inv_pred_gain.SKP_Silk_LPC_inverse_pred_gain( invGain_Q30_ptr, pAR_Q12, LPC_order ) == 1 ) { - invGain_Q30 = invGain_Q30_ptr[0]; - Silk_bwexpander.SKP_Silk_bwexpander( pAR_Q12, LPC_order, 65536 - Silk_macros.SKP_SMULBB( 66, i ) ); /* 66_Q16 = 0.001 */ - } else { - invGain_Q30 = invGain_Q30_ptr[0]; - break; - } - } - - /* Reached the last iteration */ - if( i == Silk_define.MAX_LPC_STABILIZE_ITERATIONS ) { - for( i = 0; i < LPC_order; i++ ) { - pAR_Q12[ i ] = 0; - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_MSVQ_decode.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_MSVQ_decode.java deleted file mode 100644 index 89ede58f2..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_MSVQ_decode.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * NLSF vector decoder. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_NLSF_MSVQ_decode -{ - /** - * NLSF vector decoder. - * @param pNLSF_Q15 decoded output vector [LPC_ORDER x 1]. - * @param psNLSF_CB NLSF codebook struct. - * @param NLSFIndices NLSF indices [nStages x 1]. - * @param LPC_order LPC order used. - */ - static void SKP_Silk_NLSF_MSVQ_decode( - int []pNLSF_Q15, /* O Pointer to decoded output vector [LPC_ORDER x 1] */ - SKP_Silk_NLSF_CB_struct psNLSF_CB, /* I Pointer to NLSF codebook struct */ - int []NLSFIndices, /* I Pointer to NLSF indices [nStages x 1] */ - final int LPC_order /* I LPC order used */ - ) - { - short[] pCB_element; - int pCB_element_offset; - int s; - int i; - - /* Check that each index is within valid range */ - Silk_typedef.SKP_assert( 0 <= NLSFIndices[ 0 ] && NLSFIndices[ 0 ] < psNLSF_CB.CBStages[ 0 ].nVectors ); - - /* Point to the first vector element */ - pCB_element = psNLSF_CB.CBStages[ 0 ].CB_NLSF_Q15; - pCB_element_offset = ( NLSFIndices[ 0 ] * LPC_order ); - - /* Initialize with the codebook vector from stage 0 */ - for( i = 0; i < LPC_order; i++ ) { - pNLSF_Q15[ i ] = pCB_element[ pCB_element_offset + i ]; - } - - for( s = 1; s < psNLSF_CB.nStages; s++ ) { - /* Check that each index is within valid range */ - Silk_typedef.SKP_assert( 0 <= NLSFIndices[ s ] && NLSFIndices[ s ] < psNLSF_CB.CBStages[ s ].nVectors ); - - if( LPC_order == 16 ) { - /* Point to the first vector element */ - pCB_element = psNLSF_CB.CBStages[ s ].CB_NLSF_Q15; - pCB_element_offset = ( NLSFIndices[ s ] << 4 ); - - /* Add the codebook vector from the current stage */ - pNLSF_Q15[ 0 ] += pCB_element[ pCB_element_offset + 0 ]; - pNLSF_Q15[ 1 ] += pCB_element[ pCB_element_offset + 1 ]; - pNLSF_Q15[ 2 ] += pCB_element[ pCB_element_offset + 2 ]; - pNLSF_Q15[ 3 ] += pCB_element[ pCB_element_offset + 3 ]; - pNLSF_Q15[ 4 ] += pCB_element[ pCB_element_offset + 4 ]; - pNLSF_Q15[ 5 ] += pCB_element[ pCB_element_offset + 5 ]; - pNLSF_Q15[ 6 ] += pCB_element[ pCB_element_offset + 6 ]; - pNLSF_Q15[ 7 ] += pCB_element[ pCB_element_offset + 7 ]; - pNLSF_Q15[ 8 ] += pCB_element[ pCB_element_offset + 8 ]; - pNLSF_Q15[ 9 ] += pCB_element[ pCB_element_offset + 9 ]; - pNLSF_Q15[ 10 ] += pCB_element[ pCB_element_offset + 10 ]; - pNLSF_Q15[ 11 ] += pCB_element[ pCB_element_offset + 11 ]; - pNLSF_Q15[ 12 ] += pCB_element[ pCB_element_offset + 12 ]; - pNLSF_Q15[ 13 ] += pCB_element[ pCB_element_offset + 13 ]; - pNLSF_Q15[ 14 ] += pCB_element[ pCB_element_offset + 14 ]; - pNLSF_Q15[ 15 ] += pCB_element[ pCB_element_offset + 15 ]; - } else { - /* Point to the first vector element */ - pCB_element = psNLSF_CB.CBStages[ s ].CB_NLSF_Q15; - pCB_element_offset = Silk_macros.SKP_SMULBB( NLSFIndices[ s ], LPC_order ); - - /* Add the codebook vector from the current stage */ - for( i = 0; i < LPC_order; i++ ) { - pNLSF_Q15[ i ] += pCB_element[ pCB_element_offset + i ]; - } - } - } - - /* NLSF stabilization */ - Silk_NLSF_stabilize.SKP_Silk_NLSF_stabilize( pNLSF_Q15, 0, psNLSF_CB.NDeltaMin_Q15, LPC_order ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_MSVQ_decode_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_MSVQ_decode_FLP.java deleted file mode 100644 index afa1c990d..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_MSVQ_decode_FLP.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * NLSF vector decoder. - * - * @author Dingxin Xu - */ -public class Silk_NLSF_MSVQ_decode_FLP -{ - /** - * NLSF vector decoder. - * @param pNLSF - * @param psNLSF_CB_FLP - * @param NLSFIndices - * @param NLSFIndices_offset - * @param LPC_order - */ - static void SKP_Silk_NLSF_MSVQ_decode_FLP( - float []pNLSF, /* O Decoded output vector [ LPC_ORDER ] */ - final SKP_Silk_NLSF_CB_FLP psNLSF_CB_FLP, /* I NLSF codebook struct */ - final int []NLSFIndices, /* I NLSF indices [ nStages ] */ - int NLSFIndices_offset, - final int LPC_order /* I LPC order used */ - ) - { - float[] pCB_element; - int pCB_element_offset; - int s; - int i; - - - /* Check that each index is within valid range */ - assert( 0 <= NLSFIndices[ NLSFIndices_offset+0 ] && NLSFIndices[ NLSFIndices_offset+0 ] < psNLSF_CB_FLP.CBStages[ 0 ].nVectors ); - - /* Point to the first vector element */ - pCB_element = psNLSF_CB_FLP.CBStages[ 0 ].CB; - pCB_element_offset = ( NLSFIndices[ NLSFIndices_offset+0 ] * LPC_order ); - - /* Initialize with the codebook vector from stage 0 */ - System.arraycopy(pCB_element, pCB_element_offset, pNLSF, 0, LPC_order); - - for( s = 1; s < psNLSF_CB_FLP.nStages; s++ ) { - /* Check that each index is within valid range */ - assert( 0 <= NLSFIndices[ NLSFIndices_offset+s ] && NLSFIndices[ NLSFIndices_offset+s ] < psNLSF_CB_FLP.CBStages[ s ].nVectors ); - - if( LPC_order == 16 ) { - /* Point to the first vector element */ - pCB_element = psNLSF_CB_FLP.CBStages[ s ].CB; - pCB_element_offset = ( NLSFIndices[ NLSFIndices_offset+s ] << 4 ); - - /* Add the codebook vector from the current stage */ - pNLSF[ 0 ] += pCB_element[ pCB_element_offset+0 ]; - pNLSF[ 1 ] += pCB_element[ pCB_element_offset+1 ]; - pNLSF[ 2 ] += pCB_element[ pCB_element_offset+2 ]; - pNLSF[ 3 ] += pCB_element[ pCB_element_offset+3 ]; - pNLSF[ 4 ] += pCB_element[ pCB_element_offset+4 ]; - pNLSF[ 5 ] += pCB_element[ pCB_element_offset+5 ]; - pNLSF[ 6 ] += pCB_element[ pCB_element_offset+6 ]; - pNLSF[ 7 ] += pCB_element[ pCB_element_offset+7 ]; - pNLSF[ 8 ] += pCB_element[ pCB_element_offset+8 ]; - pNLSF[ 9 ] += pCB_element[ pCB_element_offset+9 ]; - pNLSF[ 10 ] += pCB_element[ pCB_element_offset+10 ]; - pNLSF[ 11 ] += pCB_element[ pCB_element_offset+11 ]; - pNLSF[ 12 ] += pCB_element[ pCB_element_offset+12 ]; - pNLSF[ 13 ] += pCB_element[ pCB_element_offset+13 ]; - pNLSF[ 14 ] += pCB_element[ pCB_element_offset+14 ]; - pNLSF[ 15 ] += pCB_element[ pCB_element_offset+15 ]; - } else { - /* Point to the first vector element */ - pCB_element = psNLSF_CB_FLP.CBStages[ s ].CB; - pCB_element_offset = NLSFIndices[ NLSFIndices_offset+s ] * LPC_order; - - /* Add the codebook vector from the current stage */ - for( i = 0; i < LPC_order; i++ ) { - pNLSF[ i ] += pCB_element[ pCB_element_offset+i ]; - } - } - } - - /* NLSF stabilization */ - Silk_wrappers_FLP.SKP_Silk_NLSF_stabilize_FLP( pNLSF, psNLSF_CB_FLP.NDeltaMin, LPC_order ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_MSVQ_encode_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_MSVQ_encode_FLP.java deleted file mode 100644 index 659aed30d..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_MSVQ_encode_FLP.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -import java.util.*; - -/** - * NLSF vector encoder. - * - * @author Dingxin Xu - */ -public class Silk_NLSF_MSVQ_encode_FLP -{ - /** - * NLSF vector encoder. - * @param NLSFIndices Codebook path vector [ CB_STAGES ] - * @param pNLSF Quantized NLSF vector [ LPC_ORDER ] - * @param psNLSF_CB_FLP Codebook object - * @param pNLSF_q_prev Prev. quantized NLSF vector [LPC_ORDER] - * @param pW NLSF weight vector [ LPC_ORDER ] - * @param NLSF_mu Rate weight for the RD optimization - * @param NLSF_mu_fluc_red Fluctuation reduction error weight - * @param NLSF_MSVQ_Survivors Max survivors from each stage - * @param LPC_order LPC order - * @param deactivate_fluc_red Deactivate fluctuation reduction - */ - static void SKP_Silk_NLSF_MSVQ_encode_FLP( - int []NLSFIndices, /* O Codebook path vector [ CB_STAGES ] */ - float []pNLSF, /* I/O Quantized NLSF vector [ LPC_ORDER ] */ - final SKP_Silk_NLSF_CB_FLP psNLSF_CB_FLP, /* I Codebook object */ - final float []pNLSF_q_prev, /* I Prev. quantized NLSF vector [LPC_ORDER] */ - final float []pW, /* I NLSF weight vector [ LPC_ORDER ] */ - final float NLSF_mu, /* I Rate weight for the RD optimization */ - final float NLSF_mu_fluc_red, /* I Fluctuation reduction error weight */ - final int NLSF_MSVQ_Survivors,/* I Max survivors from each stage */ - final int LPC_order, /* I LPC order */ - final int deactivate_fluc_red /* I Deactivate fluctuation reduction */ - ) - { - int i, s, k, cur_survivors, prev_survivors, input_index, cb_index, bestIndex; - float se, wsse, rateDistThreshold, bestRateDist; - float pNLSF_in[] = new float[ Silk_define.MAX_LPC_ORDER ]; - - float pRateDist[]; - float pRate[]; - float pRate_new[]; - int pTempIndices[]; - int pPath[]; - int pPath_new[]; - float pRes[]; - float pRes_new[]; - if(Silk_define.LOW_COMPLEXITY_ONLY == 1) - { - pRateDist = new float[Silk_define.NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED_LC_MODE()]; - pRate = new float[Silk_define.MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ]; - pRate_new = new float[Silk_define.MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ]; - pTempIndices = new int[Silk_define.MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ]; - pPath = new int[Silk_define.MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * Silk_define.NLSF_MSVQ_MAX_CB_STAGES]; - pPath_new = new int[Silk_define.MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * Silk_define.NLSF_MSVQ_MAX_CB_STAGES]; - pRes = new float[Silk_define.MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * Silk_define.MAX_LPC_ORDER ]; - pRes_new = new float[Silk_define.MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * Silk_define.MAX_LPC_ORDER ]; - }else - { - pRateDist = new float[Silk_define.NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED() ]; - pRate = new float[Silk_define.MAX_NLSF_MSVQ_SURVIVORS ]; - pRate_new = new float[Silk_define.MAX_NLSF_MSVQ_SURVIVORS ]; - pTempIndices = new int[Silk_define.MAX_NLSF_MSVQ_SURVIVORS ]; - pPath = new int[Silk_define.MAX_NLSF_MSVQ_SURVIVORS * Silk_define.NLSF_MSVQ_MAX_CB_STAGES ]; - pPath_new = new int[Silk_define.MAX_NLSF_MSVQ_SURVIVORS * Silk_define.NLSF_MSVQ_MAX_CB_STAGES ]; - pRes = new float[Silk_define.MAX_NLSF_MSVQ_SURVIVORS * Silk_define.MAX_LPC_ORDER ]; - pRes_new = new float[Silk_define.MAX_NLSF_MSVQ_SURVIVORS * Silk_define.MAX_LPC_ORDER ]; - } - - float[] pConstFloat;int pConstFloat_offset; - float[] pFloat; int pFloat_offset; - int[] pConstInt; int pConstInt_offset; - int[] pInt; int pInt_offset; - float[] pCB_element;int pCB_element_offset; - SKP_Silk_NLSF_CBS_FLP pCurrentCBStage; - - assert( NLSF_MSVQ_Survivors <= Silk_define.MAX_NLSF_MSVQ_SURVIVORS ); - assert( ( Silk_define.LOW_COMPLEXITY_ONLY == 0 ) || ( NLSF_MSVQ_Survivors <= Silk_define.MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ) ); - - cur_survivors = NLSF_MSVQ_Survivors; - - - - /* Copy the input vector */ - System.arraycopy(pNLSF, 0, pNLSF_in, 0, LPC_order); - - /****************************************************/ - /* Tree search for the multi-stage vector quantizer */ - /****************************************************/ - - /* Clear accumulated rates */ - Arrays.fill(pRate, 0, NLSF_MSVQ_Survivors, 0); - - /* Copy NLSFs into residual signal vector */ - System.arraycopy(pNLSF, 0, pRes, 0, LPC_order); - - /* Set first stage values */ - prev_survivors = 1; - - /* Loop over all stages */ - for( s = 0; s < psNLSF_CB_FLP.nStages; s++ ) { - - /* Set a pointer to the current stage codebook */ - pCurrentCBStage = psNLSF_CB_FLP.CBStages[ s ]; - - /* Calculate the number of survivors in the current stage */ - cur_survivors = Math.min( NLSF_MSVQ_Survivors, prev_survivors * pCurrentCBStage.nVectors ); - - if(Silk_define.NLSF_MSVQ_FLUCTUATION_REDUCTION == 0 ) { - /* Find a single best survivor in the last stage, if we */ - /* do not need candidates for fluctuation reduction */ - if( s == psNLSF_CB_FLP.nStages - 1 ) { - cur_survivors = 1; - } - } - /* Nearest neighbor clustering for multiple input data vectors */ - Silk_NLSF_VQ_rate_distortion_FLP.SKP_Silk_NLSF_VQ_rate_distortion_FLP( pRateDist, pCurrentCBStage, - pRes, pW, pRate, NLSF_mu, prev_survivors, LPC_order ); - - /* Sort the rate-distortion errors */ - Silk_sort_FLP.SKP_Silk_insertion_sort_increasing_FLP( pRateDist, 0, pTempIndices, prev_survivors * pCurrentCBStage.nVectors, cur_survivors ); - - /* Discard survivors with rate-distortion values too far above the best one */ - rateDistThreshold = Silk_define.NLSF_MSVQ_SURV_MAX_REL_RD * pRateDist[ 0 ]; - while( pRateDist[ cur_survivors - 1 ] > rateDistThreshold && cur_survivors > 1 ) { - cur_survivors--; - } - - /* Update accumulated codebook contributions for the 'cur_survivors' best codebook indices */ - for( k = 0; k < cur_survivors; k++ ) { - if( s > 0 ) { - /* Find the indices of the input and the codebook vector */ - if( pCurrentCBStage.nVectors == 8 ) { - input_index = ( pTempIndices[ k ] >> 3 ); - cb_index = pTempIndices[ k ] & 7; - } else { - input_index = pTempIndices[ k ] / pCurrentCBStage.nVectors; - cb_index = pTempIndices[ k ] - input_index * pCurrentCBStage.nVectors; - } - } else { - /* Find the indices of the input and the codebook vector */ - input_index = 0; - cb_index = pTempIndices[ k ]; - } - - /* Subtract new contribution from the previous residual vector for each of 'cur_survivors' */ - pConstFloat = pRes; - pConstFloat_offset = input_index * LPC_order; - pCB_element = pCurrentCBStage.CB; - pCB_element_offset = cb_index * LPC_order; - pFloat = pRes_new; - pFloat_offset = k * LPC_order; - for( i = 0; i < LPC_order; i++ ) { - pFloat[ pFloat_offset + i ] = pConstFloat[ pConstFloat_offset + i ] - pCB_element[ pCB_element_offset + i ]; - } - - /* Update accumulated rate for stage 1 to the current */ - pRate_new[ k ] = pRate[ input_index ] + pCurrentCBStage.Rates[ cb_index ]; - - /* Copy paths from previous matrix, starting with the best path */ - pConstInt = pPath; - pConstInt_offset = input_index * psNLSF_CB_FLP.nStages; - pInt = pPath_new; - pInt_offset = k * psNLSF_CB_FLP.nStages; - for( i = 0; i < s; i++ ) { - pInt[ pInt_offset + i ] = pConstInt[ pConstInt_offset + i ]; - } - /* Write the current stage indices for the 'cur_survivors' to the best path matrix */ - pInt[ pInt_offset + s ] = cb_index; - } - - if( s < psNLSF_CB_FLP.nStages - 1 ) { - /* Copy NLSF residual matrix for next stage */ - System.arraycopy(pRes_new, 0, pRes, 0, cur_survivors * LPC_order); - - /* Copy rate vector for next stage */ - System.arraycopy(pRate_new, 0, pRate, 0, cur_survivors); - - /* Copy best path matrix for next stage */ - System.arraycopy(pPath_new, 0, pPath, 0, cur_survivors * psNLSF_CB_FLP.nStages); - } - - prev_survivors = cur_survivors; - } - - /* (Preliminary) index of the best survivor, later to be decoded */ - bestIndex = 0; - - if (Silk_define.NLSF_MSVQ_FLUCTUATION_REDUCTION == 1) - { - /******************************/ - /* NLSF fluctuation reduction */ - /******************************/ - if( deactivate_fluc_red != 1 ) { - - /* Search among all survivors, now taking also weighted fluctuation errors into account */ - bestRateDist = Float.MAX_VALUE; - for( s = 0; s < cur_survivors; s++ ) { - /* Decode survivor to compare with previous quantized NLSF vector */ - Silk_NLSF_MSVQ_decode_FLP.SKP_Silk_NLSF_MSVQ_decode_FLP( pNLSF, psNLSF_CB_FLP, - pPath_new, s * psNLSF_CB_FLP.nStages, LPC_order ); - - /* Compare decoded NLSF vector with the previously quantized vector */ - wsse = 0; - for( i = 0; i < LPC_order; i += 2 ) { - /* Compute weighted squared quantization error for index i */ - se = pNLSF[ i ] - pNLSF_q_prev[ i ]; - wsse += pW[ i ] * se * se; - - /* Compute weighted squared quantization error for index i + 1 */ - se = pNLSF[ i + 1 ] - pNLSF_q_prev[ i + 1 ]; - wsse += pW[ i + 1 ] * se * se; - } - - /* Add the fluctuation reduction penalty to the rate distortion error */ - wsse = pRateDist[s] + wsse * NLSF_mu_fluc_red; - - /* Keep index of best survivor */ - if( wsse < bestRateDist ) { - bestRateDist = wsse; - bestIndex = s; - } - } - } - } - - /* Copy best path to output argument */ - System.arraycopy(pPath_new, bestIndex * psNLSF_CB_FLP.nStages, NLSFIndices, 0, psNLSF_CB_FLP.nStages); - - /* Decode and stabilize the best survivor */ - Silk_NLSF_MSVQ_decode_FLP.SKP_Silk_NLSF_MSVQ_decode_FLP( pNLSF, psNLSF_CB_FLP, NLSFIndices, 0, LPC_order ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_VQ_rate_distortion_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_VQ_rate_distortion_FLP.java deleted file mode 100644 index 49ba95df1..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_VQ_rate_distortion_FLP.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Rate-Distortion calculations for multiple input data vectors - * - * @author Dingxin Xu - */ -public class Silk_NLSF_VQ_rate_distortion_FLP -{ - /** - * Rate-Distortion calculations for multiple input data vectors. - * @param pRD Rate-distortion values [psNLSF_CBS_FLP->nVectors*N] - * @param psNLSF_CBS_FLP NLSF codebook stage struct - * @param in Input vectors to be quantized - * @param w Weight vector - * @param rate_acc Accumulated rates from previous stage - * @param mu Weight between weighted error and rate - * @param N Number of input vectors to be quantized - * @param LPC_order LPC order - */ - static void SKP_Silk_NLSF_VQ_rate_distortion_FLP( - float []pRD, /* O Rate-distortion values [psNLSF_CBS_FLP->nVectors*N] */ - final SKP_Silk_NLSF_CBS_FLP psNLSF_CBS_FLP, /* I NLSF codebook stage struct */ - final float []in, /* I Input vectors to be quantized */ - final float []w, /* I Weight vector */ - final float []rate_acc, /* I Accumulated rates from previous stage */ - final float mu, /* I Weight between weighted error and rate */ - final int N, /* I Number of input vectors to be quantized */ - final int LPC_order /* I LPC order */ - ) - { - float[] pRD_vec; - int pRD_vec_offset; - int i, n; - - /* Compute weighted quantization errors for all input vectors over one codebook stage */ - Silk_NLSF_VQ_sum_error_FLP.SKP_Silk_NLSF_VQ_sum_error_FLP( pRD, in, w, psNLSF_CBS_FLP.CB, - N, psNLSF_CBS_FLP.nVectors, LPC_order ); - - /* Loop over input vectors */ - pRD_vec = pRD; - pRD_vec_offset = 0; - for( n = 0; n < N; n++ ) { - /* Add rate cost to error for each codebook vector */ - for( i = 0; i < psNLSF_CBS_FLP.nVectors; i++ ) { - pRD_vec[ pRD_vec_offset + i ] += mu * ( rate_acc[n] + psNLSF_CBS_FLP.Rates[ i ] ); - } - pRD_vec_offset += psNLSF_CBS_FLP.nVectors; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_VQ_sum_error_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_VQ_sum_error_FLP.java deleted file mode 100644 index 1ef61a147..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_VQ_sum_error_FLP.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * compute weighted quantization errors for LPC_order element input vectors, over one codebook stage. - * - * @author Dingxin Xu - */ -public class Silk_NLSF_VQ_sum_error_FLP -{ - /** - * compute weighted quantization errors for LPC_order element input vectors, over one codebook stage. - * @param err Weighted quantization errors [ N * K ] - * @param in Input vectors [ N * LPC_order ] - * @param w Weighting vectors [ N * LPC_order ] - * @param pCB Codebook vectors [ K * LPC_order ] - * @param N Number of input vectors - * @param K Number of codebook vectors - * @param LPC_order pCB - */ - static void SKP_Silk_NLSF_VQ_sum_error_FLP( - float []err, /* O Weighted quantization errors [ N * K ] */ - final float []in, /* I Input vectors [ N * LPC_order ] */ - final float []w, /* I Weighting vectors [ N * LPC_order ] */ - final float []pCB, /* I Codebook vectors [ K * LPC_order ] */ - final int N, /* I Number of input vectors */ - final int K, /* I Number of codebook vectors */ - final int LPC_order /* I LPC order */ - ) - { - int i, n; - float diff, sum_error; - float Wcpy[] = new float[ Silk_define.MAX_LPC_ORDER ]; - float[] cb_vec; - int cb_vec_offset; - - /* Copy to local stack */ - System.arraycopy(w, 0, Wcpy, 0, LPC_order); - -//TODO: - float[] err_tmp = err; - int err_tmp_offset = 0; - float[] in_tmp = in; - int in_tmp_offset = 0; - if( LPC_order == 16 ) { - /* Loop over input vectors */ - for( n = 0; n < N; n++ ) { - /* Loop over codebook */ - cb_vec = pCB; - cb_vec_offset = 0; - for( i = 0; i < K; i++ ) { - /* Compute weighted squared quantization error */ - diff = in_tmp[in_tmp_offset+0 ] - cb_vec[ cb_vec_offset+0 ]; - sum_error = Wcpy[ 0 ] * diff * diff; - diff = in_tmp[in_tmp_offset+1 ] - cb_vec[ cb_vec_offset+1 ]; - sum_error += Wcpy[ 1 ] * diff * diff; - diff = in_tmp[in_tmp_offset+2 ] - cb_vec[ cb_vec_offset+2 ]; - sum_error += Wcpy[ 2 ] * diff * diff; - diff = in_tmp[in_tmp_offset+3 ] - cb_vec[ cb_vec_offset+3 ]; - sum_error += Wcpy[ 3 ] * diff * diff; - diff = in_tmp[in_tmp_offset+4 ] - cb_vec[ cb_vec_offset+4 ]; - sum_error += Wcpy[ 4 ] * diff * diff; - diff = in_tmp[in_tmp_offset+5 ] - cb_vec[ cb_vec_offset+5 ]; - sum_error += Wcpy[ 5 ] * diff * diff; - diff = in_tmp[in_tmp_offset+6 ] - cb_vec[ cb_vec_offset+6 ]; - sum_error += Wcpy[ 6 ] * diff * diff; - diff = in_tmp[in_tmp_offset+7 ] - cb_vec[ cb_vec_offset+7 ]; - sum_error += Wcpy[ 7 ] * diff * diff; - diff = in_tmp[in_tmp_offset+8 ] - cb_vec[ cb_vec_offset+8 ]; - sum_error += Wcpy[ 8 ] * diff * diff; - diff = in_tmp[in_tmp_offset+9 ] - cb_vec[ cb_vec_offset+9 ]; - sum_error += Wcpy[ 9 ] * diff * diff; - diff = in_tmp[in_tmp_offset+10 ] - cb_vec[ cb_vec_offset+10 ]; - sum_error += Wcpy[ 10 ] * diff * diff; - diff = in_tmp[in_tmp_offset+11 ] - cb_vec[ cb_vec_offset+11 ]; - sum_error += Wcpy[ 11 ] * diff * diff; - diff = in_tmp[in_tmp_offset+12 ] - cb_vec[ cb_vec_offset+12 ]; - sum_error += Wcpy[ 12 ] * diff * diff; - diff = in_tmp[in_tmp_offset+13 ] - cb_vec[ cb_vec_offset+13 ]; - sum_error += Wcpy[ 13 ] * diff * diff; - diff = in_tmp[in_tmp_offset+14 ] - cb_vec[ cb_vec_offset+14 ]; - sum_error += Wcpy[ 14 ] * diff * diff; - diff = in_tmp[in_tmp_offset+15 ] - cb_vec[ cb_vec_offset+15 ]; - sum_error += Wcpy[ 15 ] * diff * diff; - - err_tmp[ err_tmp_offset +i ] = sum_error; - cb_vec_offset += 16; - } - err_tmp_offset += K; - in_tmp_offset += 16; - } - } else { - assert( LPC_order == 10 ); - - /* Loop over input vectors */ - for( n = 0; n < N; n++ ) { - /* Loop over codebook */ - cb_vec = pCB; - cb_vec_offset = 0; - for( i = 0; i < K; i++ ) { - /* Compute weighted squared quantization error */ - diff = in_tmp[in_tmp_offset+0 ] - cb_vec[ cb_vec_offset+0 ]; - sum_error = Wcpy[ 0 ] * diff * diff; - diff = in_tmp[in_tmp_offset+1 ] - cb_vec[ cb_vec_offset+1 ]; - sum_error += Wcpy[ 1 ] * diff * diff; - diff = in_tmp[in_tmp_offset+2 ] - cb_vec[ cb_vec_offset+2 ]; - sum_error += Wcpy[ 2 ] * diff * diff; - diff = in_tmp[in_tmp_offset+3 ] - cb_vec[ cb_vec_offset+3 ]; - sum_error += Wcpy[ 3 ] * diff * diff; - diff = in_tmp[in_tmp_offset+4 ] - cb_vec[ cb_vec_offset+4 ]; - sum_error += Wcpy[ 4 ] * diff * diff; - diff = in_tmp[in_tmp_offset+5 ] - cb_vec[ cb_vec_offset+5 ]; - sum_error += Wcpy[ 5 ] * diff * diff; - diff = in_tmp[in_tmp_offset+6 ] - cb_vec[ cb_vec_offset+6 ]; - sum_error += Wcpy[ 6 ] * diff * diff; - diff = in_tmp[in_tmp_offset+7 ] - cb_vec[ cb_vec_offset+7 ]; - sum_error += Wcpy[ 7 ] * diff * diff; - diff = in_tmp[in_tmp_offset+8 ] - cb_vec[ cb_vec_offset+8 ]; - sum_error += Wcpy[ 8 ] * diff * diff; - diff = in_tmp[in_tmp_offset+9 ] - cb_vec[ cb_vec_offset+9 ]; - sum_error += Wcpy[ 9 ] * diff * diff; - - err_tmp[ err_tmp_offset + i ] = sum_error; - cb_vec_offset += 10; - } - err_tmp_offset += K; - in_tmp_offset += 10; - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_VQ_weights_laroia_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_VQ_weights_laroia_FLP.java deleted file mode 100644 index 9c16c502a..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_VQ_weights_laroia_FLP.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * R. Laroia, N. Phamdo and N. Farvardin, "Robust and Efficient Quantization of Speech LSP - * Parameters Using Structured Vector Quantization", Proc. IEEE Int. Conf. Acoust., Speech, - * Signal Processing, pp. 641-644, 1991. - * - * @author Dingxin Xu - */ -public class Silk_NLSF_VQ_weights_laroia_FLP -{ - static float MIN_NDELTA = ( 1e-6f / Silk_SigProc_FLP.PI ); - - /** - * Laroia low complexity NLSF weights. - * @param pXW Pointer to input vector weights [D x 1] - * @param pX Pointer to input vector [D x 1] - * @param D Input vector dimension - */ - static void SKP_Silk_NLSF_VQ_weights_laroia_FLP( - float []pXW, /* 0: Pointer to input vector weights [D x 1] */ - final float []pX, /* I: Pointer to input vector [D x 1] */ - final int D /* I: Input vector dimension */ - ) - { - int k; - float tmp1, tmp2; - - /* Safety checks */ - assert( D > 0 ); - assert( ( D & 1 ) == 0 ); - - /* First value */ - tmp1 = 1.0f / ( pX[ 0 ] > MIN_NDELTA ? pX[0]:MIN_NDELTA); - tmp2 = 1.0f / ((pX[ 1 ] - pX[ 0 ])>MIN_NDELTA ?(pX[ 1 ] - pX[ 0 ]):MIN_NDELTA); - pXW[ 0 ] = tmp1 + tmp2; - - /* Main loop */ - for( k = 1; k < D - 1; k += 2 ) { - tmp1 = 1.0f / ((pX[ k + 1 ] - pX[ k ])>MIN_NDELTA ? (pX[ k + 1 ] - pX[ k ]):MIN_NDELTA); - pXW[ k ] = tmp1 + tmp2; - - tmp2 = 1.0f / ((pX[ k + 2 ] - pX[ k + 1 ]) >MIN_NDELTA ?(pX[ k + 2 ] - pX[ k + 1 ]):MIN_NDELTA); - pXW[ k + 1 ] = tmp1 + tmp2; - } - - /* Last value */ - tmp1 = 1.0f / ( (1.0f - pX[ D - 1 ])> MIN_NDELTA ?(1.0f - pX[ D - 1 ]):MIN_NDELTA); - pXW[ D - 1 ] = tmp1 + tmp2; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_stabilize.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_stabilize.java deleted file mode 100644 index 60b17cd54..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NLSF_stabilize.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * NLSF stabilizer: - * - Moves NLSFs further apart if they are too close - * - Moves NLSFs away from borders if they are too close - * - High effort to achieve a modification with minimum Euclidean distance to input vector - * - Output are sorted NLSF coefficients - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_NLSF_stabilize -{ - /** - * Constant Definitions. - */ - static final int MAX_LOOPS = 20; - - /** - * NLSF stabilizer, for a single input data vector. - * @param NLSF_Q15 Unstable/stabilized normalized LSF vector in Q15 [L]. - * @param NLSF_Q15_offset offset of valid data. - * @param NDeltaMin_Q15 Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1]. - * @param L Number of NLSF parameters in the input vector. - */ - static void SKP_Silk_NLSF_stabilize( - int []NLSF_Q15, /* I/O: Unstable/stabilized normalized LSF vector in Q15 [L] */ - int NLSF_Q15_offset, - int []NDeltaMin_Q15, /* I: Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1] */ - final int L /* I: Number of NLSF parameters in the input vector */ - ) - { - int center_freq_Q15, diff_Q15, min_center_Q15, max_center_Q15; - int min_diff_Q15; - int loops; - int i, I=0, k; - - /* This is necessary to ensure an output within range of a SKP_int16 */ - Silk_typedef.SKP_assert( NDeltaMin_Q15[L] >= 1 ); - - for( loops = 0; loops < MAX_LOOPS; loops++ ) { - /**************************/ - /* Find smallest distance */ - /**************************/ - /* First element */ - min_diff_Q15 = NLSF_Q15[ NLSF_Q15_offset + 0] - NDeltaMin_Q15[0]; - I = 0; - /* Middle elements */ - for( i = 1; i <= L-1; i++ ) { - diff_Q15 = NLSF_Q15[ NLSF_Q15_offset + i] - ( NLSF_Q15[ NLSF_Q15_offset + i-1] + NDeltaMin_Q15[i] ); - if( diff_Q15 < min_diff_Q15 ) { - min_diff_Q15 = diff_Q15; - I = i; - } - } - /* Last element */ - diff_Q15 = (1<<15) - ( NLSF_Q15[ NLSF_Q15_offset + L-1] + NDeltaMin_Q15[L] ); - if( diff_Q15 < min_diff_Q15 ) { - min_diff_Q15 = diff_Q15; - I = L; - } - - /***************************************************/ - /* Now check if the smallest distance non-negative */ - /***************************************************/ - if (min_diff_Q15 >= 0) { - return; - } - - if( I == 0 ) { - /* Move away from lower limit */ - NLSF_Q15[ NLSF_Q15_offset + 0] = NDeltaMin_Q15[0]; - - } else if( I == L) { - /* Move away from higher limit */ - NLSF_Q15[ NLSF_Q15_offset + L-1] = (1<<15) - NDeltaMin_Q15[L]; - - } else { - /* Find the lower extreme for the location of the current center frequency */ - min_center_Q15 = 0; - for( k = 0; k < I; k++ ) { - min_center_Q15 += NDeltaMin_Q15[k]; - } - min_center_Q15 += ( NDeltaMin_Q15[I] >> 1 ); - - - /* Find the upper extreme for the location of the current center frequency */ - max_center_Q15 = (1<<15); - for( k = L; k > I; k-- ) { - max_center_Q15 -= NDeltaMin_Q15[k]; - } - max_center_Q15 -= ( NDeltaMin_Q15[I] - ( NDeltaMin_Q15[I] >> 1 ) ); - - /* Move apart, sorted by value, keeping the same center frequency */ - center_freq_Q15 = Silk_SigProc_FIX.SKP_LIMIT_32( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( NLSF_Q15[ NLSF_Q15_offset + I-1] + NLSF_Q15[ NLSF_Q15_offset + I], 1 ), - min_center_Q15, max_center_Q15 ); - NLSF_Q15[ NLSF_Q15_offset + I-1] = center_freq_Q15 - ( NDeltaMin_Q15[I] >> 1 ); - NLSF_Q15[ NLSF_Q15_offset + I] = NLSF_Q15[ NLSF_Q15_offset + I-1] + NDeltaMin_Q15[I]; - } - } - - /* Safe and simple fall back method, which is less ideal than the above */ - if( loops == MAX_LOOPS ) - { - /* Insertion sort (fast for already almost sorted arrays): */ - /* Best case: O(n) for an already sorted array */ - /* Worst case: O(n^2) for an inversely sorted array */ - Silk_sort.SKP_Silk_insertion_sort_increasing_all_values(NLSF_Q15, NLSF_Q15_offset + 0, L); - - /* First NLSF should be no less than NDeltaMin[0] */ - NLSF_Q15[ NLSF_Q15_offset + 0] = Silk_SigProc_FIX.SKP_max_int( NLSF_Q15[ NLSF_Q15_offset + 0], NDeltaMin_Q15[0] ); - - /* Keep delta_min distance between the NLSFs */ - for( i = 1; i < L; i++ ) - NLSF_Q15[ NLSF_Q15_offset + i] = Silk_SigProc_FIX.SKP_max_int( NLSF_Q15[ NLSF_Q15_offset + i], NLSF_Q15[ NLSF_Q15_offset + i-1] + NDeltaMin_Q15[i] ); - - /* Last NLSF should be no higher than 1 - NDeltaMin[L] */ - NLSF_Q15[ NLSF_Q15_offset + L-1] = Silk_SigProc_FIX.SKP_min_int( NLSF_Q15[ NLSF_Q15_offset + L-1], (1<<15) - NDeltaMin_Q15[L] ); - - /* Keep NDeltaMin distance between the NLSFs */ - for( i = L-2; i >= 0; i-- ) - NLSF_Q15[ NLSF_Q15_offset + i] = Silk_SigProc_FIX.SKP_min_int( NLSF_Q15[ NLSF_Q15_offset + i], NLSF_Q15[ NLSF_Q15_offset + i+1] - NDeltaMin_Q15[i+1] ); - } - } - - /** - * NLSF stabilizer, over multiple input column data vectors. - * @param NLSF_Q15 Unstable/stabilized normalized LSF vectors in Q15 [LxN]. - * @param NDeltaMin_Q15 Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1]. - * @param N Number of input vectors to be stabilized. - * @param L NLSF vector dimension. - */ - static void SKP_Silk_NLSF_stabilize_multi( - int []NLSF_Q15, /* I/O: Unstable/stabilized normalized LSF vectors in Q15 [LxN] */ - int []NDeltaMin_Q15, /* I: Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1] */ - final int N, /* I: Number of input vectors to be stabilized */ - final int L /* I: NLSF vector dimension */ - ) - { - int n; - - /* loop over input data */ - for( n = 0; n < N; n++ ) { - SKP_Silk_NLSF_stabilize( NLSF_Q15, n * L, NDeltaMin_Q15, L ); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NSQ.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NSQ.java deleted file mode 100644 index bfc610370..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NSQ.java +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -import java.util.*; - -/** - * - * @author Dingxin Xu - */ -public class Silk_NSQ -{ - /** - * - * @param psEncC Encoder State - * @param psEncCtrlC Encoder Control - * @param NSQ NSQ state - * @param x prefiltered input signal - * @param q quantized qulse signal - * @param LSFInterpFactor_Q2 LSF interpolation factor in Q2 - * @param PredCoef_Q12 Short term prediction coefficients - * @param LTPCoef_Q14 Long term prediction coefficients - * @param AR2_Q13 - * @param HarmShapeGain_Q14 - * @param Tilt_Q14 Spectral tilt - * @param LF_shp_Q14 - * @param Gains_Q16 - * @param Lambda_Q10 - * @param LTP_scale_Q14 LTP state scaling - */ - static void SKP_Silk_NSQ( - SKP_Silk_encoder_state psEncC, /* I/O Encoder State */ - SKP_Silk_encoder_control psEncCtrlC, /* I Encoder Control */ - SKP_Silk_nsq_state NSQ, /* I/O NSQ state */ - short x[], /* I prefiltered input signal */ - byte q[], /* O quantized qulse signal */ - int LSFInterpFactor_Q2, /* I LSF interpolation factor in Q2 */ - short PredCoef_Q12[], /* I Short term prediction coefficients */ - short LTPCoef_Q14[], /* I Long term prediction coefficients */ - short AR2_Q13[], /* I */ - int HarmShapeGain_Q14[],/* I */ - int Tilt_Q14[], /* I Spectral tilt */ - int LF_shp_Q14[], /* I */ - int Gains_Q16[], /* I */ - int Lambda_Q10, /* I */ - int LTP_scale_Q14 /* I LTP state scaling */ - ) - { - int k, lag, start_idx, subfr_length, LSF_interpolation_flag; - short []A_Q12; - short [] B_Q14; - short [] AR_shp_Q13; - int A_Q12_offset, B_Q14_offset, AR_shp_Q13_offset; - short []pxq; - int pxq_offset; - int sLTP_Q16[] = new int[ 2 * Silk_define.MAX_FRAME_LENGTH ]; - short sLTP[] = new short[ 2 * Silk_define.MAX_FRAME_LENGTH ]; - int HarmShapeFIRPacked_Q14; - int offset_Q10; - int FiltState[] = new int[ Silk_define.MAX_LPC_ORDER ]; - int x_sc_Q10[] = new int[ Silk_define.MAX_FRAME_LENGTH / Silk_define.NB_SUBFR ]; - - subfr_length = psEncC.frame_length / Silk_define.NB_SUBFR; - - NSQ.rand_seed = psEncCtrlC.Seed; - /* Set unvoiced lag to the previous one, overwrite later for voiced */ - lag = NSQ.lagPrev; - - assert( NSQ.prev_inv_gain_Q16 != 0 ); - - offset_Q10 = Silk_tables_other.SKP_Silk_Quantization_Offsets_Q10[ psEncCtrlC.sigtype ][ psEncCtrlC.QuantOffsetType ]; - - if( LSFInterpFactor_Q2 == ( 1 << 2 ) ) { - LSF_interpolation_flag = 0; - } else { - LSF_interpolation_flag = 1; - } - - /* Setup pointers to start of sub frame */ - NSQ.sLTP_shp_buf_idx = psEncC.frame_length; - NSQ.sLTP_buf_idx = psEncC.frame_length; - pxq = NSQ.xq; - pxq_offset = psEncC.frame_length; -//TODO: use a local copy of the parameter short x[], which is supposed to be input; - short[] x_tmp = x.clone(); - int x_tmp_offset = 0; -//TODO: use a local copy of the parameter byte[] q, which is supposed to be output; - byte[] q_tmp = q.clone(); - int q_tmp_offset = 0; - - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - A_Q12 = PredCoef_Q12; - A_Q12_offset = (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * Silk_define.MAX_LPC_ORDER; - B_Q14 = LTPCoef_Q14; - B_Q14_offset = k * Silk_define.LTP_ORDER; - AR_shp_Q13 = AR2_Q13; - AR_shp_Q13_offset = k * Silk_define.SHAPE_LPC_ORDER_MAX; - - /* Noise shape parameters */ - assert( HarmShapeGain_Q14[ k ] >= 0 ); - HarmShapeFIRPacked_Q14 = ( HarmShapeGain_Q14[ k ] >> 2 ); - HarmShapeFIRPacked_Q14 |= ( ( HarmShapeGain_Q14[ k ] >> 1 ) << 16 ); - - - if( psEncCtrlC.sigtype == Silk_define.SIG_TYPE_VOICED ) { - /* Voiced */ - lag = psEncCtrlC.pitchL[ k ]; - - NSQ.rewhite_flag = 0; - /* Re-whitening */ - if( ( k & ( 3 - ( LSF_interpolation_flag << 1 ) ) ) == 0 ) { - /* Rewhiten with new A coefs */ - - start_idx = psEncC.frame_length - lag - psEncC.predictLPCOrder - Silk_define.LTP_ORDER / 2; - start_idx = Silk_SigProc_FIX.SKP_LIMIT_int( start_idx, 0, psEncC.frame_length - psEncC.predictLPCOrder ); /* Limit */ - - Arrays.fill(FiltState, 0, psEncC.predictLPCOrder, 0); - Silk_MA.SKP_Silk_MA_Prediction( NSQ.xq, start_idx + k * ( psEncC.frame_length >> 2 ), - A_Q12, A_Q12_offset, FiltState, sLTP, start_idx, psEncC.frame_length - start_idx, psEncC.predictLPCOrder ); - - NSQ.rewhite_flag = 1; - NSQ.sLTP_buf_idx = psEncC.frame_length; - } - } - - SKP_Silk_nsq_scale_states( NSQ, x_tmp, x_tmp_offset, x_sc_Q10, psEncC.subfr_length, sLTP, - sLTP_Q16, k, LTP_scale_Q14, Gains_Q16, psEncCtrlC.pitchL ); - - - SKP_Silk_noise_shape_quantizer( NSQ, psEncCtrlC.sigtype, x_sc_Q10, q_tmp, q_tmp_offset, pxq, pxq_offset, - sLTP_Q16, A_Q12, A_Q12_offset, B_Q14, B_Q14_offset, - AR_shp_Q13, AR_shp_Q13_offset, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, - offset_Q10, psEncC.subfr_length, psEncC.shapingLPCOrder, psEncC.predictLPCOrder - ); - - x_tmp_offset += psEncC.subfr_length; - q_tmp_offset += psEncC.subfr_length; - pxq_offset += psEncC.subfr_length; - } - - /* Save scalars for this layer */ - NSQ.sLF_AR_shp_Q12 = NSQ.sLF_AR_shp_Q12; - NSQ.prev_inv_gain_Q16 = NSQ.prev_inv_gain_Q16; - NSQ.lagPrev = psEncCtrlC.pitchL[ Silk_define.NB_SUBFR - 1 ]; - /* Save quantized speech and noise shaping signals */ - System.arraycopy(NSQ.xq, psEncC.frame_length, NSQ.xq, 0, psEncC.frame_length); - System.arraycopy(NSQ.sLTP_shp_Q10, psEncC.frame_length, NSQ.sLTP_shp_Q10, 0, psEncC.frame_length); - -//TODO: copy back the q_tmp to the output parameter q; - System.arraycopy(q_tmp, 0, q, 0, q.length); - } - - /** - * SKP_Silk_noise_shape_quantizer. - * @param NSQ NSQ state - * @param sigtype Signal type - * @param x_sc_Q10 - * @param q - * @param q_offset - * @param xq - * @param xq_offset - * @param sLTP_Q16 LTP state - * @param a_Q12 Short term prediction coefs - * @param a_Q12_offset - * @param b_Q14 Long term prediction coefs - * @param b_Q14_offset - * @param AR_shp_Q13 Noise shaping AR coefs - * @param AR_shp_Q13_offset - * @param lag Pitch lag - * @param HarmShapeFIRPacked_Q14 - * @param Tilt_Q14 Spectral tilt - * @param LF_shp_Q14 - * @param Gain_Q16 - * @param Lambda_Q10 - * @param offset_Q10 - * @param length Input length - * @param shapingLPCOrder Noise shaping AR filter order - * @param predictLPCOrder Prediction filter order - */ - static void SKP_Silk_noise_shape_quantizer( - SKP_Silk_nsq_state NSQ, /* I/O NSQ state */ - int sigtype, /* I Signal type */ - final int x_sc_Q10[], /* I */ - byte q[], /* O */ - int q_offset, - short xq[], /* O */ - int xq_offset, - int sLTP_Q16[], /* I/O LTP state */ - final short a_Q12[], /* I Short term prediction coefs */ - int a_Q12_offset, - final short b_Q14[], /* I Long term prediction coefs */ - int b_Q14_offset, - final short AR_shp_Q13[], /* I Noise shaping AR coefs */ - int AR_shp_Q13_offset, - int lag, /* I Pitch lag */ - int HarmShapeFIRPacked_Q14, /* I */ - int Tilt_Q14, /* I Spectral tilt */ - int LF_shp_Q14, /* I */ - int Gain_Q16, /* I */ - int Lambda_Q10, /* I */ - int offset_Q10, /* I */ - int length, /* I Input length */ - int shapingLPCOrder, /* I Noise shaping AR filter order */ - int predictLPCOrder /* I Prediction filter order */ - ) - { - int i, j; - int LTP_pred_Q14, LPC_pred_Q10, n_AR_Q10, n_LTP_Q14; - int n_LF_Q10, r_Q10, q_Q0, q_Q10; - int thr1_Q10, thr2_Q10, thr3_Q10; - int dither; - int exc_Q10, LPC_exc_Q10, xq_Q10; - int tmp, sLF_AR_shp_Q10; - int []psLPC_Q14; - int psLPC_Q14_offset; - int []shp_lag_ptr, pred_lag_ptr; - int shp_lag_ptr_offset, pred_lag_ptr_offset; - - shp_lag_ptr = NSQ.sLTP_shp_Q10; - shp_lag_ptr_offset = NSQ.sLTP_shp_buf_idx - lag + Silk_define.HARM_SHAPE_FIR_TAPS / 2; - pred_lag_ptr = sLTP_Q16; - pred_lag_ptr_offset = NSQ.sLTP_buf_idx - lag + Silk_define.LTP_ORDER / 2; - - /* Setup short term AR state */ - psLPC_Q14 = NSQ.sLPC_Q14; - psLPC_Q14_offset = Silk_define.MAX_LPC_ORDER - 1; - - /* Quantization thresholds */ - thr1_Q10 = ( -1536 - (Lambda_Q10 >> 1)); - thr2_Q10 = ( -512 - (Lambda_Q10 >> 1)); - thr2_Q10 = ( thr2_Q10 + (Silk_macros.SKP_SMULBB( offset_Q10, Lambda_Q10 ) >> 10 )); - thr3_Q10 = ( 512 + (Lambda_Q10 >> 1)); - - for( i = 0; i < length; i++ ) { - /* Generate dither */ - NSQ.rand_seed = Silk_SigProc_FIX.SKP_RAND( NSQ.rand_seed ); - - /* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */ - dither = ( NSQ.rand_seed >> 31 ); - - /* Short-term prediction */ - assert( ( predictLPCOrder & 1 ) == 0 ); /* check that order is even */ -// SKP_assert( ( (SKP_int64)a_Q12 & 3 ) == 0 ); /* check that array starts at 4-byte aligned address */ - assert( predictLPCOrder >= 10 ); /* check that unrolling works */ - /* Partially unrolled */ - LPC_pred_Q10 = Silk_macros.SKP_SMULWB( psLPC_Q14[ psLPC_Q14_offset+0 ], a_Q12[ a_Q12_offset+0 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-1 ], a_Q12[ a_Q12_offset+1 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-2 ], a_Q12[ a_Q12_offset+2 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-3 ], a_Q12[ a_Q12_offset+3 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-4 ], a_Q12[ a_Q12_offset+4 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-5 ], a_Q12[ a_Q12_offset+5 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-6 ], a_Q12[ a_Q12_offset+6 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-7 ], a_Q12[ a_Q12_offset+7 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-8 ], a_Q12[ a_Q12_offset+8 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-9 ], a_Q12[ a_Q12_offset+9 ] ); - - for( j = 10; j < predictLPCOrder; j ++ ) { - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-j ], a_Q12[ a_Q12_offset+j ] ); - } - /* Long-term prediction */ - if( sigtype == Silk_define.SIG_TYPE_VOICED ) { - /* Unrolled loop */ - LTP_pred_Q14 = Silk_macros.SKP_SMULWB( pred_lag_ptr[ pred_lag_ptr_offset +0 ], b_Q14[ b_Q14_offset+0 ] ); - LTP_pred_Q14 = Silk_macros.SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ pred_lag_ptr_offset -1 ], b_Q14[ b_Q14_offset+1 ] ); - LTP_pred_Q14 = Silk_macros.SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ pred_lag_ptr_offset -2 ], b_Q14[ b_Q14_offset+2 ] ); - LTP_pred_Q14 = Silk_macros.SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ pred_lag_ptr_offset -3 ], b_Q14[ b_Q14_offset+3 ] ); - LTP_pred_Q14 = Silk_macros.SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ pred_lag_ptr_offset -4 ], b_Q14[ b_Q14_offset+4 ] ); - pred_lag_ptr_offset++; - } else { - LTP_pred_Q14 = 0; - } - - /* Noise shape feedback */ - assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ -// SKP_assert( ( (SKP_int64)AR_shp_Q13 & 3 ) == 0 ); /* check that array starts at 4-byte aligned address */ - assert( shapingLPCOrder >= 12 ); /* check that unrolling works */ - /* Partially unrolled */ - n_AR_Q10 = Silk_macros.SKP_SMULWB( psLPC_Q14[ psLPC_Q14_offset+0 ], AR_shp_Q13[AR_shp_Q13_offset+0 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-1 ], AR_shp_Q13[AR_shp_Q13_offset+1 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-2 ], AR_shp_Q13[AR_shp_Q13_offset+2 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-3 ], AR_shp_Q13[AR_shp_Q13_offset+3 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-4 ], AR_shp_Q13[AR_shp_Q13_offset+4 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-5 ], AR_shp_Q13[AR_shp_Q13_offset+5 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-6 ], AR_shp_Q13[AR_shp_Q13_offset+6 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-7 ], AR_shp_Q13[AR_shp_Q13_offset+7 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-8 ], AR_shp_Q13[AR_shp_Q13_offset+8 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-9 ], AR_shp_Q13[AR_shp_Q13_offset+9 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-10 ], AR_shp_Q13[AR_shp_Q13_offset+10] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-11 ], AR_shp_Q13[AR_shp_Q13_offset+11] ); - - for( j = 12; j < shapingLPCOrder; j ++ ) { - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-j ], AR_shp_Q13[ AR_shp_Q13_offset+j ] ); - } - n_AR_Q10 = ( n_AR_Q10 >> 1 ); /* Q11 -> Q10 */ - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, NSQ.sLF_AR_shp_Q12, Tilt_Q14 ); - - n_LF_Q10 = ( Silk_macros.SKP_SMULWB( NSQ.sLTP_shp_Q10[ NSQ.sLTP_shp_buf_idx - 1 ], LF_shp_Q14 ) << 2 ); - n_LF_Q10 = Silk_macros.SKP_SMLAWT( n_LF_Q10, NSQ.sLF_AR_shp_Q12, LF_shp_Q14 ); - - assert( lag > 0 || sigtype == Silk_define.SIG_TYPE_UNVOICED ); - - /* Long-term shaping */ - if( lag > 0 ) { - /* Symmetric, packed FIR coefficients */ - n_LTP_Q14 = Silk_macros.SKP_SMULWB((shp_lag_ptr[ shp_lag_ptr_offset+0 ] + shp_lag_ptr[ shp_lag_ptr_offset-2 ] ), - HarmShapeFIRPacked_Q14 ); - n_LTP_Q14 = Silk_macros.SKP_SMLAWT(n_LTP_Q14, shp_lag_ptr[ shp_lag_ptr_offset-1 ],HarmShapeFIRPacked_Q14 ); - shp_lag_ptr_offset++; - n_LTP_Q14 = ( n_LTP_Q14 << 6 ); - } else { - n_LTP_Q14 = 0; - } - - /* Input minus prediction plus noise feedback */ - //r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP; - tmp = ( LTP_pred_Q14 - n_LTP_Q14 ); /* Add Q14 stuff */ - tmp = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( tmp, 4 ); /* round to Q10 */ - tmp = ( tmp + LPC_pred_Q10 ); /* add Q10 stuff */ - tmp = ( tmp - n_AR_Q10 ); /* subtract Q10 stuff */ - tmp = ( tmp - n_LF_Q10 ); /* subtract Q10 stuff */ - r_Q10 = ( x_sc_Q10[ i ] - tmp ); - - /* Flip sign depending on dither */ - r_Q10 = ( r_Q10 ^ dither ) - dither; - r_Q10 = ( r_Q10 - offset_Q10 ); - r_Q10 = Silk_SigProc_FIX.SKP_LIMIT_32( r_Q10, -64 << 10, 64 << 10 ); - - /* Quantize */ - if( r_Q10 < thr1_Q10 ) { - q_Q0 = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( ( r_Q10 + (Lambda_Q10 >> 1) ), 10 ); - q_Q10 = ( q_Q0 << 10 ); - } else if( r_Q10 < thr2_Q10 ) { - q_Q0 = -1; - q_Q10 = -1024; - } else if( r_Q10 > thr3_Q10 ) { - q_Q0 = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( ( r_Q10 - (Lambda_Q10 >> 1) ), 10 ); - q_Q10 = ( q_Q0 << 10 ); - } else { - q_Q0 = 0; - q_Q10 = 0; - } - q[ q_offset + i ] = ( byte)q_Q0; /* No saturation needed because max is 64 */ - - /* Excitation */ - exc_Q10 = ( q_Q10 + offset_Q10 ); - exc_Q10 = ( exc_Q10 ^ dither ) - dither; - - /* Add predictions */ - LPC_exc_Q10 = ( exc_Q10 + Silk_SigProc_FIX.SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ) ); - xq_Q10 = ( LPC_exc_Q10 + LPC_pred_Q10 ); - - /* Scale XQ back to normal level before saving */ - xq[ xq_offset + i ] = ( short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( Silk_macros.SKP_SMULWW( xq_Q10, Gain_Q16 ), 10 ) ); - - - /* Update states */ - psLPC_Q14_offset++; - psLPC_Q14[psLPC_Q14_offset] = ( xq_Q10 << 4 ); - sLF_AR_shp_Q10 = ( xq_Q10 - n_AR_Q10 ); - NSQ.sLF_AR_shp_Q12 = ( sLF_AR_shp_Q10 << 2 ); - - NSQ.sLTP_shp_Q10[ NSQ.sLTP_shp_buf_idx ] = ( sLF_AR_shp_Q10 - n_LF_Q10 ); - sLTP_Q16[ NSQ.sLTP_buf_idx ] = ( LPC_exc_Q10 << 6 ); - NSQ.sLTP_shp_buf_idx++; - NSQ.sLTP_buf_idx++; - - /* Make dither dependent on quantized signal */ - NSQ.rand_seed += q[ q_offset + i ]; - } - /* Update LPC synth buffer */ - System.arraycopy(NSQ.sLPC_Q14, length, NSQ.sLPC_Q14, 0, Silk_define.MAX_LPC_ORDER); - } - - /** - * - * @param NSQ NSQ state - * @param x input in Q0 - * @param x_offset - * @param x_sc_Q10 input scaled with 1/Gain - * @param length length of input - * @param sLTP re-whitened LTP state in Q0 - * @param sLTP_Q16 LTP state matching scaled input - * @param subfr subframe number - * @param LTP_scale_Q14 - * @param Gains_Q16 - * @param pitchL - */ - static void SKP_Silk_nsq_scale_states( - SKP_Silk_nsq_state NSQ, /* I/O NSQ state */ - final short x[], /* I input in Q0 */ - int x_offset, - int x_sc_Q10[], /* O input scaled with 1/Gain */ - int length, /* I length of input */ - short sLTP[], /* I re-whitened LTP state in Q0 */ - int sLTP_Q16[], /* O LTP state matching scaled input */ - int subfr, /* I subframe number */ - final int LTP_scale_Q14, /* I */ - final int Gains_Q16[], /* I */ - final int pitchL[] /* I */ - ) - { - int i, scale_length, lag; - int inv_gain_Q16, gain_adj_Q16, inv_gain_Q32; - - inv_gain_Q16 = ( Integer.MAX_VALUE / ( Gains_Q16[ subfr ] >> 1) ); - inv_gain_Q16 = ( inv_gain_Q16 < Short.MAX_VALUE ? inv_gain_Q16:Short.MAX_VALUE ); - lag = pitchL[ subfr ]; - - /* After rewhitening the LTP state is un-scaled */ - if( NSQ.rewhite_flag !=0 ) { - inv_gain_Q32 = ( inv_gain_Q16 << 16 ); - if( subfr == 0 ) { - /* Do LTP downscaling */ - inv_gain_Q32 = ( Silk_macros.SKP_SMULWB( inv_gain_Q32, LTP_scale_Q14 ) << 2 ); - } - for( i = NSQ.sLTP_buf_idx - lag - Silk_define.LTP_ORDER / 2; i < NSQ.sLTP_buf_idx; i++ ) { - sLTP_Q16[ i ] = Silk_macros.SKP_SMULWB( inv_gain_Q32, sLTP[ i ] ); - } - } - - /* Prepare for Worst case. Next frame starts with max lag voiced */ - scale_length = length * Silk_define.NB_SUBFR; /* approx max lag */ - scale_length = scale_length - Silk_macros.SKP_SMULBB( Silk_define.NB_SUBFR - (subfr + 1), length ); /* subtract samples that will be too old in next frame */ - scale_length = Silk_SigProc_FIX.SKP_max_int( scale_length, lag + Silk_define.LTP_ORDER ); /* make sure to scale whole pitch period if voiced */ - - /* Adjust for changing gain */ - if( inv_gain_Q16 != NSQ.prev_inv_gain_Q16 ) { - gain_adj_Q16 = Silk_Inlines.SKP_DIV32_varQ( inv_gain_Q16, NSQ.prev_inv_gain_Q16, 16 ); - - for( i = NSQ.sLTP_shp_buf_idx - scale_length; i < NSQ.sLTP_shp_buf_idx; i++ ) { - NSQ.sLTP_shp_Q10[ i ] = Silk_macros.SKP_SMULWW( gain_adj_Q16, NSQ.sLTP_shp_Q10[ i ] ); - } - - /* Scale LTP predict state */ - if( NSQ.rewhite_flag == 0 ) { - for( i = NSQ.sLTP_buf_idx - lag - Silk_define.LTP_ORDER / 2; i < NSQ.sLTP_buf_idx; i++ ) { - sLTP_Q16[ i ] = Silk_macros.SKP_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] ); - } - } - NSQ.sLF_AR_shp_Q12 = Silk_macros.SKP_SMULWW( gain_adj_Q16, NSQ.sLF_AR_shp_Q12 ); - - /* scale short term state */ - for( i = 0; i < Silk_define.MAX_LPC_ORDER; i++ ) { - NSQ.sLPC_Q14[ i ] = Silk_macros.SKP_SMULWW( gain_adj_Q16, NSQ.sLPC_Q14[ i ] ); - } - } - - /* Scale input */ - for( i = 0; i < length; i++ ) { - x_sc_Q10[ i ] = ( Silk_macros.SKP_SMULBB( x[ x_offset + i ], ( short )inv_gain_Q16 ) >> 6 ); - } - - /* save inv_gain */ - assert( inv_gain_Q16 != 0 ); - NSQ.prev_inv_gain_Q16 = inv_gain_Q16; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NSQ_del_dec.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NSQ_del_dec.java deleted file mode 100644 index 4a6c50956..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_NSQ_del_dec.java +++ /dev/null @@ -1,796 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -import java.util.*; - -/** - * - * @author Dingxin Xu - */ -class NSQ_del_dec_struct -{ - int RandState[] = new int[ Silk_define.DECISION_DELAY ]; - int Q_Q10[] = new int[ Silk_define.DECISION_DELAY ]; - int Xq_Q10[] = new int[ Silk_define.DECISION_DELAY ]; - int Pred_Q16[] = new int[ Silk_define.DECISION_DELAY ]; - int Shape_Q10[] = new int[ Silk_define.DECISION_DELAY ]; - int Gain_Q16[] = new int[ Silk_define.DECISION_DELAY ]; - int sLPC_Q14[] = new int[ Silk_define.MAX_FRAME_LENGTH / Silk_define.NB_SUBFR + Silk_define.NSQ_LPC_BUF_LENGTH() ]; - int LF_AR_Q12; - int Seed; - int SeedInit; - int RD_Q10; - public void FieldsInit() - { - Arrays.fill(this.RandState, 0); - Arrays.fill(this.Q_Q10, 0); - Arrays.fill(this.Xq_Q10, 0); - Arrays.fill(this.Pred_Q16, 0); - Arrays.fill(this.Shape_Q10, 0); - Arrays.fill(this.Gain_Q16, 0); - Arrays.fill(this.sLPC_Q14, 0); - this.LF_AR_Q12 = 0; - this.Seed = 0; - this.SeedInit = 0; - this.RD_Q10 = 0; - } -} - -/** - * - * @author Dingxin Xu - */ -class NSQ_sample_struct implements Cloneable -{ - int Q_Q10; - int RD_Q10; - int xq_Q14; - int LF_AR_Q12; - int sLTP_shp_Q10; - int LPC_exc_Q16; - public Object clone() - { - NSQ_sample_struct clone = null; - try { - clone = (NSQ_sample_struct) super.clone(); - } catch (CloneNotSupportedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return clone; - } -} - -/** - * - * @author Dingxin Xu - */ -public class Silk_NSQ_del_dec -{ - static void SKP_Silk_NSQ_del_dec( - SKP_Silk_encoder_state psEncC, /* I/O Encoder State */ - SKP_Silk_encoder_control psEncCtrlC, /* I Encoder Control */ - SKP_Silk_nsq_state NSQ, /* I/O NSQ state */ - short x[], /* I Prefiltered input signal */ - byte q[], /* O Quantized pulse signal */ - int LSFInterpFactor_Q2, /* I LSF interpolation factor in Q2 */ - short PredCoef_Q12[], /* I Prediction coefs */ - short LTPCoef_Q14[], /* I LT prediction coefs */ - short AR2_Q13[], /* I */ - int HarmShapeGain_Q14[],/* I */ - int Tilt_Q14[], /* I Spectral tilt */ - int LF_shp_Q14[], /* I */ - int Gains_Q16[], /* I */ - int Lambda_Q10, /* I */ - int LTP_scale_Q14 /* I LTP state scaling */ - ) - { - int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr; - int last_smple_idx, smpl_buf_idx, decisionDelay, subfr_length; - short[] A_Q12; - short[] B_Q14; - short[] AR_shp_Q13; - int A_Q12_offset, B_Q14_offset, AR_shp_Q13_offset; - short[] pxq; - int pxq_offset; - int sLTP_Q16[] = new int[ 2 * Silk_define.MAX_FRAME_LENGTH ]; - short sLTP[] = new short[ 2 * Silk_define.MAX_FRAME_LENGTH ]; - int HarmShapeFIRPacked_Q14; - int offset_Q10; - int FiltState[] = new int[ Silk_define.MAX_LPC_ORDER ], RDmin_Q10; - int x_sc_Q10[] = new int[ Silk_define.MAX_FRAME_LENGTH / Silk_define.NB_SUBFR ]; - NSQ_del_dec_struct psDelDec[] = new NSQ_del_dec_struct[ Silk_define.DEL_DEC_STATES_MAX ]; - /* - * psDelDec is an array of references, which has to be created manually. - */ - { - for(int psDelDecIni_i=0; psDelDecIni_i> 1 ) | ( 1 - LSF_interpolation_flag ) ) * Silk_define.MAX_LPC_ORDER ; - B_Q14 = LTPCoef_Q14; - B_Q14_offset = k * Silk_define.LTP_ORDER; - AR_shp_Q13 = AR2_Q13; - AR_shp_Q13_offset = k * Silk_define.SHAPE_LPC_ORDER_MAX; - - NSQ.rewhite_flag = 0; - if( psEncCtrlC.sigtype == Silk_define.SIG_TYPE_VOICED ) { - /* Voiced */ - lag = psEncCtrlC.pitchL[ k ]; - - /* Re-whitening */ - if( ( k & ( 3 - ( LSF_interpolation_flag << 1 ) ) ) == 0 ) { - if( k == 2 ) { - /* RESET DELAYED DECISIONS */ - /* Find winner */ - RDmin_Q10 = psDelDec[ 0 ].RD_Q10; - Winner_ind = 0; - for( i = 1; i < psEncC.nStatesDelayedDecision; i++ ) { - if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) { - RDmin_Q10 = psDelDec[ i ].RD_Q10; - Winner_ind = i; - } - } - for( i = 0; i < psEncC.nStatesDelayedDecision; i++ ) { - if( i != Winner_ind ) { - psDelDec[ i ].RD_Q10 += ( Integer.MAX_VALUE >> 4 ); - assert( psDelDec[ i ].RD_Q10 >= 0 ); - } - } - - /* Copy final part of signals from winner state to output and long-term filter states */ - psDD = psDelDec[ Winner_ind ]; - last_smple_idx = smpl_buf_idx + decisionDelay; - for( i = 0; i < decisionDelay; i++ ) { - last_smple_idx = ( last_smple_idx - 1 ) & Silk_define.DECISION_DELAY_MASK; -// q[ i - decisionDelay ] = ( SKP_int )SKP_RSHIFT( psDD.Q_Q10[ last_smple_idx ], 10 ); - q_tmp[ q_tmp_offset + i - decisionDelay ] = (byte) ( psDD.Q_Q10[ last_smple_idx ] >> 10 ); - -// pxq[ i - decisionDelay ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( -// SKP_SMULWW( psDD.Xq_Q10[ last_smple_idx ], -// psDD.Gain_Q16[ last_smple_idx ] ), 10 ) ); - pxq[ pxq_offset + i - decisionDelay ] = (short) Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( - Silk_macros.SKP_SMULWW( psDD.Xq_Q10[ last_smple_idx ], - psDD.Gain_Q16[ last_smple_idx ] ), 10 ) ); - NSQ.sLTP_shp_Q10[ NSQ.sLTP_shp_buf_idx - decisionDelay + i ] = psDD.Shape_Q10[ last_smple_idx ]; - } - - subfr = 0; - } - - /* Rewhiten with new A coefs */ - start_idx = psEncC.frame_length - lag - psEncC.predictLPCOrder - Silk_define.LTP_ORDER / 2; - start_idx = Silk_SigProc_FIX.SKP_LIMIT_int( start_idx, 0, psEncC.frame_length - psEncC.predictLPCOrder ); - -// SKP_memset( FiltState, 0, psEncC.predictLPCOrder * sizeof( SKP_int32 ) ); - Arrays.fill(FiltState, 0, psEncC.predictLPCOrder, 0); - Silk_MA.SKP_Silk_MA_Prediction( NSQ.xq, start_idx + k * psEncC.subfr_length, - A_Q12, A_Q12_offset, FiltState, sLTP, start_idx, psEncC.frame_length - start_idx, psEncC.predictLPCOrder ); - - NSQ.sLTP_buf_idx = psEncC.frame_length; - NSQ.rewhite_flag = 1; - } - } - - /* Noise shape parameters */ - assert( HarmShapeGain_Q14[ k ] >= 0 ); - HarmShapeFIRPacked_Q14 = ( HarmShapeGain_Q14[ k ] >> 2 ); - HarmShapeFIRPacked_Q14 |= ( ( HarmShapeGain_Q14[ k ] >> 1 ) << 16 ); - - SKP_Silk_nsq_del_dec_scale_states( NSQ, psDelDec, x_tmp, x_tmp_offset, x_sc_Q10, - subfr_length, sLTP, sLTP_Q16, k, psEncC.nStatesDelayedDecision, smpl_buf_idx, - LTP_scale_Q14, Gains_Q16, psEncCtrlC.pitchL ); - - int smpl_buf_idx_ptr[] = new int[1]; - smpl_buf_idx_ptr[0] = smpl_buf_idx; - SKP_Silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psEncCtrlC.sigtype, x_sc_Q10, q_tmp, q_tmp_offset, pxq, pxq_offset, - sLTP_Q16, A_Q12, A_Q12_offset, B_Q14, B_Q14_offset, AR_shp_Q13, AR_shp_Q13_offset, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], - LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC.subfr_length, subfr++, psEncC.shapingLPCOrder, psEncC.predictLPCOrder, - psEncC.nStatesDelayedDecision, smpl_buf_idx_ptr, decisionDelay ); - smpl_buf_idx = smpl_buf_idx_ptr[0]; - - x_tmp_offset += psEncC.subfr_length; - q_tmp_offset += psEncC.subfr_length; - pxq_offset += psEncC.subfr_length; - } - - /* Find winner */ - RDmin_Q10 = psDelDec[ 0 ].RD_Q10; - Winner_ind = 0; - for( k = 1; k < psEncC.nStatesDelayedDecision; k++ ) { - if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) { - RDmin_Q10 = psDelDec[ k ].RD_Q10; - Winner_ind = k; - } - } - - /* Copy final part of signals from winner state to output and long-term filter states */ - psDD = psDelDec[ Winner_ind ]; - psEncCtrlC.Seed = psDD.SeedInit; - last_smple_idx = smpl_buf_idx + decisionDelay; - for( i = 0; i < decisionDelay; i++ ) { - last_smple_idx = ( last_smple_idx - 1 ) & Silk_define.DECISION_DELAY_MASK; - q_tmp[q_tmp_offset + i - decisionDelay] = ( byte )( psDD.Q_Q10[ last_smple_idx ] >> 10 ); - pxq[ pxq_offset + i - decisionDelay ] = ( short )Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( - Silk_macros.SKP_SMULWW( psDD.Xq_Q10[ last_smple_idx ], psDD.Gain_Q16[ last_smple_idx ] ), 10 ) ); - NSQ.sLTP_shp_Q10[ NSQ.sLTP_shp_buf_idx - decisionDelay + i ] = psDD.Shape_Q10[ last_smple_idx ]; - sLTP_Q16[ NSQ.sLTP_buf_idx - decisionDelay + i ] = psDD.Pred_Q16[ last_smple_idx ]; - - } -// SKP_memcpy( NSQ.sLPC_Q14, &psDD.sLPC_Q14[ psEncC.subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) ); - System.arraycopy(psDD.sLPC_Q14, psEncC.subfr_length, NSQ.sLPC_Q14, 0, Silk_define.NSQ_LPC_BUF_LENGTH()); - - /* Update states */ - NSQ.sLF_AR_shp_Q12 = psDD.LF_AR_Q12; - NSQ.prev_inv_gain_Q16 = NSQ.prev_inv_gain_Q16; - NSQ.lagPrev = psEncCtrlC.pitchL[ Silk_define.NB_SUBFR - 1 ]; - - /* Save quantized speech and noise shaping signals */ -// SKP_memcpy( NSQ.xq, &NSQ.xq[ psEncC.frame_length ], psEncC.frame_length * sizeof( SKP_int16 ) ); -// SKP_memcpy( NSQ.sLTP_shp_Q10, &NSQ.sLTP_shp_Q10[ psEncC.frame_length ], psEncC.frame_length * sizeof( SKP_int32 ) ); - System.arraycopy(NSQ.xq, psEncC.frame_length, NSQ.xq, 0, psEncC.frame_length); - System.arraycopy(NSQ.sLTP_shp_Q10, psEncC.frame_length, NSQ.sLTP_shp_Q10, 0, psEncC.frame_length); -//TODO: copy back the q_tmp to the output parameter q; - System.arraycopy(q_tmp, 0, q, 0, q.length); - } - - /** - * Noise shape quantizer for one subframe. - * @param NSQ NSQ state - * @param psDelDec Delayed decision states - * @param sigtype Signal type - * @param x_Q10 - * @param q - * @param q_offset - * @param xq - * @param xq_offset - * @param sLTP_Q16 LTP filter state - * @param a_Q12 Short term prediction coefs - * @param a_Q12_offset - * @param b_Q14 Long term prediction coefs - * @param b_Q14_offset - * @param AR_shp_Q13 Noise shaping coefs - * @param AR_shp_Q13_offset - * @param lag Pitch lag - * @param HarmShapeFIRPacked_Q14 - * @param Tilt_Q14 Spectral tilt - * @param LF_shp_Q14 - * @param Gain_Q16 - * @param Lambda_Q10 - * @param offset_Q10 - * @param length Input length - * @param subfr Subframe number - * @param shapingLPCOrder Shaping LPC filter order - * @param predictLPCOrder Prediction LPC filter order - * @param nStatesDelayedDecision Number of states in decision tree - * @param smpl_buf_idx Index to newest samples in buffers - * @param decisionDelay - */ - static void SKP_Silk_noise_shape_quantizer_del_dec( - SKP_Silk_nsq_state NSQ, /* I/O NSQ state */ - NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ - int sigtype, /* I Signal type */ - final int x_Q10[], /* I */ - byte q[], /* O */ - int q_offset, - short xq[], /* O */ - int xq_offset, - int sLTP_Q16[], /* I/O LTP filter state */ - final short a_Q12[], /* I Short term prediction coefs */ - int a_Q12_offset, - final short b_Q14[], /* I Long term prediction coefs */ - int b_Q14_offset, - final short AR_shp_Q13[], /* I Noise shaping coefs */ - int AR_shp_Q13_offset, - int lag, /* I Pitch lag */ - int HarmShapeFIRPacked_Q14, /* I */ - int Tilt_Q14, /* I Spectral tilt */ - int LF_shp_Q14, /* I */ - int Gain_Q16, /* I */ - int Lambda_Q10, /* I */ - int offset_Q10, /* I */ - int length, /* I Input length */ - int subfr, /* I Subframe number */ - int shapingLPCOrder, /* I Shaping LPC filter order */ - int predictLPCOrder, /* I Prediction LPC filter order */ - int nStatesDelayedDecision, /* I Number of states in decision tree */ - int []smpl_buf_idx, /* I Index to newest samples in buffers */ - int decisionDelay /* I */ - ) - { - int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx; - int Winner_rand_state; - int LTP_pred_Q14, LPC_pred_Q10, n_AR_Q10, n_LTP_Q14; - int n_LF_Q10; - int r_Q10, rr_Q20, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10; - int q1_Q10, q2_Q10; - int dither; - int exc_Q10, LPC_exc_Q10, xq_Q10; - int tmp, sLF_AR_shp_Q10; - int pred_lag_ptr[], shp_lag_ptr[]; - int pred_lag_ptr_offset, shp_lag_ptr_offset; - int []psLPC_Q14; int psLPC_Q14_offset; - NSQ_sample_struct psSampleState[][] = new NSQ_sample_struct[ Silk_define.DEL_DEC_STATES_MAX ][ 2 ]; - /* - * psSampleState is an two-dimension array of reference, which should be created manually. - */ - { - for(int Ini_i=0; Ini_i 0 ) { - /* Symmetric, packed FIR coefficients */ - n_LTP_Q14 = Silk_macros.SKP_SMULWB( ( shp_lag_ptr[ shp_lag_ptr_offset+0 ] + shp_lag_ptr[ shp_lag_ptr_offset-2 ] ), HarmShapeFIRPacked_Q14 ); - n_LTP_Q14 = Silk_macros.SKP_SMLAWT( n_LTP_Q14, shp_lag_ptr[ shp_lag_ptr_offset-1 ], HarmShapeFIRPacked_Q14 ); -// n_LTP_Q14 = SKP_LSHIFT( n_LTP_Q14, 6 ); - n_LTP_Q14 = ( n_LTP_Q14 << 6 ); - shp_lag_ptr_offset++; - } else { - n_LTP_Q14 = 0; - } - - for( k = 0; k < nStatesDelayedDecision; k++ ) { - /* Delayed decision state */ - psDD = psDelDec[ k ]; - - /* Sample state */ - psSS = psSampleState[ k ]; - - /* Generate dither */ - psDD.Seed = Silk_SigProc_FIX.SKP_RAND( psDD.Seed ); - - /* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */ -// dither = SKP_RSHIFT( psDD.Seed, 31 ); - dither = ( psDD.Seed >> 31 ); - - /* Pointer used in short term prediction and shaping */ - psLPC_Q14 = psDD.sLPC_Q14; - psLPC_Q14_offset = Silk_define.NSQ_LPC_BUF_LENGTH() - 1 + i; - /* Short-term prediction */ - assert( predictLPCOrder >= 10 ); /* check that unrolling works */ - assert( ( predictLPCOrder & 1 ) == 0 ); /* check that order is even */ -// SKP_assert( ( (SKP_int64)a_Q12 & 3 ) == 0 ); /* check that array starts at 4-byte aligned address */ - /* Partially unrolled */ - LPC_pred_Q10 = Silk_macros.SKP_SMULWB( psLPC_Q14[ psLPC_Q14_offset+0 ], a_Q12[ a_Q12_offset+0 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-1 ], a_Q12[ a_Q12_offset+1 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-2 ], a_Q12[ a_Q12_offset+2 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-3 ], a_Q12[ a_Q12_offset+3 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-4 ], a_Q12[ a_Q12_offset+4 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-5 ], a_Q12[ a_Q12_offset+5 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-6 ], a_Q12[ a_Q12_offset+6 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-7 ], a_Q12[ a_Q12_offset+7 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-8 ], a_Q12[ a_Q12_offset+8 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-9 ], a_Q12[ a_Q12_offset+9 ] ); - - for( j = 10; j < predictLPCOrder; j ++ ) { - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ psLPC_Q14_offset-j ], a_Q12[ a_Q12_offset+j]); - } - - /* Noise shape feedback */ - assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ -// assert( ( (SKP_int64)AR_shp_Q13 & 3 ) == 0 ); /* check that array starts at 4-byte aligned address */ - assert( shapingLPCOrder >= 12 ); /* check that unrolling works */ - /* Partially unrolled */ - n_AR_Q10 = Silk_macros.SKP_SMULWB( psLPC_Q14[ psLPC_Q14_offset+0 ], AR_shp_Q13[ AR_shp_Q13_offset+0 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-1 ], AR_shp_Q13[ AR_shp_Q13_offset+1 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-2 ], AR_shp_Q13[ AR_shp_Q13_offset+2 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-3 ], AR_shp_Q13[ AR_shp_Q13_offset+3 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-4 ], AR_shp_Q13[ AR_shp_Q13_offset+4 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-5 ], AR_shp_Q13[ AR_shp_Q13_offset+5 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-6 ], AR_shp_Q13[ AR_shp_Q13_offset+6 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-7 ], AR_shp_Q13[ AR_shp_Q13_offset+7 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-8 ], AR_shp_Q13[ AR_shp_Q13_offset+8 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-9 ], AR_shp_Q13[ AR_shp_Q13_offset+9 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-10 ],AR_shp_Q13[ AR_shp_Q13_offset+10 ] ); - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-11 ],AR_shp_Q13[ AR_shp_Q13_offset+11 ] ); - - for( j = 12; j < shapingLPCOrder; j ++ ) { - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ psLPC_Q14_offset-j ], AR_shp_Q13[ AR_shp_Q13_offset+j ] ); - } - -// n_AR_Q10 = SKP_RSHIFT( n_AR_Q10, 1 ); /* Q11 -> Q10 */ - n_AR_Q10 = ( n_AR_Q10 >> 1 ); /* Q11 -> Q10 */ - n_AR_Q10 = Silk_macros.SKP_SMLAWB( n_AR_Q10, psDD.LF_AR_Q12, Tilt_Q14 ); - - n_LF_Q10 = ( Silk_macros.SKP_SMULWB( psDD.Shape_Q10[ smpl_buf_idx[0] ], LF_shp_Q14 ) << 2 ); - n_LF_Q10 = Silk_macros.SKP_SMLAWT( n_LF_Q10, psDD.LF_AR_Q12, LF_shp_Q14 ); - - /* Input minus prediction plus noise feedback */ - /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */ - tmp = ( LTP_pred_Q14 - n_LTP_Q14 ); /* Add Q14 stuff */ - tmp = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( tmp, 4 ); /* round to Q10 */ - tmp = ( tmp + LPC_pred_Q10 ); /* add Q10 stuff */ - tmp = ( tmp - n_AR_Q10 ); /* subtract Q10 stuff */ - tmp = ( tmp - n_LF_Q10 ); /* subtract Q10 stuff */ - r_Q10 = ( x_Q10[ i ] - tmp ); /* residual error Q10 */ - - /* Flip sign depending on dither */ - r_Q10 = ( r_Q10 ^ dither ) - dither; - r_Q10 = ( r_Q10 - offset_Q10 ); - r_Q10 = Silk_SigProc_FIX.SKP_LIMIT_32( r_Q10, -64 << 10, 64 << 10 ); - - /* Find two quantization level candidates and measure their rate-distortion */ - if( r_Q10 < -1536 ) { - q1_Q10 = ( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( r_Q10, 10 ) << 10 ); - r_Q10 = ( r_Q10 - q1_Q10 ); - rd1_Q10 = ( Silk_macros.SKP_SMLABB( ( -( q1_Q10 + offset_Q10 ) * Lambda_Q10 ), r_Q10, r_Q10 ) >> 10 ); - rd2_Q10 = ( rd1_Q10 + 1024 ); - rd2_Q10 = ( rd2_Q10 - Silk_SigProc_FIX.SKP_ADD_LSHIFT32( Lambda_Q10, r_Q10, 1 ) ); - q2_Q10 = ( q1_Q10 + 1024 ); - } else if( r_Q10 > 512 ) { - q1_Q10 = ( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( r_Q10, 10 ) << 10 ); - r_Q10 = ( r_Q10 - q1_Q10 ); - rd1_Q10 = ( Silk_macros.SKP_SMLABB( ( ( q1_Q10 + offset_Q10 ) * Lambda_Q10 ), r_Q10, r_Q10 ) >> 10 ); - rd2_Q10 = ( rd1_Q10 + 1024 ); - rd2_Q10 = ( rd2_Q10 - Silk_SigProc_FIX.SKP_SUB_LSHIFT32( Lambda_Q10, r_Q10, 1 ) ); - q2_Q10 = ( q1_Q10 - 1024 ); - } else { /* r_Q10 >= -1536 && q1_Q10 <= 512 */ - rr_Q20 = Silk_macros.SKP_SMULBB( offset_Q10, Lambda_Q10 ); - rd2_Q10 = ( Silk_macros.SKP_SMLABB( rr_Q20, r_Q10, r_Q10 ) >> 10 ); - rd1_Q10 = ( rd2_Q10 + 1024 ); - rd1_Q10 = ( rd1_Q10 + Silk_SigProc_FIX.SKP_SUB_RSHIFT32( Silk_SigProc_FIX.SKP_ADD_LSHIFT32( Lambda_Q10, r_Q10, 1 ), rr_Q20, 9 ) ); - q1_Q10 = -1024; - q2_Q10 = 0; - } - - if( rd1_Q10 < rd2_Q10 ) { - psSS[ 0 ].RD_Q10 = ( psDD.RD_Q10 + rd1_Q10 ); - psSS[ 1 ].RD_Q10 = ( psDD.RD_Q10 + rd2_Q10 ); - psSS[ 0 ].Q_Q10 = q1_Q10; - psSS[ 1 ].Q_Q10 = q2_Q10; - } else { - psSS[ 0 ].RD_Q10 = ( psDD.RD_Q10 + rd2_Q10 ); - psSS[ 1 ].RD_Q10 = ( psDD.RD_Q10 + rd1_Q10 ); - psSS[ 0 ].Q_Q10 = q2_Q10; - psSS[ 1 ].Q_Q10 = q1_Q10; - } - - /* Update states for best quantization */ - - /* Quantized excitation */ - exc_Q10 = ( offset_Q10 + psSS[ 0 ].Q_Q10 ); - exc_Q10 = ( exc_Q10 ^ dither ) - dither; - - /* Add predictions */ - LPC_exc_Q10 = exc_Q10 + Silk_SigProc_FIX.SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ); - xq_Q10 = ( LPC_exc_Q10 + LPC_pred_Q10 ); - - /* Update states */ - sLF_AR_shp_Q10 = ( xq_Q10 - n_AR_Q10 ); - psSS[ 0 ].sLTP_shp_Q10 = ( sLF_AR_shp_Q10 - n_LF_Q10 ); - psSS[ 0 ].LF_AR_Q12 = ( sLF_AR_shp_Q10 << 2 ); - psSS[ 0 ].xq_Q14 = ( xq_Q10 << 4 ); - psSS[ 0 ].LPC_exc_Q16 = ( LPC_exc_Q10 << 6 ); - - /* Update states for second best quantization */ - - /* Quantized excitation */ - exc_Q10 = ( offset_Q10 + psSS[ 1 ].Q_Q10 ); - exc_Q10 = ( exc_Q10 ^ dither ) - dither; - - /* Add predictions */ - LPC_exc_Q10 = exc_Q10 + Silk_SigProc_FIX.SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ); - xq_Q10 = ( LPC_exc_Q10 + LPC_pred_Q10 ); - - /* Update states */ - sLF_AR_shp_Q10 = ( xq_Q10 - n_AR_Q10 ); - psSS[ 1 ].sLTP_shp_Q10 = ( sLF_AR_shp_Q10 - n_LF_Q10 ); - psSS[ 1 ].LF_AR_Q12 = ( sLF_AR_shp_Q10 << 2 ); - psSS[ 1 ].xq_Q14 = ( xq_Q10 << 4 ); - psSS[ 1 ].LPC_exc_Q16 = ( LPC_exc_Q10 << 6 ); - } - - smpl_buf_idx[0] = ( smpl_buf_idx[0] - 1 ) & Silk_define.DECISION_DELAY_MASK; /* Index to newest samples */ - last_smple_idx = ( smpl_buf_idx[0] + decisionDelay ) & Silk_define.DECISION_DELAY_MASK; /* Index to decisionDelay old samples */ - - /* Find winner */ - RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; - Winner_ind = 0; - for( k = 1; k < nStatesDelayedDecision; k++ ) { - if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) { - RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10; - Winner_ind = k; - } - } - - /* Increase RD values of expired states */ - Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ]; - for( k = 0; k < nStatesDelayedDecision; k++ ) { - if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) { - psSampleState[ k ][ 0 ].RD_Q10 = ( psSampleState[ k ][ 0 ].RD_Q10 + ( Integer.MAX_VALUE >> 4 ) ); - psSampleState[ k ][ 1 ].RD_Q10 = ( psSampleState[ k ][ 1 ].RD_Q10 + ( Integer.MAX_VALUE >> 4 ) ); - assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 ); - } - } - - /* Find worst in first set and best in second set */ - RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; - RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10; - RDmax_ind = 0; - RDmin_ind = 0; - for( k = 1; k < nStatesDelayedDecision; k++ ) { - /* find worst in first set */ - if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) { - RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10; - RDmax_ind = k; - } - /* find best in second set */ - if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) { - RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10; - RDmin_ind = k; - } - } - - /* Replace a state if best from second set outperforms worst in first set */ - if( RDmin_Q10 < RDmax_Q10 ) { -// SKP_Silk_copy_del_dec_state( &psDelDec[ RDmax_ind ], &psDelDec[ RDmin_ind ], i ); - SKP_Silk_copy_del_dec_state( psDelDec[ RDmax_ind ], psDelDec[ RDmin_ind ], i ); -//TODO:how to copy a struct ??? -// SKP_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) ); - psSampleState[ RDmax_ind ][ 0 ] = (NSQ_sample_struct) psSampleState[ RDmin_ind ][ 1 ].clone(); - } - - /* Write samples from winner to output and long-term filter states */ - psDD = psDelDec[ Winner_ind ]; - if( subfr > 0 || i >= decisionDelay ) { - q[ q_offset + i - decisionDelay ] = ( byte )( psDD.Q_Q10[ last_smple_idx ] >> 10 ); - xq[ xq_offset + i - decisionDelay ] = ( short )Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( - Silk_macros.SKP_SMULWW( psDD.Xq_Q10[ last_smple_idx ], psDD.Gain_Q16[ last_smple_idx ] ), 10 ) ); - NSQ.sLTP_shp_Q10[ NSQ.sLTP_shp_buf_idx - decisionDelay ] = psDD.Shape_Q10[ last_smple_idx ]; - sLTP_Q16[ NSQ.sLTP_buf_idx - decisionDelay ] = psDD.Pred_Q16[ last_smple_idx ]; - } - NSQ.sLTP_shp_buf_idx++; - NSQ.sLTP_buf_idx++; - - /* Update states */ - for( k = 0; k < nStatesDelayedDecision; k++ ) { - psDD = psDelDec[ k ]; -//TODO: psSS is an array of reference rather than a reference. -// psSS = &psSampleState[ k ][ 0 ]; - psSS = psSampleState[ k ]; - psDD.LF_AR_Q12 = psSS[0].LF_AR_Q12; - psDD.sLPC_Q14[ Silk_define.NSQ_LPC_BUF_LENGTH() + i ] = psSS[0].xq_Q14; - psDD.Xq_Q10[ smpl_buf_idx[0] ] = ( psSS[0].xq_Q14 >> 4 ); - psDD.Q_Q10[ smpl_buf_idx[0] ] = psSS[0].Q_Q10; - psDD.Pred_Q16[ smpl_buf_idx[0] ] = psSS[0].LPC_exc_Q16; - psDD.Shape_Q10[ smpl_buf_idx[0] ] = psSS[0].sLTP_shp_Q10; - psDD.Seed = Silk_SigProc_FIX.SKP_ADD_RSHIFT32( psDD.Seed, psSS[0].Q_Q10, 10 ); - psDD.RandState[ smpl_buf_idx[0] ] = psDD.Seed; - psDD.RD_Q10 = psSS[0].RD_Q10; - psDD.Gain_Q16[ smpl_buf_idx[0] ] = Gain_Q16; - } - } - /* Update LPC states */ - for( k = 0; k < nStatesDelayedDecision; k++ ) { - psDD = psDelDec[ k ]; - System.arraycopy(psDD.sLPC_Q14, length, psDD.sLPC_Q14, 0, Silk_define.NSQ_LPC_BUF_LENGTH()); - } - } - - /** - * - * @param NSQ NSQ state - * @param psDelDec Delayed decision states - * @param x Input in Q0 - * @param x_offset offset of valid data. - * @param x_sc_Q10 nput scaled with 1/Gain in Q10 - * @param length Length of input - * @param sLTP Re-whitened LTP state in Q0 - * @param sLTP_Q16 LTP state matching scaled input - * @param subfr Subframe number - * @param nStatesDelayedDecision Number of del dec states - * @param smpl_buf_idx Index to newest samples in buffers - * @param LTP_scale_Q14 LTP state scaling - * @param Gains_Q16 - * @param pitchL Pitch lag - */ - static void SKP_Silk_nsq_del_dec_scale_states( - SKP_Silk_nsq_state NSQ, /* I/O NSQ state */ - NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ - final short x[], /* I Input in Q0 */ - int x_offset, - int x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ - int length, /* I Length of input */ - short sLTP[], /* I Re-whitened LTP state in Q0 */ - int sLTP_Q16[], /* O LTP state matching scaled input */ - int subfr, /* I Subframe number */ - int nStatesDelayedDecision, /* I Number of del dec states */ - int smpl_buf_idx, /* I Index to newest samples in buffers */ - final int LTP_scale_Q14, /* I LTP state scaling */ - final int Gains_Q16[], /* I */ - final int pitchL[] /* I Pitch lag */ - ) - { - int i, k, scale_length, lag; - int inv_gain_Q16, gain_adj_Q16, inv_gain_Q32; - NSQ_del_dec_struct psDD; - - inv_gain_Q16 = ( Integer.MAX_VALUE / ( Gains_Q16[ subfr ] >> 1 ) ); - inv_gain_Q16 = ( inv_gain_Q16 < Short.MAX_VALUE ? inv_gain_Q16:Short.MAX_VALUE); - lag = pitchL[ subfr ]; - /* After rewhitening the LTP state is un-scaled. So scale with inv_gain_Q16 */ - if( NSQ.rewhite_flag != 0) { - inv_gain_Q32 = ( inv_gain_Q16 << 16 ); - if( subfr == 0 ) { - /* Do LTP downscaling */ - inv_gain_Q32 = ( Silk_macros.SKP_SMULWB( inv_gain_Q32, LTP_scale_Q14 ) << 2 ); - } - for( i = NSQ.sLTP_buf_idx - lag - Silk_define.LTP_ORDER / 2; i < NSQ.sLTP_buf_idx; i++ ) { - assert( i < Silk_define.MAX_FRAME_LENGTH ); - sLTP_Q16[ i ] = Silk_macros.SKP_SMULWB( inv_gain_Q32, sLTP[ i ] ); - } - } - - /* Adjust for changing gain */ - if( inv_gain_Q16 != NSQ.prev_inv_gain_Q16 ) { - gain_adj_Q16 = Silk_Inlines.SKP_DIV32_varQ( inv_gain_Q16, NSQ.prev_inv_gain_Q16, 16 ); - - for( k = 0; k < nStatesDelayedDecision; k++ ) { - psDD = psDelDec[ k ]; - - /* Scale scalar states */ - psDD.LF_AR_Q12 = Silk_macros.SKP_SMULWW( gain_adj_Q16, psDD.LF_AR_Q12 ); - - /* scale short term state */ - for( i = 0; i < Silk_define.NSQ_LPC_BUF_LENGTH(); i++ ) { - psDD.sLPC_Q14[ Silk_define.NSQ_LPC_BUF_LENGTH() - i - 1 ] = Silk_macros.SKP_SMULWW( gain_adj_Q16, - psDD.sLPC_Q14[ Silk_define.NSQ_LPC_BUF_LENGTH() - i - 1 ] ); - } - for( i = 0; i < Silk_define.DECISION_DELAY; i++ ) { - psDD.Pred_Q16[ i ] = Silk_macros.SKP_SMULWW( gain_adj_Q16, psDD.Pred_Q16[ i ] ); - psDD.Shape_Q10[ i ] = Silk_macros.SKP_SMULWW( gain_adj_Q16, psDD.Shape_Q10[ i ] ); - } - } - - /* Scale long term shaping state */ - - /* Calculate length to be scaled, Worst case: Next frame is voiced with max lag */ - scale_length = length * Silk_define.NB_SUBFR; /* aprox max lag */ - scale_length = scale_length - Silk_macros.SKP_SMULBB( Silk_define.NB_SUBFR - ( subfr + 1 ), length ); /* subtract samples that will be too old in next frame */ - scale_length = Math.max( scale_length, lag + Silk_define.LTP_ORDER ); /* make sure to scale whole pitch period if voiced */ - - for( i = NSQ.sLTP_shp_buf_idx - scale_length; i < NSQ.sLTP_shp_buf_idx; i++ ) { - NSQ.sLTP_shp_Q10[ i ] = Silk_macros.SKP_SMULWW( gain_adj_Q16, NSQ.sLTP_shp_Q10[ i ] ); - } - - /* Scale LTP predict state */ - if( NSQ.rewhite_flag == 0 ) { - for( i = NSQ.sLTP_buf_idx - lag - Silk_define.LTP_ORDER / 2; i < NSQ.sLTP_buf_idx; i++ ) { - sLTP_Q16[ i ] = Silk_macros.SKP_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] ); - } - } - } - - /* Scale input */ - for( i = 0; i < length; i++ ) { - x_sc_Q10[ i ] = (Silk_macros.SKP_SMULBB( x[ x_offset + i ], ( short )inv_gain_Q16 ) >> 6 ); - } - - /* save inv_gain */ - assert( inv_gain_Q16 != 0 ); - NSQ.prev_inv_gain_Q16 = inv_gain_Q16; - } - - /** - * - * @param DD_dst Dst del dec state - * @param DD_src Src del dec state - * @param LPC_state_idx Index to LPC buffer - */ - static void SKP_Silk_copy_del_dec_state( - NSQ_del_dec_struct DD_dst, /* I Dst del dec state */ - NSQ_del_dec_struct DD_src, /* I Src del dec state */ - int LPC_state_idx /* I Index to LPC buffer */ - ) - { - System.arraycopy(DD_src.RandState, 0, DD_dst.RandState, 0, Silk_define.DECISION_DELAY); - System.arraycopy(DD_src.Q_Q10, 0, DD_dst.Q_Q10, 0, Silk_define.DECISION_DELAY); - System.arraycopy(DD_src.Pred_Q16, 0, DD_dst.Pred_Q16, 0, Silk_define.DECISION_DELAY); - System.arraycopy(DD_src.Shape_Q10, 0, DD_dst.Shape_Q10, 0, Silk_define.DECISION_DELAY); - System.arraycopy(DD_src.Xq_Q10, 0, DD_dst.Xq_Q10, 0, Silk_define.DECISION_DELAY); - - System.arraycopy(DD_src.sLPC_Q14, LPC_state_idx, DD_dst.sLPC_Q14, LPC_state_idx, Silk_define.NSQ_LPC_BUF_LENGTH()); - DD_dst.LF_AR_Q12 = DD_src.LF_AR_Q12; - DD_dst.Seed = DD_src.Seed; - DD_dst.SeedInit = DD_src.SeedInit; - DD_dst.RD_Q10 = DD_src.RD_Q10; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_PLC.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_PLC.java deleted file mode 100644 index 56fdb3d02..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_PLC.java +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -import java.util.*; - -/** - * SILK PNG. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_PLC -{ - static final int BWE_COEF_Q16 = 64880; /* 0.99 in Q16 */ - static final int V_PITCH_GAIN_START_MIN_Q14 = 11469; /* 0.7 in Q14 */ - static final int V_PITCH_GAIN_START_MAX_Q14 = 15565; /* 0.95 in Q14 */ - static final int MAX_PITCH_LAG_MS = 18; - static final int SA_THRES_Q8 = 50; - static final boolean USE_SINGLE_TAP = true; - static final int RAND_BUF_SIZE = 128; - static final int RAND_BUF_MASK = (RAND_BUF_SIZE - 1); - static final int LOG2_INV_LPC_GAIN_HIGH_THRES = 3; /* 2^3 = 8 dB LPC gain */ - static final int LOG2_INV_LPC_GAIN_LOW_THRES = 8; /* 2^8 = 24 dB LPC gain */ - static final int PITCH_DRIFT_FAC_Q16 = 655; /* 0.01 in Q16 */ - - static final int NB_ATT = 2; - - static short[] HARM_ATT_Q15 = { 32440, 31130 }; /* 0.99, 0.95 */ - static short[] PLC_RAND_ATTENUATE_V_Q15 = { 31130, 26214 }; /* 0.95, 0.8 */ - static short[] PLC_RAND_ATTENUATE_UV_Q15 = { 32440, 29491 }; /* 0.99, 0.9 */ - - /** - * PLC reset. - * @param psDec Decoder state. - */ - static void SKP_Silk_PLC_Reset( - SKP_Silk_decoder_state psDec /* I/O Decoder state */ - ) - { - psDec.sPLC.pitchL_Q8 = ( psDec.frame_length >> 1 ); - } - - /** - * - * @param psDec Decoder state. - * @param psDecCtrl Decoder control. - * @param signal Concealed signal. - * @param signal_offset offset of the valid data. - * @param length Length of residual. - * @param lost Loss flag. - */ - static void SKP_Silk_PLC( - SKP_Silk_decoder_state psDec, /* I Decoder state */ - SKP_Silk_decoder_control psDecCtrl, /* I Decoder control */ - short signal[], /* O Concealed signal */ - int signal_offset, - int length, /* I length of residual */ - int lost /* I Loss flag */ - ) - { - /* PLC control function */ - if( psDec.fs_kHz != psDec.sPLC.fs_kHz ) { - SKP_Silk_PLC_Reset( psDec ); - psDec.sPLC.fs_kHz = psDec.fs_kHz; - } - - if( lost != 0 ) { - /****************************/ - /* Generate Signal */ - /****************************/ - SKP_Silk_PLC_conceal( psDec, psDecCtrl, signal, signal_offset, length ); - } else { - /****************************/ - /* Update state */ - /****************************/ - SKP_Silk_PLC_update( psDec, psDecCtrl, signal, signal_offset, length ); - } - } - - /** - * Update state of PLC - * @param psDec Decoder state. - * @param psDecCtrl Decoder control. - * @param signal - * @param signal_offset - * @param length - */ - static void SKP_Silk_PLC_update( - SKP_Silk_decoder_state psDec, /* (I/O) Decoder state */ - SKP_Silk_decoder_control psDecCtrl, /* (I/O) Decoder control */ - short signal[], - int signal_offset, - int length - ) - { - int LTP_Gain_Q14, temp_LTP_Gain_Q14; - int i, j; - SKP_Silk_PLC_struct psPLC; - - psPLC = psDec.sPLC; - - /* Update parameters used in case of packet loss */ - psDec.prev_sigtype = psDecCtrl.sigtype; - LTP_Gain_Q14 = 0; - if( psDecCtrl.sigtype == Silk_define.SIG_TYPE_VOICED ) { - /* Find the parameters for the last subframe which contains a pitch pulse */ - for( j = 0; j * psDec.subfr_length < psDecCtrl.pitchL[ Silk_define.NB_SUBFR - 1 ]; j++ ) { - temp_LTP_Gain_Q14 = 0; - for( i = 0; i < Silk_define.LTP_ORDER; i++ ) { - temp_LTP_Gain_Q14 += psDecCtrl.LTPCoef_Q14[ ( Silk_define.NB_SUBFR - 1 - j ) * Silk_define.LTP_ORDER + i ]; - } - if( temp_LTP_Gain_Q14 > LTP_Gain_Q14 ) { - LTP_Gain_Q14 = temp_LTP_Gain_Q14; - System.arraycopy(psDecCtrl.LTPCoef_Q14, Silk_macros.SKP_SMULBB( Silk_define.NB_SUBFR - 1 - j, Silk_define.LTP_ORDER ), - psPLC.LTPCoef_Q14, 0, Silk_define.LTP_ORDER); - psPLC.pitchL_Q8 = ( psDecCtrl.pitchL[ Silk_define.NB_SUBFR - 1 - j ] << 8 ); - } - } - - if(USE_SINGLE_TAP) - { - Arrays.fill(psPLC.LTPCoef_Q14, 0, Silk_define.LTP_ORDER, (short)0); - psPLC.LTPCoef_Q14[ Silk_define.LTP_ORDER / 2 ] = (short) LTP_Gain_Q14; - } - - /* Limit LT coefs */ - if( LTP_Gain_Q14 < V_PITCH_GAIN_START_MIN_Q14 ) { - int scale_Q10; - int tmp; - - tmp = ( V_PITCH_GAIN_START_MIN_Q14 << 10 ); - - scale_Q10 = ( tmp / Math.max( LTP_Gain_Q14, 1 ) ); - - for( i = 0; i < Silk_define.LTP_ORDER; i++ ) { - psPLC.LTPCoef_Q14[ i ] = (short) ( Silk_macros.SKP_SMULBB( psPLC.LTPCoef_Q14[ i ], scale_Q10 ) >> 10 ); - } - } else if( LTP_Gain_Q14 > V_PITCH_GAIN_START_MAX_Q14 ) { - int scale_Q14; - int tmp; - - tmp = ( V_PITCH_GAIN_START_MAX_Q14 << 14 ); - scale_Q14 = ( tmp / Math.max( LTP_Gain_Q14, 1 ) ); - - for( i = 0; i < Silk_define.LTP_ORDER; i++ ) { - psPLC.LTPCoef_Q14[ i ] = (short) ( Silk_macros.SKP_SMULBB( psPLC.LTPCoef_Q14[ i ], scale_Q14 ) << 14 ); - } - } - } else { - psPLC.pitchL_Q8 = ( Silk_macros.SKP_SMULBB( psDec.fs_kHz, 18 ) << 8 ); - Arrays.fill(psPLC.LTPCoef_Q14, 0, Silk_define.LTP_ORDER, (short)0); - } - - /* Save LPC coeficients */ - System.arraycopy(psDecCtrl.PredCoef_Q12[1], 0, psPLC.prevLPC_Q12, 0, psDec.LPC_order); - psPLC.prevLTP_scale_Q14 = (short) psDecCtrl.LTP_scale_Q14; - - /* Save Gains */ - System.arraycopy(psDecCtrl.Gains_Q16, 0, psPLC.prevGain_Q16, 0, Silk_define.NB_SUBFR); - - } - - /** - * - * @param psDec Decoder state. - * @param psDecCtrl Decoder control. - * @param signal concealed signal. - * @param signal_offset offset of the valid data. - * @param length Length of residual. - */ - static void SKP_Silk_PLC_conceal( - SKP_Silk_decoder_state psDec, /* I/O Decoder state */ - SKP_Silk_decoder_control psDecCtrl, /* I/O Decoder control */ - short signal[], /* O concealed signal */ - int signal_offset, - int length /* I length of residual */ - ) - { - int i, j, k; - short[] B_Q14; - short[] exc_buf = new short[Silk_define.MAX_FRAME_LENGTH]; - short[] exc_buf_ptr; - int exc_buf_ptr_offset; - - short rand_scale_Q14; - short[] A_Q12_tmp = new short[Silk_define.MAX_LPC_ORDER]; - - - int rand_seed, harm_Gain_Q15, rand_Gain_Q15; - int lag, idx, shift1, shift2; - int shift1_ptr[] = new int[1]; - int shift2_ptr[] = new int[1]; - - int energy1, energy2; - int energy1_ptr[] = new int[1]; - int energy2_ptr[] = new int[1]; - - int[] rand_ptr, pred_lag_ptr; - int rand_ptr_offset, pred_lag_ptr_offset; - - int[] sig_Q10 = new int[Silk_define.MAX_FRAME_LENGTH]; - int[] sig_Q10_ptr; - int sig_Q10_ptr_offset; - - int LPC_exc_Q10, LPC_pred_Q10, LTP_pred_Q14; - - SKP_Silk_PLC_struct psPLC; - psPLC = psDec.sPLC; - - /* Update LTP buffer */ - System.arraycopy(psDec.sLTP_Q16, psDec.frame_length, psDec.sLTP_Q16, 0, psDec.frame_length); - - /* LPC concealment. Apply BWE to previous LPC */ - Silk_bwexpander.SKP_Silk_bwexpander( psPLC.prevLPC_Q12, psDec.LPC_order, BWE_COEF_Q16 ); - - /* Find random noise component */ - /* Scale previous excitation signal */ - exc_buf_ptr = exc_buf; - exc_buf_ptr_offset = 0; - - for( k = ( Silk_define.NB_SUBFR >> 1 ); k < Silk_define.NB_SUBFR; k++ ) { - for( i = 0; i < psDec.subfr_length; i++ ) { - exc_buf_ptr[exc_buf_ptr_offset + i ] = ( short )( Silk_macros.SKP_SMULWW( psDec.exc_Q10[ i + k * psDec.subfr_length ], psPLC.prevGain_Q16[ k ] ) >> 10 ); - - } - exc_buf_ptr_offset += psDec.subfr_length; - } - /* Find the subframe with lowest energy of the last two and use that as random noise generator */ - Silk_sum_sqr_shift.SKP_Silk_sum_sqr_shift( energy1_ptr, shift1_ptr, exc_buf, 0, psDec.subfr_length ); - energy1 = energy1_ptr[0]; - shift1 = shift1_ptr[0]; - - Silk_sum_sqr_shift.SKP_Silk_sum_sqr_shift( energy2_ptr, shift2_ptr, exc_buf, psDec.subfr_length , psDec.subfr_length ); - energy2 = energy2_ptr[0]; - shift2 = shift2_ptr[0]; - - if( ( energy1 >> shift2 ) < ( energy1 >> shift2 ) ) { - /* First sub-frame has lowest energy */ - rand_ptr = psDec.exc_Q10; - rand_ptr_offset = Math.max( 0, 3 * psDec.subfr_length - RAND_BUF_SIZE ); - } else { - /* Second sub-frame has lowest energy */ - rand_ptr = psDec.exc_Q10; - rand_ptr_offset = Math.max(0, psDec.frame_length - RAND_BUF_SIZE); - } - - /* Setup Gain to random noise component */ - B_Q14 = psPLC.LTPCoef_Q14; - rand_scale_Q14 = psPLC.randScale_Q14; - - /* Setup attenuation gains */ - harm_Gain_Q15 = HARM_ATT_Q15[ Math.min( NB_ATT - 1, psDec.lossCnt ) ]; - if( psDec.prev_sigtype == Silk_define.SIG_TYPE_VOICED ) { - rand_Gain_Q15 = PLC_RAND_ATTENUATE_V_Q15[ Math.min( NB_ATT - 1, psDec.lossCnt ) ]; - } else { - rand_Gain_Q15 = PLC_RAND_ATTENUATE_UV_Q15[ Math.min( NB_ATT - 1, psDec.lossCnt ) ]; - } - - /* First Lost frame */ - if( psDec.lossCnt == 0 ) { - rand_scale_Q14 = (1 << 14 ); - - /* Reduce random noise Gain for voiced frames */ - if( psDec.prev_sigtype == Silk_define.SIG_TYPE_VOICED ) { - for( i = 0; i < Silk_define.LTP_ORDER; i++ ) { - rand_scale_Q14 -= B_Q14[ i ]; - } - rand_scale_Q14 = (short) Math.max( 3277, rand_scale_Q14 ); /* 0.2 */ - rand_scale_Q14 = ( short )( Silk_macros.SKP_SMULBB( rand_scale_Q14, psPLC.prevLTP_scale_Q14 ) >> 14 ); - } - - /* Reduce random noise for unvoiced frames with high LPC gain */ - if( psDec.prev_sigtype == Silk_define.SIG_TYPE_UNVOICED ) { - int invGain_Q30, down_scale_Q30; - int invGain_Q30_ptr[] = new int[1]; - Silk_LPC_inv_pred_gain.SKP_Silk_LPC_inverse_pred_gain( invGain_Q30_ptr, psPLC.prevLPC_Q12, psDec.LPC_order ); - invGain_Q30 = invGain_Q30_ptr[0]; - - down_scale_Q30 = Math.min( ( ( 1 << 30 ) >> LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 ); - down_scale_Q30 = Math.max( ( ( 1 << 30 ) >> LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 ); - down_scale_Q30 = ( down_scale_Q30 << LOG2_INV_LPC_GAIN_HIGH_THRES ); - - rand_Gain_Q15 = ( Silk_macros.SKP_SMULWB( down_scale_Q30, rand_Gain_Q15 ) >> 14 ); - } - } - - rand_seed = psPLC.rand_seed; - lag = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( psPLC.pitchL_Q8, 8 ); - psDec.sLTP_buf_idx = psDec.frame_length; - - /***************************/ - /* LTP synthesis filtering */ - /***************************/ - sig_Q10_ptr = sig_Q10; - sig_Q10_ptr_offset = 0; - - - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - /* Setup pointer */ - pred_lag_ptr = psDec.sLTP_Q16; - pred_lag_ptr_offset = psDec.sLTP_buf_idx - lag + Silk_define.LTP_ORDER / 2; - - for( i = 0; i < psDec.subfr_length; i++ ) { - rand_seed = Silk_SigProc_FIX.SKP_RAND( rand_seed ); - idx = ( rand_seed >> 25 ) & RAND_BUF_MASK; - - /* Unrolled loop */ -// LTP_pred_Q14 = Silk_macros.SKP_SMULWB( pred_lag_ptr[ pred_lag_ptr_offset + 0 ], B_Q14[ 0 ] ); -//TODO: array bonds check??? - LTP_pred_Q14 = Silk_macros.SKP_SMULWB( pred_lag_ptr[ pred_lag_ptr_offset + 0 ], B_Q14[ 0 ] ); - LTP_pred_Q14 = Silk_macros.SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ pred_lag_ptr_offset - 1 ], B_Q14[ 1 ] ); - LTP_pred_Q14 = Silk_macros.SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ pred_lag_ptr_offset - 2 ], B_Q14[ 2 ] ); - LTP_pred_Q14 = Silk_macros.SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ pred_lag_ptr_offset - 3 ], B_Q14[ 3 ] ); - LTP_pred_Q14 = Silk_macros.SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ pred_lag_ptr_offset - 4 ], B_Q14[ 4 ] ); - pred_lag_ptr_offset++; - - /* Generate LPC residual */ - LPC_exc_Q10 = ( Silk_macros.SKP_SMULWB( rand_ptr[rand_ptr_offset + idx ], rand_scale_Q14 ) << 2 ); /* Random noise part */ - LPC_exc_Q10 = ( LPC_exc_Q10 + Silk_SigProc_FIX.SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ) ); /* Harmonic part */ - - /* Update states */ - psDec.sLTP_Q16[ psDec.sLTP_buf_idx ] = ( LPC_exc_Q10 << 6 ); - psDec.sLTP_buf_idx++; - - /* Save LPC residual */ - sig_Q10_ptr[ sig_Q10_ptr_offset + i ] = LPC_exc_Q10; - } - sig_Q10_ptr_offset += psDec.subfr_length; - /* Gradually reduce LTP gain */ - for( j = 0; j < Silk_define.LTP_ORDER; j++ ) { - B_Q14[ j ] = (short) ( Silk_macros.SKP_SMULBB( harm_Gain_Q15, B_Q14[ j ] )>> 15 ); - } - /* Gradually reduce excitation gain */ - rand_scale_Q14 = (short) ( Silk_macros.SKP_SMULBB( rand_scale_Q14, rand_Gain_Q15 ) >> 15 ); - - /* Slowly increase pitch lag */ - psPLC.pitchL_Q8 += Silk_macros.SKP_SMULWB( psPLC.pitchL_Q8, PITCH_DRIFT_FAC_Q16 ); - psPLC.pitchL_Q8 = Math.min( psPLC.pitchL_Q8, ( Silk_macros.SKP_SMULBB( MAX_PITCH_LAG_MS, psDec.fs_kHz ) << 8 ) ); - lag = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( psPLC.pitchL_Q8, 8 ); - } - - /***************************/ - /* LPC synthesis filtering */ - /***************************/ - sig_Q10_ptr = sig_Q10; - sig_Q10_ptr_offset = 0; - /* Preload LPC coeficients to array on stack. Gives small performance gain */ - System.arraycopy(psPLC.prevLPC_Q12, 0, A_Q12_tmp, 0, psDec.LPC_order); - Silk_typedef.SKP_assert( psDec.LPC_order >= 10 ); /* check that unrolling works */ - - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - for( i = 0; i < psDec.subfr_length; i++ ){ - /* partly unrolled */ - LPC_pred_Q10 = Silk_macros.SKP_SMULWB( psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 2 ], A_Q12_tmp[ 1 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 3 ], A_Q12_tmp[ 2 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 4 ], A_Q12_tmp[ 3 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 5 ], A_Q12_tmp[ 4 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 6 ], A_Q12_tmp[ 5 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 7 ], A_Q12_tmp[ 6 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 8 ], A_Q12_tmp[ 7 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 9 ], A_Q12_tmp[ 8 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 10 ], A_Q12_tmp[ 9 ] ); - - for( j = 10; j < psDec.LPC_order; j++ ) { - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - j - 1 ], A_Q12_tmp[ j ] ); - } - /* Add prediction to LPC residual */ - sig_Q10_ptr[ sig_Q10_ptr_offset = i ] = ( sig_Q10_ptr[ sig_Q10_ptr_offset +i ] + LPC_pred_Q10 ); - - /* Update states */ - psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i ] = ( sig_Q10_ptr[sig_Q10_ptr_offset+ i ] << 4 ); - } - sig_Q10_ptr_offset += psDec.subfr_length; - /* Update LPC filter state */ - System.arraycopy(psDec.sLPC_Q14, psDec.subfr_length, psDec.sLPC_Q14, 0, Silk_define.MAX_LPC_ORDER); - } - - /* Scale with Gain */ - for( i = 0; i < psDec.frame_length; i++ ) { - signal[ signal_offset + i ] = ( short )Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( Silk_macros.SKP_SMULWW( sig_Q10[ i ], psPLC.prevGain_Q16[ Silk_define.NB_SUBFR - 1 ] ), 10 ) ); - } - - /**************************************/ - /* Update states */ - /**************************************/ - psPLC.rand_seed = rand_seed; - psPLC.randScale_Q14 = rand_scale_Q14; - for( i = 0; i < Silk_define.NB_SUBFR; i++ ) { - psDecCtrl.pitchL[ i ] = lag; - } - } - - /** - * Glues concealed frames with new good recieved frames. - * @param psDec Decoder state. - * @param psDecCtrl Decoder control. - * @param signal signal. - * @param signal_offset offset of the valid data. - * @param length length of the residual. - */ - static void SKP_Silk_PLC_glue_frames( - SKP_Silk_decoder_state psDec, /* I/O decoder state */ - SKP_Silk_decoder_control psDecCtrl, /* I/O Decoder control */ - short signal[], /* I/O signal */ - int signal_offset, - int length /* I length of residual */ - ) - { - int i, energy_shift; - int energy; - int energy_ptr[] = new int[1]; - int energy_shift_ptr[] = new int[1]; - - SKP_Silk_PLC_struct psPLC; - psPLC = psDec.sPLC; - - if( psDec.lossCnt != 0) { - /* Calculate energy in concealed residual */ - int[] conc_energy_ptr = new int[1]; - int[] conc_energy_shift_ptr = new int[1]; - Silk_sum_sqr_shift.SKP_Silk_sum_sqr_shift( conc_energy_ptr, conc_energy_shift_ptr, signal, signal_offset, length ); - psPLC.conc_energy = conc_energy_ptr[0]; - psPLC.conc_energy_shift = conc_energy_shift_ptr[0]; - - psPLC.last_frame_lost = 1; - } else { - if( psDec.sPLC.last_frame_lost != 0 ) { - /* Calculate residual in decoded signal if last frame was lost */ - Silk_sum_sqr_shift.SKP_Silk_sum_sqr_shift( energy_ptr, energy_shift_ptr, signal, signal_offset, length ); - energy = energy_ptr[0]; - energy_shift = energy_shift_ptr[0]; - - - /* Normalize energies */ - if( energy_shift > psPLC.conc_energy_shift ) { - psPLC.conc_energy = ( psPLC.conc_energy >> energy_shift - psPLC.conc_energy_shift ); - } else if( energy_shift < psPLC.conc_energy_shift ) { - energy = ( energy >> psPLC.conc_energy_shift - energy_shift ); - } - - /* Fade in the energy difference */ - if( energy > psPLC.conc_energy ) { - int frac_Q24, LZ; - int gain_Q12, slope_Q12; - - LZ = Silk_macros.SKP_Silk_CLZ32( psPLC.conc_energy ); - LZ = LZ - 1; - psPLC.conc_energy = ( psPLC.conc_energy << LZ ); - energy = ( energy >> Math.max( 24 - LZ, 0 ) ); - - frac_Q24 = ( psPLC.conc_energy / Math.max( energy, 1 ) ); - - gain_Q12 = Silk_Inlines.SKP_Silk_SQRT_APPROX( frac_Q24 ); - slope_Q12 = ( ( 1 << 12 ) - gain_Q12 / length ); - - for( i = 0; i < length; i++ ) { - signal[signal_offset + i ] = (short) ( ( gain_Q12 * signal[ signal_offset + i ] ) >> 12 ); - gain_Q12 += slope_Q12; - gain_Q12 = Math.min( gain_Q12, ( 1 << 12 ) ); - } - } - } - psPLC.last_frame_lost = 0; - - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_SDK_API.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_SDK_API.java deleted file mode 100644 index 7fd776699..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_SDK_API.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - */ -public class Silk_SDK_API -{ - static final int SILK_MAX_FRAMES_PER_PACKET = 5; -} - -/** - * Struct for TOC (Table of Contents). - * - * @author Jing Dai - * @author Dingxin Xu - */ -class SKP_Silk_TOC_struct -{ - int framesInPacket; /* Number of 20 ms frames in packet */ - int fs_kHz; /* Sampling frequency in packet */ - int inbandLBRR; /* Does packet contain LBRR information */ - int corrupt; /* Packet is corrupt */ - int[] vadFlags = new int[Silk_SDK_API.SILK_MAX_FRAMES_PER_PACKET ]; /* VAD flag for each frame in packet */ - int[] sigtypeFlags = new int[Silk_SDK_API.SILK_MAX_FRAMES_PER_PACKET ]; /* Signal type for each frame in packet */ -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_SigProc_FIX.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_SigProc_FIX.java deleted file mode 100644 index 192e81812..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_SigProc_FIX.java +++ /dev/null @@ -1,810 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -class Silk_SigProc_FIX_constants -{ - /** - * max order of the LPC analysis in schur() and k2a(). - */ - static final int SKP_Silk_MAX_ORDER_LPC = 16; /* max order of the LPC analysis in schur() and k2a() */ - /** - * max input length to the correlation. - */ - static final int SKP_Silk_MAX_CORRELATION_LENGTH = 640;/* max input length to the correlation */ - - /* Pitch estimator */ - static final int SKP_Silk_PITCH_EST_MIN_COMPLEX = 0; - static final int SKP_Silk_PITCH_EST_MID_COMPLEX = 1; - static final int SKP_Silk_PITCH_EST_MAX_COMPLEX = 2; - - /* parameter defining the size and accuracy of the piecewise linear */ - /* cosine approximatin table. */ - static final int LSF_COS_TAB_SZ_FIX = 128; - /* rom table with cosine values */ -// (to see rom table value, refer to Silk_LSF_cos_table.java) -} - -public class Silk_SigProc_FIX - extends Silk_SigProc_FIX_constants -{ - /** - * Rotate a32 right by 'rot' bits. Negative rot values result in rotating - * left. Output is 32bit int. - * - * @param a32 - * @param rot - * @return - */ - static int SKP_ROR32( int a32, int rot ) - { - if(rot <= 0) - return ((a32 << -rot) | (a32 >>> (32 + rot))); - else - return ((a32 << (32 - rot)) | (a32 >>> rot)); - } - - /* fixed point */ - - /** - * (a32 * b32) output have to be 32bit int - */ - static int SKP_MUL(int a32, int b32) - { - return a32*b32; - } - - /** - * (a32 * b32) output have to be 32bit uint. - * @param a32 - * @param b32 - * @return - */ - static long SKP_MUL_uint(long a32, long b32) - { - return a32*b32; - } - - /** - * a32 + (b32 * c32) output have to be 32bit int - * @param a32 - * @param b32 - * @param c32 - * @return - */ - static int SKP_MLA(int a32, int b32, int c32) - { - return a32 + b32*c32; - } - - /** - * a32 + (b32 * c32) output have to be 32bit uint - * @param a32 - * @param b32 - * @param c32 - * @return - */ - static long SKP_MLA_uint(long a32, long b32, long c32) - { - return a32 + b32*c32; - } - - /** - * ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int - * @param a32 - * @param b32 - * @return - */ - static int SKP_SMULTT(int a32, int b32) - { - return (((a32) >> 16) * ((b32) >> 16)); - } - - /** - * a32 + ((b32 >> 16) * (c32 >> 16)) output have to be 32bit int - * @param a32 - * @param b32 - * @param c32 - * @return - */ - static int SKP_SMLATT(int a32, int b32, int c32) - { - return (a32) + ((b32) >> 16) * ((c32) >> 16); - } - - /** - * SKP_ADD64((a64),(SKP_int64)((SKP_int32)(b16) * (SKP_int32)(c16))). - * @param a64 - * @param b16 - * @param c16 - * @return - */ - static long SKP_SMLALBB(long a64, short b16, short c16) - { - return (a64) + ((b16) * (c16)); - } - - /** - * (a32 * b32) - * @param a32 - * @param b32 - * @return - */ - static long SKP_SMULL(int a32, int b32) - { - return ((long)(a32) * /*(long)*/(b32)); - } - - // multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) - /** - * SKP_MLA(a32, b32, c32). - */ - static int SKP_MLA_ovflw(int a32, int b32, int c32) - { - return a32 + b32*c32; - } - - /** - * SKP_SMLABB(a32, b32, c32) - * @param a32 - * @param b32 - * @param c32 - * @return - */ - static int SKP_SMLABB_ovflw(int a32, int b32, int c32) - { - return ((a32) + (((short)(b32))) * ((short)(c32))); - } - /** - * SKP_SMLABT(a32, b32, c32) - * @param a32 - * @param b32 - * @param c32 - * @return - */ - static int SKP_SMLABT_ovflw(int a32, int b32, int c32) - { - return ((a32) + (((short)(b32))) * ((c32) >> 16)); - } - /** - * SKP_SMLATT(a32, b32, c32) - * @param a32 - * @param b32 - * @param c32 - * @return - */ - static int SKP_SMLATT_ovflw(int a32, int b32, int c32) - { - return (a32) + ((b32) >> 16) * ((c32) >> 16); - } - /** - * SKP_SMLAWB(a32, b32, c32) - * @param a32 - * @param b32 - * @param c32 - * @return - */ - static int SKP_SMLAWB_ovflw(int a32, int b32, int c32) - { - return ((a32) + ((((b32) >> 16) * ((short)(c32))) + ((((b32) & 0x0000FFFF) * ((short)(c32))) >> 16))); - } - /** - * SKP_SMLAWT(a32, b32, c32) - * @param a32 - * @param b32 - * @param c32 - * @return - */ - static int SKP_SMLAWT_ovflw(int a32, int b32, int c32) - { - return ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16)); - } - - /** - * ((a64)/(b32)) - * TODO: rewrite it as a set of SKP_DIV32. - */ - static long SKP_DIV64_32(long a64, int b32) - { - return a64/b32; - } - - /** - * ((int)((a32) / (b16))) - * @param a32 - * @param b16 - * @return - */ - static int SKP_DIV32_16(int a32, short b16) - { - return (((a32) / (b16))); - } - /** - * ((SKP_int32)((a32) / (b32))) - * @param a32 - * @param b32 - * @return - */ - static int SKP_DIV32(int a32, int b32) - { - return (((a32) / (b32))); - } - - // These macros enables checking for overflow in SKP_Silk_API_Debug.h - /** - * ((a) + (b)) - */ - static short SKP_ADD16(short a, short b) - { - return (short)(a+b); - } - /** - * ((a) + (b)) - * @param a - * @param b - * @return - */ - static int SKP_ADD32(int a, int b) - { - return a+b; - } - /** - * ((a) + (b)) - * @param a - * @param b - * @return - */ - static long SKP_ADD64(long a, long b) - { - return a+b; - } - - /** - * ((a) - (b)) - * @param a - * @param b - * @return - */ - static short SKP_SUB16(short a, short b) - { - return (short)(a-b); - } - /** - * ((a) - (b)) - * @param a - * @param b - * @return - */ - static int SKP_SUB32(int a, int b) - { - return a-b; - } - /** - * ((a) - (b)) - * @param a - * @param b - * @return - */ - static long SKP_SUB64(long a, long b) - { - return a-b; - } - - static int SKP_SAT8(int a) - { - return ((a) > Byte.MAX_VALUE ? Byte.MAX_VALUE : ((a) < Byte.MIN_VALUE ? Byte.MIN_VALUE : (a))); - } - - static int SKP_SAT16(int a) - { - return ((a) > Short.MAX_VALUE ? Short.MAX_VALUE : ((a) < Short.MIN_VALUE ? Short.MIN_VALUE : (a))); - } - - static long SKP_SAT32(long a) - { - return ((a) > Integer.MAX_VALUE ? Integer.MAX_VALUE : ((a) < Integer.MIN_VALUE ? Integer.MIN_VALUE : (a))); - } - - /** - * (a) - * @param a - * @return - */ - static byte SKP_CHECK_FIT8(int a) - { - return (byte)a; - } - /** - * (a) - * @param a - * @return - */ - static short SKP_CHECK_FIT16(int a) - { - return (short)a; - } - /** - * (a) - * @param a - * @return - */ - static int SKP_CHECK_FIT32(int a) - { - return a; - } - - static short SKP_ADD_SAT16(short a, short b) - { - return (short)SKP_SAT16( (a) + (b) ); - } - - static long SKP_ADD_SAT64(long a, long b) - { - if( ((a + b) & 0x8000000000000000L) == 0 ) - return ((a & b) & 0x8000000000000000L) != 0 ? Long.MIN_VALUE : a+b; - else - return ((a | b) & 0x8000000000000000L) == 0 ? Long.MAX_VALUE : a+b; - } - - static short SKP_SUB_SAT16(short a, short b) - { - return (short)SKP_SAT16( (a) - (b) ); - } - - static long SKP_SUB_SAT64(long a, long b) - { - if( ((a - b) & 0x8000000000000000L) == 0 ) - return ( a & (b^0x8000000000000000L) & 0x8000000000000000L) != 0 ? Long.MIN_VALUE : a-b; - else - return ( (a^0x8000000000000000L) & b & 0x8000000000000000L) != 0 ? Long.MAX_VALUE : a-b; - } - - /* Saturation for positive input values */ - static long SKP_POS_SAT32(long a) - { - return ((a) > Integer.MAX_VALUE ? Integer.MAX_VALUE : (a)); - } - - /* Add with saturation for positive input values */ - static byte SKP_ADD_POS_SAT8(byte a, byte b) - { - return ((a+b) & 0x80) != 0? Byte.MAX_VALUE : (byte)(a+b); - } - static short SKP_ADD_POS_SAT16(short a, short b) - { - return ((a+b) & 0x8000) != 0 ? Short.MAX_VALUE : (short)(a+b); - } - static int SKP_ADD_POS_SAT32(int a, int b) - { - return ((((a)+(b)) & 0x80000000) != 0 ? Integer.MAX_VALUE : ((a)+(b))); - } - static long SKP_ADD_POS_SAT64(long a, long b) - { - return ((((a)+(b)) & 0x8000000000000000L) != 0 ? Long.MAX_VALUE : ((a)+(b))); - } - - /** - * ((a)<<(shift)) // shift >= 0, shift < 8 - * @param a - * @param shift - * @return - */ - static byte SKP_LSHIFT8(byte a, int shift) - { - return (byte)(a<= 0, shift < 16 - * @param a - * @param shift - * @return - */ - static short SKP_LSHIFT16(short a, int shift) - { - return (short)(a<= 0, shift < 32 - * @param a - * @param shift - * @return - */ - static int SKP_LSHIFT32(int a, int shift) - { - return a<= 0, shift < 64 - * @param a - * @param shift - * @return - */ - static long SKP_LSHIFT64(long a, int shift) - { - return a<= 0, shift < 32 - * @param a - * @param shift - * @return - */ - static int SKP_LSHIFT(int a, int shift) - { - return a<>(shift)) // shift >= 0, shift < 8 - * @param a - * @param shift - * @return - */ - static byte SKP_RSHIFT8(byte a, int shift) - { - return (byte)(a>>shift); - } - /** - * ((a)>>(shift)) // shift >= 0, shift < 16 - * @param a - * @param shift - * @return - */ - static short SKP_RSHIFT16(short a, int shift) - { - return (short)(a>>shift); - } - /** - * ((a)>>(shift)) // shift >= 0, shift < 32 - * @param a - * @param shift - * @return - */ - static int SKP_RSHIFT32(int a, int shift) - { - return a>>shift; - } - /** - * ((a)>>(shift)) // shift >= 0, shift < 64 - * @param a - * @param shift - * @return - */ - static long SKP_RSHIFT64(long a, int shift) - { - return a>>shift; - } - /** - * SKP_RSHIFT32(a, shift) // shift >= 0, shift < 32 - * @param a - * @param shift - * @return - */ - static int SKP_RSHIFT(int a, int shift) - { - return a>>shift; - } - - /* saturates before shifting */ - static short SKP_LSHIFT_SAT16(short a, int shift) - { - return SKP_LSHIFT16( SKP_LIMIT_16( a, (short)(Short.MIN_VALUE>>shift), (short)(Short.MAX_VALUE>>shift) ), shift ); - } - - static int SKP_LSHIFT_SAT32(int a, int shift) - { - return SKP_LSHIFT32( SKP_LIMIT( a, Integer.MIN_VALUE>>shift, Integer.MAX_VALUE>>shift ), shift ); - } - - /** - * ((a)<<(shift)) // shift >= 0, allowed to overflow - * @param a - * @param shift - * @return - */ - static int SKP_LSHIFT_ovflw(int a, int shift) - { - return a<= 0 - * @param a - * @param shift - * @return - */ - static int SKP_LSHIFT_uint(int a, int shift) - { - return a<>(shift)) // shift >= 0 - * @param a - * @param shift - * @return - */ - static int SKP_RSHIFT_uint(int a, int shift) - { - return a>>>shift; - } - - /** - * ((a) + SKP_LSHIFT((b), (shift))) // shift >= 0 - * @param a - * @param b - * @param shift - * @return - */ - static int SKP_ADD_LSHIFT(int a, int b, int shift) - { - return a + (b<= 0 - * @param a - * @param b - * @param shift - * @return - */ - static int SKP_ADD_LSHIFT32(int a, int b, int shift) - { - return a + (b<= 0 - * @param a - * @param b - * @param shift - * @return - */ - static int SKP_ADD_LSHIFT_uint(int a, int b, int shift) - { - return a + (b<= 0 - * @param a - * @param b - * @param shift - * @return - */ - static int SKP_ADD_RSHIFT(int a, int b, int shift) - { - return a + (b>>shift); - } - /** - * SKP_ADD32((a), SKP_RSHIFT32((b), (shift))) // shift >= 0 - * @param a - * @param b - * @param shift - * @return - */ - static int SKP_ADD_RSHIFT32(int a, int b, int shift) - { - return a + (b>>shift); - } - /** - * ((a) + SKP_RSHIFT_uint((b), (shift))) // shift >= 0 - * @param a - * @param b - * @param shift - * @return - */ - static int SKP_ADD_RSHIFT_uint(int a, int b, int shift) - { - return a + (b>>>shift); - } - /** - * SKP_SUB32((a), SKP_LSHIFT32((b), (shift))) // shift >= 0 - * @param a - * @param b - * @param shift - * @return - */ - static int SKP_SUB_LSHIFT32(int a, int b, int shift) - { - return a - (b<= 0 - * @param a - * @param b - * @param shift - * @return - */ - static int SKP_SUB_RSHIFT32(int a, int b, int shift) - { - return a - (b>>shift); - } - - /* Requires that shift > 0 */ - /** - * ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1) - */ - static int SKP_RSHIFT_ROUND(int a, int shift) - { - return shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; - } - /** - * ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1) - * @param a - * @param shift - * @return - */ - static long SKP_RSHIFT_ROUND64(long a, int shift) - { - return shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; - } - - /* Number of rightshift required to fit the multiplication */ - static int SKP_NSHIFT_MUL_32_32(int a, int b) - { - return -(31- (32-Silk_macros.SKP_Silk_CLZ32(Math.abs(a)) + (32-Silk_macros.SKP_Silk_CLZ32(Math.abs(b))))); - } - static int SKP_NSHIFT_MUL_16_16(short a, short b) - { - return -(15- (16-Silk_macros.SKP_Silk_CLZ16((short)Math.abs(a)) + (16-Silk_macros.SKP_Silk_CLZ16((short)Math.abs(b))))); - } - - - static int SKP_min(int a, int b) - { - return ab ? a:b; - } - - /* Macro to convert floating-point constants to fixed-point */ - /** - * ((int)((C) * (1 << (Q)) + 0.5)) - */ - static int SKP_FIX_CONST( float C, int Q ) - { - return (int)(C * (1 << Q) + 0.5); - } - - /* SKP_min() versions with typecast in the function call */ - static int SKP_min_int(int a, int b) - { - return (((a) < (b)) ? (a) : (b)); - } - static short SKP_min_16(short a, short b) - { - return (((a) < (b)) ? (a) : (b)); - } - static int SKP_min_32(int a, int b) - { - return (((a) < (b)) ? (a) : (b)); - } - static long SKP_min_64(long a, long b) - { - return (((a) < (b)) ? (a) : (b)); - } - - /* SKP_min() versions with typecast in the function call */ - static int SKP_max_int(int a, int b) - { - return (((a) > (b)) ? (a) : (b)); - } - static short SKP_max_16(short a, short b) - { - return (((a) > (b)) ? (a) : (b)); - } - static int SKP_max_32(int a, int b) - { - return (((a) > (b)) ? (a) : (b)); - } - static long SKP_max_64(long a, long b) - { - return (((a) > (b)) ? (a) : (b)); - } - - static int SKP_LIMIT( int a, int limit1, int limit2) - { - if( limit1 > limit2 ) - return a > limit1 ? limit1 : (a < limit2 ? limit2 : a); - else - return a > limit2 ? limit2 : (a < limit1 ? limit1 : a); - } - static float SKP_LIMIT( float a, float limit1, float limit2) - { - if( limit1 > limit2 ) - return a > limit1 ? limit1 : (a < limit2 ? limit2 : a); - else - return a > limit2 ? limit2 : (a < limit1 ? limit1 : a); - } - - static int SKP_LIMIT_int( int a, int limit1, int limit2) - { - if( limit1 > limit2 ) - return a > limit1 ? limit1 : (a < limit2 ? limit2 : a); - else - return a > limit2 ? limit2 : (a < limit1 ? limit1 : a); - } - static short SKP_LIMIT_16( short a, short limit1, short limit2) - { - if( limit1 > limit2 ) - return a > limit1 ? limit1 : (a < limit2 ? limit2 : a); - else - return a > limit2 ? limit2 : (a < limit1 ? limit1 : a); - } - static int SKP_LIMIT_32( int a, int limit1, int limit2) - { - if( limit1 > limit2 ) - return a > limit1 ? limit1 : (a < limit2 ? limit2 : a); - else - return a > limit2 ? limit2 : (a < limit1 ? limit1 : a); - } - - - /** - * (((a) > 0) ? (a) : -(a)) - * Be careful, SKP_abs returns wrong when input equals to SKP_intXX_MIN - * @param a - * @return - */ - static int SKP_abs(int a) - { - return (((a) > 0) ? (a) : -(a)); - } - static int SKP_abs_int(int a) - { - return (((a) ^ ((a) >> (Integer.SIZE - 1))) - ((a) >> (Integer.SIZE - 1))); - } - static int SKP_abs_int32(int a) - { - return (((a) ^ ((a) >> 31)) - ((a) >> 31)); - } - static long SKP_abs_int64(long a) - { - return (((a) > 0) ? (a) : -(a)); - } - - static int SKP_sign(int a) - { - return ((a) > 0 ? 1 : ( (a) < 0 ? -1 : 0 )); - } - - static double SKP_sqrt(int a) - { - return Math.sqrt(a); - } - - /** - * PSEUDO-RANDOM GENERATOR - * Make sure to store the result as the seed for the next call (also in between - * frames), otherwise result won't be random at all. When only using some of the - * bits, take the most significant bits by right-shifting. Do not just mask off - * the lowest bits. - * SKP_RAND(seed) (SKP_MLA_ovflw(907633515, (seed), 196314165)) - * @param seed - * @return - */ - static int SKP_RAND(int seed) - { - return 907633515 + seed*196314165; - } - - // Add some multiplication functions that can be easily mapped to ARM. - -// SKP_SMMUL: Signed top word multiply. -// ARMv6 2 instruction cycles. -// ARMv3M+ 3 instruction cycles. use SMULL and ignore LSB registers.(except xM) -// #define SKP_SMMUL(a32, b32) (SKP_int32)SKP_RSHIFT(SKP_SMLAL(SKP_SMULWB((a32), (b32)), (a32), SKP_RSHIFT_ROUND((b32), 16)), 16) -// the following seems faster on x86 -// #define SKP_SMMUL(a32, b32) (SKP_int32)SKP_RSHIFT64(SKP_SMULL((a32), (b32)), 32) - static int SKP_SMMUL(int a32, int b32) - { - return (int)( ( (long)a32*b32 )>>32 ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_SigProc_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_SigProc_FLP.java deleted file mode 100644 index 3384cd56d..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_SigProc_FLP.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -class Silk_SigProc_FLP_constants -{ - /* Pitch estimator */ - static final int SigProc_PITCH_EST_MIN_COMPLEX = 0; - static final int SigProc_PITCH_EST_MID_COMPLEX = 1; - static final int SigProc_PITCH_EST_MAX_COMPLEX = 2; - - static final float PI = 3.1415926536f; -} - -public class Silk_SigProc_FLP - extends Silk_SigProc_FLP_constants -{ - static float SKP_min_float(float a, float b) - { - return (((a) < (b)) ? (a) : (b)); - } - static float SKP_max_float(float a, float b) - { - return (((a) > (b)) ? (a) : (b)); - } - static float SKP_abs_float(float a) - { - return Math.abs(a); - } - - static float SKP_LIMIT_float( float a, float limit1, float limit2) - { - if( limit1 > limit2 ) - return a > limit1 ? limit1 : (a < limit2 ? limit2 : a); - else - return a > limit2 ? limit2 : (a < limit1 ? limit1 : a); - } - - /* sigmoid function */ - static float SKP_sigmoid(float x) - { - return (float)(1.0 / (1.0 + Math.exp(-x))); - } - - /* floating-point to integer conversion (rounding) */ - static void SKP_float2short_array - ( - short[] out, - int out_offset, - float[] in, - int in_offset, - int length - ) - { - int k; - for (k = length-1; k >= 0; k--) - { - double x = in[in_offset+k]; - out[out_offset+k] = (short)Silk_SigProc_FIX.SKP_SAT16( (int)(( x > 0 ) ? x + 0.5 : x - 0.5) ); - } - } - - /* floating-point to integer conversion (rounding) */ - static int SKP_float2int(double x) - { - return (int)( ( x > 0 ) ? x + 0.5 : x - 0.5 ); - } - - /* integer to floating-point conversion */ - static void SKP_short2float_array - ( - float[] out, - int out_offset, - short[] in, - int in_offset, - int length - ) - { - int k; - for (k = length-1; k >= 0; k--) - { - out[out_offset+k] = in[in_offset+k]; - } - } - -//TODO: #define SKP_round(x) (SKP_float)((x)>=0 ? (SKP_int64)((x)+0.5) : (SKP_int64)((x)-0.5)) - static float SKP_round(float x) - { - return ((x)>=0 ? (long)(x+0.5) : (long)(x-0.5)); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_VAD.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_VAD.java deleted file mode 100644 index 12d4e2b03..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_VAD.java +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_VAD -{ - /** - * Initialization of the Silk VAD. - * @param psSilk_VAD Silk VAD state. - * @return return 0 if success. - */ - static int SKP_Silk_VAD_Init( /* O Return value, 0 if success */ - SKP_Silk_VAD_state psSilk_VAD /* I/O Pointer to Silk VAD state */ - ) - { - int b, ret = 0; - - /* reset state memory */ -//TODO: memset -// SKP_memset( psSilk_VAD, 0, sizeof( SKP_Silk_VAD_state ) ); - - /* init noise levels */ - /* Initialize array with approx pink noise levels (psd proportional to inverse of frequency) */ - for( b = 0; b < Silk_define.VAD_N_BANDS; b++ ) - { - psSilk_VAD.NoiseLevelBias[ b ] = Math.max( Silk_define.VAD_NOISE_LEVELS_BIAS / ( b + 1 ), 1 ); - } - - /* Initialize state */ - for( b = 0; b < Silk_define.VAD_N_BANDS; b++ ) - { - psSilk_VAD.NL[ b ] = 100 * psSilk_VAD.NoiseLevelBias[ b ]; - psSilk_VAD.inv_NL[ b ] = Silk_typedef.SKP_int32_MAX / psSilk_VAD.NL[ b ]; - } - psSilk_VAD.counter = 15; - - /* init smoothed energy-to-noise ratio*/ - for( b = 0; b < Silk_define.VAD_N_BANDS; b++ ) { - psSilk_VAD.NrgRatioSmth_Q8[ b ] = 100 * 256; /* 100 * 256 --> 20 dB SNR */ - } - - return( ret ); - } - - /* Weighting factors for tilt measure */ - static int[] tiltWeights = { 30000, 6000, -12000, -12000 }; - - /** - * Get the speech activity level in Q8. - * @param psSilk_VAD Silk VAD state. - * @param pSA_Q8 Speech activity level in Q8. - * @param pSNR_dB_Q7 SNR for current frame in Q7. - * @param pQuality_Q15 Smoothed SNR for each band. - * @param pTilt_Q15 Smoothed SNR for each band. - * @param pIn PCM input[framelength]. - * @param pIn_offset offset of valid data. - * @param framelength Input frame length. - * @return Return value, 0 if success. - */ - static int SKP_Silk_VAD_GetSA_Q8( /* O Return value, 0 if success */ - SKP_Silk_VAD_state psSilk_VAD, /* I/O Silk VAD state */ - int[] pSA_Q8, /* O Speech activity level in Q8 */ - int[] pSNR_dB_Q7, /* O SNR for current frame in Q7 */ - int[] pQuality_Q15, /* O Smoothed SNR for each band */ - int[] pTilt_Q15, /* O current frame's frequency tilt */ - short[] pIn, /* I PCM input [framelength] */ - int pIn_offset, - int framelength /* I Input frame length */ - ) - { - int SA_Q15, input_tilt; - int[] scratch = new int[ 3 * Silk_define.MAX_FRAME_LENGTH / 2 ]; - int decimated_framelength, dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s; - int sumSquared=0, smooth_coef_Q16; - short HPstateTmp; - - short[][] X = new short[ Silk_define.VAD_N_BANDS ][ Silk_define.MAX_FRAME_LENGTH / 2 ]; - int[] Xnrg = new int[ Silk_define.VAD_N_BANDS ]; - int[] NrgToNoiseRatio_Q8 = new int[ Silk_define.VAD_N_BANDS ]; - int speech_nrg, x_tmp; - int ret = 0; - - /* Safety checks */ - assert( Silk_define.VAD_N_BANDS == 4 ); - assert( Silk_define.MAX_FRAME_LENGTH >= framelength ); - assert( framelength <= 512 ); - - /***********************/ - /* Filter and Decimate */ - /***********************/ - /* 0-8 kHz to 0-4 kHz and 4-8 kHz */ - Silk_ana_filt_bank_1.SKP_Silk_ana_filt_bank_1( pIn,pIn_offset, psSilk_VAD.AnaState,0, X[ 0 ],0, X[ 3 ],0, scratch, framelength ); - - /* 0-4 kHz to 0-2 kHz and 2-4 kHz */ - Silk_ana_filt_bank_1.SKP_Silk_ana_filt_bank_1( X[ 0 ],0, psSilk_VAD.AnaState1,0, X[ 0 ],0, X[ 2 ],0, scratch, framelength>>1 ); - - /* 0-2 kHz to 0-1 kHz and 1-2 kHz */ - Silk_ana_filt_bank_1.SKP_Silk_ana_filt_bank_1( X[ 0 ],0, psSilk_VAD.AnaState2,0, X[ 0 ],0, X[ 1 ],0, scratch, framelength>>2 ); - - /*********************************************/ - /* HP filter on lowest band (differentiator) */ - /*********************************************/ - decimated_framelength = framelength >> 3; - X[ 0 ][ decimated_framelength - 1 ] = (short)( X[ 0 ][ decimated_framelength - 1 ] >> 1 ); - HPstateTmp = X[ 0 ][ decimated_framelength - 1 ]; - for( i = decimated_framelength - 1; i > 0; i-- ) - { - X[ 0 ][ i - 1 ] = (short)( X[ 0 ][ i - 1 ] >> 1 ); - X[ 0 ][ i ] -= X[ 0 ][ i - 1 ]; - } - X[ 0 ][ 0 ] -= psSilk_VAD.HPstate; - psSilk_VAD.HPstate = HPstateTmp; - - /*************************************/ - /* Calculate the energy in each band */ - /*************************************/ - for( b = 0; b < Silk_define.VAD_N_BANDS; b++ ) - { - /* Find the decimated framelength in the non-uniformly divided bands */ - decimated_framelength = framelength >> Math.min( Silk_define.VAD_N_BANDS - b, Silk_define.VAD_N_BANDS - 1); - - /* Split length into subframe lengths */ - dec_subframe_length = decimated_framelength >> Silk_define.VAD_INTERNAL_SUBFRAMES_LOG2; - dec_subframe_offset = 0; - - /* Compute energy per sub-frame */ - /* initialize with summed energy of last subframe */ - Xnrg[ b ] = psSilk_VAD.XnrgSubfr[ b ]; - for( s = 0; s < Silk_define.VAD_INTERNAL_SUBFRAMES; s++ ) - { - sumSquared = 0; - for( i = 0; i < dec_subframe_length; i++ ) - { - /* The energy will be less than dec_subframe_length * ( SKP_int16_MIN / 8 )^2. */ - /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */ - x_tmp = X[ b ][ i + dec_subframe_offset ] >> 3; - sumSquared = Silk_macros.SKP_SMLABB( sumSquared, x_tmp, x_tmp ); - - /* Safety check */ - assert( sumSquared >= 0 ); - } - - /* add/saturate summed energy of current subframe */ - if( s < Silk_define.VAD_INTERNAL_SUBFRAMES - 1 ) - { - Xnrg[ b ] = Silk_SigProc_FIX.SKP_ADD_POS_SAT32( Xnrg[ b ], sumSquared ); - } - else - { - /* look-ahead subframe */ - Xnrg[ b ] = Silk_SigProc_FIX.SKP_ADD_POS_SAT32( Xnrg[ b ], sumSquared>>1 ); - } - - dec_subframe_offset += dec_subframe_length; - } - psSilk_VAD.XnrgSubfr[ b ] = sumSquared; - } - - /********************/ - /* Noise estimation */ - /********************/ - SKP_Silk_VAD_GetNoiseLevels( Xnrg, psSilk_VAD ); - - /***********************************************/ - /* Signal-plus-noise to noise ratio estimation */ - /***********************************************/ - sumSquared = 0; - input_tilt = 0; - for( b = 0; b < Silk_define.VAD_N_BANDS; b++ ) - { - speech_nrg = Xnrg[ b ] - psSilk_VAD.NL[ b ]; - if( speech_nrg > 0 ) - { - /* Divide, with sufficient resolution */ - if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) - { - NrgToNoiseRatio_Q8[ b ] = ( Xnrg[ b ] << 8 ) / ( psSilk_VAD.NL[ b ] + 1 ); - } - else - { - NrgToNoiseRatio_Q8[ b ] = Xnrg[ b ] / ( ( psSilk_VAD.NL[ b ] >> 8 ) + 1 ); - } - - /* Convert to log domain */ - SNR_Q7 = Silk_lin2log.SKP_Silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128; - - /* Sum-of-squares */ - sumSquared = Silk_macros.SKP_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */ - - /* Tilt measure */ - if( speech_nrg < ( 1 << 20 ) ) { - /* Scale down SNR value for small subband speech energies */ - SNR_Q7 = Silk_macros.SKP_SMULWB( Silk_Inlines.SKP_Silk_SQRT_APPROX( speech_nrg ) << 6, SNR_Q7 ); - } - input_tilt = Silk_macros.SKP_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 ); - } - else - { - NrgToNoiseRatio_Q8[ b ] = 256; - } - } - - /* Mean-of-squares */ - sumSquared = sumSquared / Silk_define.VAD_N_BANDS; /* Q14 */ - - /* Root-mean-square approximation, scale to dBs, and write to output pointer */ - pSNR_dB_Q7[0] = ( short )( 3 * Silk_Inlines.SKP_Silk_SQRT_APPROX( sumSquared ) ); /* Q7 */ - - /*********************************/ - /* Speech Probability Estimation */ - /*********************************/ - SA_Q15 = Silk_sigm_Q15.SKP_Silk_sigm_Q15( Silk_macros.SKP_SMULWB( Silk_define.VAD_SNR_FACTOR_Q16, pSNR_dB_Q7[0] ) - Silk_define.VAD_NEGATIVE_OFFSET_Q5 ); - - /**************************/ - /* Frequency Tilt Measure */ - /**************************/ - pTilt_Q15[0] = ( Silk_sigm_Q15.SKP_Silk_sigm_Q15( input_tilt ) - 16384 ) << 1; - - /**************************************************/ - /* Scale the sigmoid output based on power levels */ - /**************************************************/ - speech_nrg = 0; - for( b = 0; b < Silk_define.VAD_N_BANDS; b++ ) - { - /* Accumulate signal-without-noise energies, higher frequency bands have more weight */ - speech_nrg += ( b + 1 ) * ( ( Xnrg[ b ] - psSilk_VAD.NL[ b ] ) >> 4 ); - } - - /* Power scaling */ - if( speech_nrg <= 0 ) - { - SA_Q15 = SA_Q15 >> 1; - } - else if( speech_nrg < 32768 ) - { - /* square-root */ - speech_nrg = Silk_Inlines.SKP_Silk_SQRT_APPROX( speech_nrg << 15 ); - SA_Q15 = Silk_macros.SKP_SMULWB( 32768 + speech_nrg, SA_Q15 ); - } - - /* Copy the resulting speech activity in Q8 to *pSA_Q8 */ - pSA_Q8[0] = Math.min( SA_Q15 >> 7, Silk_typedef.SKP_uint8_MAX ); - - /***********************************/ - /* Energy Level and SNR estimation */ - /***********************************/ - /* smoothing coefficient */ - smooth_coef_Q16 = Silk_macros.SKP_SMULWB( Silk_define.VAD_SNR_SMOOTH_COEF_Q18, Silk_macros.SKP_SMULWB( SA_Q15, SA_Q15 ) ); - for( b = 0; b < Silk_define.VAD_N_BANDS; b++ ) - { - /* compute smoothed energy-to-noise ratio per band */ - psSilk_VAD.NrgRatioSmth_Q8[ b ] = Silk_macros.SKP_SMLAWB( psSilk_VAD.NrgRatioSmth_Q8[ b ], - NrgToNoiseRatio_Q8[ b ] - psSilk_VAD.NrgRatioSmth_Q8[ b ], smooth_coef_Q16 ); - - /* signal to noise ratio in dB per band */ - SNR_Q7 = 3 * ( Silk_lin2log.SKP_Silk_lin2log( psSilk_VAD.NrgRatioSmth_Q8[b] ) - 8 * 128 ); - /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */ - pQuality_Q15[ b ] = Silk_sigm_Q15.SKP_Silk_sigm_Q15( ( SNR_Q7 - 16 * 128 ) >> 4 ); - } - - return( ret ); - } - - /** - * Noise level estimation. - * @param pX subband energies. - * @param psSilk_VAD Silk VAD state. - */ - static void SKP_Silk_VAD_GetNoiseLevels - ( - int[] pX, /* I subband energies */ - SKP_Silk_VAD_state psSilk_VAD /* I/O Pointer to Silk VAD state */ - ) - { - int k; - int nl, nrg, inv_nrg; - int coef, min_coef; - - /* Initially faster smoothing */ - if( psSilk_VAD.counter < 1000 ) - { /* 1000 = 20 sec */ - min_coef = Silk_typedef.SKP_int16_MAX / ( ( psSilk_VAD.counter >> 4 ) + 1 ); - } - else - { - min_coef = 0; - } - - for( k = 0; k < Silk_define.VAD_N_BANDS; k++ ) - { - /* Get old noise level estimate for current band */ - nl = psSilk_VAD.NL[ k ]; - assert( nl >= 0 ); - - /* Add bias */ - nrg = Silk_SigProc_FIX.SKP_ADD_POS_SAT32( pX[ k ], psSilk_VAD.NoiseLevelBias[ k ] ); - assert( nrg > 0 ); - - /* Invert energies */ - inv_nrg = Silk_typedef.SKP_int32_MAX / nrg; - assert( inv_nrg >= 0 ); - - /* Less update when subband energy is high */ - if( nrg > nl<<3 ) - { - coef = Silk_define.VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3; - } - else if( nrg < nl ) - { - coef = Silk_define.VAD_NOISE_LEVEL_SMOOTH_COEF_Q16; - } - else - { - coef = Silk_macros.SKP_SMULWB( Silk_macros.SKP_SMULWW( inv_nrg, nl ), Silk_define.VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 << 1 ); - } - - /* Initially faster smoothing */ - coef = Math.max( coef, min_coef ); - - /* Smooth inverse energies */ - psSilk_VAD.inv_NL[ k ] = Silk_macros.SKP_SMLAWB( psSilk_VAD.inv_NL[ k ], inv_nrg - psSilk_VAD.inv_NL[ k ], coef ); - assert( psSilk_VAD.inv_NL[ k ] >= 0 ); - - /* Compute noise level by inverting again */ - nl = Silk_typedef.SKP_int32_MAX / psSilk_VAD.inv_NL[ k ]; - assert( nl >= 0 ); - - /* Limit noise levels (guarantee 7 bits of head room) */ - nl = Math.min( nl, 0x00FFFFFF ); - - /* Store as part of state */ - psSilk_VAD.NL[ k ] = nl; - } - - /* Increment frame counter */ - psSilk_VAD.counter++; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_VQ_nearest_neighbor_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_VQ_nearest_neighbor_FLP.java deleted file mode 100644 index 09db674fa..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_VQ_nearest_neighbor_FLP.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Dingxin Xu - */ -public class Silk_VQ_nearest_neighbor_FLP -{ - /** - * entropy constrained MATRIX-weighted VQ, for a single input data vector. - * @param ind Index of best codebook vector - * @param rate_dist Best weighted quant. error + mu * rate - * @param in Input vector to be quantized - * @param W Weighting matrix - * @param cb Codebook - * @param cl_Q6 Code length for each codebook vector - * @param mu Tradeoff between WSSE and rate - * @param L Number of vectors in codebook - */ - static void SKP_Silk_VQ_WMat_EC_FLP( - int []ind, /* O Index of best codebook vector */ - int ind_offset, - float []rate_dist, /* O Best weighted quant. error + mu * rate */ - final float []in, /* I Input vector to be quantized */ - int in_offset, - final float []W, /* I Weighting matrix */ - int W_offset, - final short []cb, /* I Codebook */ - final short []cl_Q6, /* I Code length for each codebook vector */ - final float mu, /* I Tradeoff between WSSE and rate */ - final int L /* I Number of vectors in codebook */ - ) - { -// SKP_int k; -// SKP_float sum1; -// SKP_float diff[ 5 ]; -// const SKP_int16 *cb_row; - int k; - float sum1; - float diff[] = new float[5]; - final short []cb_row; - int cb_row_offset = 0; - - /* Loop over codebook */ -// *rate_dist = SKP_float_MAX; - rate_dist[0] = Float.MAX_VALUE; - - cb_row = cb; - cb_row_offset = 0; - - for( k = 0; k < L; k++ ) { - /* Calc difference between in vector and cbk vector */ - diff[ 0 ] = in[ in_offset + 0 ] - cb_row[ 0 ] * Silk_define_FLP.Q14_CONVERSION_FAC; - diff[ 1 ] = in[ in_offset + 1 ] - cb_row[ 1 ] * Silk_define_FLP.Q14_CONVERSION_FAC; - diff[ 2 ] = in[ in_offset + 2 ] - cb_row[ 2 ] * Silk_define_FLP.Q14_CONVERSION_FAC; - diff[ 3 ] = in[ in_offset + 3 ] - cb_row[ 3 ] * Silk_define_FLP.Q14_CONVERSION_FAC; - diff[ 4 ] = in[ in_offset + 4 ] - cb_row[ 4 ] * Silk_define_FLP.Q14_CONVERSION_FAC; - - /* Weighted rate */ - sum1 = mu * cl_Q6[ k ] / 64.0f; - - /* Add weighted quantization error, assuming W is symmetric */ - /* first row of W */ - sum1 += diff[ 0 ] * ( W[ W_offset + 0 ] * diff[ 0 ] + - 2.0f * ( W[ W_offset + 1 ] * diff[ 1 ] + - W[ W_offset + 2 ] * diff[ 2 ] + - W[ W_offset + 3 ] * diff[ 3 ] + - W[ W_offset + 4 ] * diff[ 4 ] ) ); - - /* second row of W */ - sum1 += diff[ 1 ] * ( W[ W_offset + 6 ] * diff[ 1 ] + - 2.0f * ( W[ W_offset + 7 ] * diff[ 2 ] + - W[ W_offset + 8 ] * diff[ 3 ] + - W[ W_offset + 9 ] * diff[ 4 ] ) ); - - /* third row of W */ - sum1 += diff[ 2 ] * ( W[ W_offset + 12 ] * diff[ 2 ] + - 2.0f * ( W[ W_offset + 13 ] * diff[ 3 ] + - W[ W_offset + 14 ] * diff[ 4 ] ) ); - - /* fourth row of W */ - sum1 += diff[ 3 ] * ( W[ W_offset + 18 ] * diff[ 3 ] + - 2.0f * ( W[ W_offset + 19 ] * diff[ 4 ] ) ); - - /* last row of W */ - sum1 += diff[ 4 ] * ( W[ W_offset + 24 ] * diff[ 4 ] ); - - /* find best */ - if( sum1 < rate_dist[0] ) { - rate_dist[0] = sum1; - ind[ind_offset + 0] = k; - } - - /* Go to next cbk vector */ - cb_row_offset += Silk_define.LTP_ORDER; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_allpass_int.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_allpass_int.java deleted file mode 100644 index d04b7f295..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_allpass_int.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * First-order allpass filter with - * transfer function: - * - * A + Z^(-1) - * H(z) = ------------ - * 1 + A*Z^(-1) - * - * Implemented using minimum multiplier filter design. - * - * Reference: http://www.univ.trieste.it/~ramponi/teaching/ - * DSP/materiale/Ch6(2).pdf - * - * @author Dingxin Xu - */ -public class Silk_allpass_int -{ - /** - * First-order allpass filter. - * @param in Q25 input signal [len] - * @param in_offset offset of valid data. - * @param S Q25 state [1] - * @param S_offset offset of valid data. - * @param A Q15 coefficient (0 <= A < 32768) - * @param out Q25 output signal [len] - * @param out_offset offset of valid data. - * @param len Number of samples - */ - static void SKP_Silk_allpass_int( - final int []in, /* I: Q25 input signal [len] */ - int in_offset, - int []S, /* I/O: Q25 state [1] */ - int S_offset, - int A, /* I: Q15 coefficient (0 <= A < 32768) */ - int []out, /* O: Q25 output signal [len] */ - int out_offset, - final int len /* I: Number of samples */ - ) - { - int Y2, X2, S0; - int k; - - S0 = S[ S_offset+ 0 ]; - for( k = len - 1; k >= 0; k-- ) { - Y2 = in[in_offset + 0] - S0; - X2 = ( Y2 >> 15 ) * A + ( ( ( Y2 & 0x00007FFF ) * A ) >> 15 ); - ( out[out_offset++]) = S0 + X2; - S0 = in[in_offset++] + X2; - } - S[ S_offset + 0 ] = S0; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_allpass_int_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_allpass_int_FLP.java deleted file mode 100644 index 9c7609b44..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_allpass_int_FLP.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * first-order allpass filter. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_allpass_int_FLP -{ - /** - * first-order allpass filter. - * @param in input signal [len]. - * @param in_offset offset of valid data. - * @param S I/O: state [1]. - * @param S_offset offset of valid data. - * @param A coefficient (0 <= A < 1). - * @param out output signal [len]. - * @param out_offset offset of valid data. - * @param len number of samples. - */ -//TODO:float or double ??? - static void SKP_Silk_allpass_int_FLP - ( - float[] in, /* I: input signal [len] */ - int in_offset, - float[] S, /* I/O: state [1] */ - int S_offset, - float A, /* I: coefficient (0 <= A < 1) */ - float[] out, /* O: output signal [len] */ - int out_offset, - final int len /* I: number of samples */ - ) - { - float Y2, X2, S0; - int k; - - S0 = S[ S_offset ]; - for ( k = len-1; k >= 0; k-- ) - { - Y2 = in[in_offset] - S0; - X2 = Y2 * A; - out[out_offset++] = S0 + X2; - S0 = in[in_offset++] + X2; - } - S[ S_offset ] = S0; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_ana_filt_bank_1.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_ana_filt_bank_1.java deleted file mode 100644 index baa893fcb..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_ana_filt_bank_1.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Split signal into two decimated bands using first-order allpass filters. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_ana_filt_bank_1 -{ - /* Coefficients for 2-band filter bank based on first-order allpass filters */ - // old - static short[] A_fb1_20 = { 5394 << 1 }; - static short[] A_fb1_21 = { (short)(20623 << 1) }; /* wrap-around to negative number is intentional */ - - /** - * Split signal into two decimated bands using first-order allpass filters. - * @param in Input signal [N]. - * @param in_offset offset of valid data. - * @param S State vector [2]. - * @param S_offset offset of valid data. - * @param outL Low band [N/2]. - * @param outL_offset offset of valid data. - * @param outH High band [N/2]. - * @param outH_offset offset of valid data. - * @param scratch Scratch memory [3*N/2]. - * @param N Number of input samples. - */ - static void SKP_Silk_ana_filt_bank_1 - ( - short[] in, /* I: Input signal [N] */ - int in_offset, - int[] S, /* I/O: State vector [2] */ - int S_offset, - short[] outL, /* O: Low band [N/2] */ - int outL_offset, - short[] outH, /* O: High band [N/2] */ - int outH_offset, - int[] scratch, /* I: Scratch memory [3*N/2] */ // todo: remove - no longer used - final int N /* I: Number of input samples */ - ) - { - int k, N2 = N >> 1; - int in32, X, Y, out_1, out_2; - - /* Internal variables and state are in Q10 format */ - for( k = 0; k < N2; k++ ) - { - /* Convert to Q10 */ - in32 = in[ in_offset + 2 * k ] << 10; - - /* All-pass section for even input sample */ - Y = in32 - S[ S_offset + 0 ]; - X = Silk_macros.SKP_SMLAWB( Y, Y, A_fb1_21[ 0 ] ); - out_1 = S[ S_offset + 0 ] + X; - S[ S_offset + 0 ] = in32 + X; - - /* Convert to Q10 */ - in32 = in[ in_offset + 2 * k + 1 ] << 10; - - /* All-pass section for odd input sample, and add to output of previous section */ - Y = in32 - S[ S_offset + 1 ]; - X = Silk_macros.SKP_SMULWB( Y, A_fb1_20[ 0 ] ); - out_2 = S[ S_offset + 1 ] + X; - S[ S_offset + 1 ] = in32 + X; - - /* Add/subtract, convert back to int16 and store to output */ - outL[ outL_offset + k ] = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( out_2 + out_1, 11 ) ); - outH[ outH_offset + k ] = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( out_2 - out_1, 11 ) ); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_apply_sine_window_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_apply_sine_window_FLP.java deleted file mode 100644 index b89e2e574..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_apply_sine_window_FLP.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Apply sine window to signal vector. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_apply_sine_window_FLP -{ - /** - * Apply sine window to signal vector. - * Window types: - * 0 -> sine window from 0 to pi. - * 1 -> sine window from 0 to pi/2. - * 2 -> sine window from pi/2 to pi. - * - * @param px_win Pointer to windowed signal. - * @param px_win_offset offset of valid data. - * @param px Pointer to input signal. - * @param px_offset offset of valid data. - * @param win_type Selects a window type. - * @param length Window length, multiple of 4. - */ -//TODO float or double - static void SKP_Silk_apply_sine_window_FLP( - float px_win[], /* O Pointer to windowed signal */ - int px_win_offset, - float px[], /* I Pointer to input signal */ - int px_offset, - final int win_type, /* I Selects a window type */ - final int length /* I Window length, multiple of 4 */ - ) - { - int k; - float freq, c, S0, S1; - - /* Length must be multiple of 4 */ - assert( ( length & 3 ) == 0 ); - - freq = Silk_SigProc_FLP.PI / ( length + 1 ); - if( win_type == 0 ) - { - freq = 2.0f * freq; - } - - /* Approximation of 2 * cos(f) */ - c = 2.0f - freq * freq; - - /* Initialize state */ - if( win_type < 2 ) - { - /* Start from 0 */ - S0 = 0.0f; - /* Approximation of sin(f) */ - S1 = freq; - } - else - { - /* Start from 1 */ - S0 = 1.0f; - /* Approximation of cos(f) */ - S1 = 0.5f * c; - } - - /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */ - /* 4 samples at a time */ - for( k = 0; k < length; k += 4 ) - { - px_win[ px_win_offset + k + 0 ] = px[ px_offset + k + 0 ] * 0.5f * ( S0 + S1 ); - px_win[ px_win_offset + k + 1 ] = px[ px_offset + k + 1 ] * S1; - S0 = c * S1 - S0; - px_win[ px_win_offset + k + 2 ] = px[ px_offset + k + 2 ] * 0.5f * ( S1 + S0 ); - px_win[ px_win_offset + k + 3 ] = px[ px_offset + k + 3 ] * S0; - S1 = c * S0 - S1; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_autocorrelation_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_autocorrelation_FLP.java deleted file mode 100644 index a12689763..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_autocorrelation_FLP.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * compute autocorrelation. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_autocorrelation_FLP -{ - /** - * compute autocorrelation. - * @param results result (length correlationCount) - * @param results_offset offset of valid data. - * @param inputData input data to correlate - * @param inputData_offset offset of valid data. - * @param inputDataSize length of input - * @param correlationCount number of correlation taps to compute - */ - //TODO: float or double??? - static void SKP_Silk_autocorrelation_FLP( - float[] results, /* O result (length correlationCount) */ - int results_offset, - float[] inputData, /* I input data to correlate */ - int inputData_offset, - int inputDataSize, /* I length of input */ - int correlationCount /* I number of correlation taps to compute */ - ) - { - int i; - - if ( correlationCount > inputDataSize ) - { - correlationCount = inputDataSize; - } - - for( i = 0; i < correlationCount; i++ ) - { - results[ results_offset+i ] = (float)Silk_inner_product_FLP.SKP_Silk_inner_product_FLP( inputData,inputData_offset, inputData,inputData_offset + i, inputDataSize - i ); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_biquad.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_biquad.java deleted file mode 100644 index 0778e1f0c..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_biquad.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Second order ARMA filter - * Can handle slowly varying filter coefficients - * - * @author Jing Dai - */ -public class Silk_biquad -{ - /** - * Second order ARMA filter - * Can handle slowly varying filter coefficients - * @param in input signal - * @param in_offset offset of valid data. - * @param B MA coefficients, Q13 [3] - * @param A AR coefficients, Q13 [2] - * @param S state vector [2] - * @param out output signal - * @param out_offset offset of valid data. - * @param len signal length - */ - static void SKP_Silk_biquad( - short []in, /* I: input signal */ - int in_offset, - short []B, /* I: MA coefficients, Q13 [3] */ - short []A, /* I: AR coefficients, Q13 [2] */ - int []S, /* I/O: state vector [2] */ - short []out, /* O: output signal */ - int out_offset, - final int len /* I: signal length */ - ) - { - int k, in16; - int A0_neg, A1_neg, S0, S1, out32, tmp32; - - S0 = S[ 0 ]; - S1 = S[ 1 ]; - A0_neg = -A[ 0 ]; - A1_neg = -A[ 1 ]; - for( k = 0; k < len; k++ ) { - /* S[ 0 ], S[ 1 ]: Q13 */ - in16 = in[ in_offset + k ]; - out32 = Silk_macros.SKP_SMLABB( S0, in16, B[ 0 ] ); - - S0 = Silk_macros.SKP_SMLABB( S1, in16, B[ 1 ] ); - S0 += ( Silk_macros.SKP_SMULWB( out32, A0_neg ) << 3 ); - - - S1 = ( Silk_macros.SKP_SMULWB( out32, A1_neg ) << 3 ); - S1 = Silk_macros.SKP_SMLABB( S1, in16, B[ 2 ] ); - tmp32 = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( out32, 13 ) + 1; - out[ out_offset + k ] = (short)Silk_SigProc_FIX.SKP_SAT16( tmp32 ); - } - S[ 0 ] = S0; - S[ 1 ] = S1; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_biquad_alt.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_biquad_alt.java deleted file mode 100644 index 707c60a20..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_biquad_alt.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Second order ARMA filter, alternative implementation. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_biquad_alt -{ - /** - * Second order ARMA filter, alternative implementation. - * @param in Input signal. - * @param in_offset offset of valid data. - * @param B_Q28 MA coefficients [3]. - * @param A_Q28 AR coefficients [2]. - * @param S State vector [2]. - * @param out Output signal. - * @param out_offset offset of valid data. - * @param len Signal length (must be even). - */ - static void SKP_Silk_biquad_alt( - short[] in, /* I: Input signal */ - int in_offset, - int[] B_Q28, /* I: MA coefficients [3] */ - int[] A_Q28, /* I: AR coefficients [2] */ - int[] S, /* I/O: State vector [2] */ - short[] out, /* O: Output signal */ - int out_offset, - final int len /* I: Signal length (must be even) */ - ) - { - /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */ - int k; - int inval, A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14; - - /* Negate A_Q28 values and split in two parts */ - A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */ - A0_U_Q28 = ( -A_Q28[ 0 ] ) >> 14; /* upper part */ - A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */ - A1_U_Q28 = ( -A_Q28[ 1 ] ) >> 14; /* upper part */ - - for( k = 0; k < len; k++ ) - { - /* S[ 0 ], S[ 1 ]: Q12 */ - inval = in[ in_offset+k ]; - out32_Q14 = Silk_macros.SKP_SMLAWB( S[ 0 ], B_Q28[ 0 ], inval ) << 2; - - S[ 0 ] = S[1] + ( Silk_macros.SKP_SMULWB( out32_Q14, A0_L_Q28 ) >> 14 ); - S[ 0 ] = Silk_macros.SKP_SMLAWB( S[ 0 ], out32_Q14, A0_U_Q28 ); - S[ 0 ] = Silk_macros.SKP_SMLAWB( S[ 0 ], B_Q28[ 1 ], inval); - - S[ 1 ] = Silk_macros.SKP_SMULWB( out32_Q14, A1_L_Q28 ) >> 14; - S[ 1 ] = Silk_macros.SKP_SMLAWB( S[ 1 ], out32_Q14, A1_U_Q28 ); - S[ 1 ] = Silk_macros.SKP_SMLAWB( S[ 1 ], B_Q28[ 2 ], inval ); - - /* Scale back to Q0 and saturate */ - out[ out_offset+k ] = (short)Silk_SigProc_FIX.SKP_SAT16( ( out32_Q14 >> 14 ) + 2 ); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_burg_modified_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_burg_modified_FLP.java deleted file mode 100644 index d4f24f07d..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_burg_modified_FLP.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Calculates the reflection coefficients from the input vector - * Input vector contains nb_subfr sub vectors of length L_sub + D - * - * @author Dingxin Xu - */ -public class Silk_burg_modified_FLP -{ - static final int MAX_FRAME_SIZE = 544; // subfr_length * nb_subfr = ( 0.005 * 24000 + 16 ) * 4 = 544 - static final int MAX_NB_SUBFR = 4; - - /** - * Compute reflection coefficients from input signal. - * @param A prediction coefficients (length order). - * @param x input signal, length: nb_subfr*(D+L_sub). - * @param x_offset offset of valid data. - * @param subfr_length input signal subframe length (including D preceeding samples). - * @param nb_subfr number of subframes stacked in x. - * @param WhiteNoiseFrac fraction added to zero-lag autocorrelation. - * @param D order. - * @return - */ - static float SKP_Silk_burg_modified_FLP( /* O returns residual energy */ - float A[], /* O prediction coefficients (length order) */ - final float x[], /* I input signal, length: nb_subfr*(D+L_sub) */ - int x_offset, - final int subfr_length, /* I input signal subframe length (including D preceeding samples) */ - final int nb_subfr, /* I number of subframes stacked in x */ - final float WhiteNoiseFrac, /* I fraction added to zero-lag autocorrelation */ - final int D /* I order */ - ) - { - int k, n, s; - double C0, num, nrg_f, nrg_b, rc, Atmp, tmp1, tmp2; - float []x_ptr; - int x_ptr_offset; - double C_first_row[] = new double [ Silk_SigProc_FIX.SKP_Silk_MAX_ORDER_LPC ], - C_last_row[] = new double [ Silk_SigProc_FIX.SKP_Silk_MAX_ORDER_LPC ]; - double CAf[] = new double [ Silk_SigProc_FIX.SKP_Silk_MAX_ORDER_LPC + 1 ], - CAb[] = new double [ Silk_SigProc_FIX.SKP_Silk_MAX_ORDER_LPC + 1 ]; - double Af[] = new double [ Silk_SigProc_FIX.SKP_Silk_MAX_ORDER_LPC ]; - - assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE ); - assert( nb_subfr <= MAX_NB_SUBFR ); - - /* Compute autocorrelations, added over subframes */ - C0 = Silk_energy_FLP.SKP_Silk_energy_FLP( x, x_offset, nb_subfr * subfr_length ); - for( s = 0; s < nb_subfr; s++ ) { - x_ptr = x; - x_ptr_offset = x_offset + s * subfr_length; - for( n = 1; n < D + 1; n++ ) { - C_first_row[ n - 1 ] += Silk_inner_product_FLP.SKP_Silk_inner_product_FLP( x_ptr, x_ptr_offset, - x_ptr, x_ptr_offset + n, subfr_length - n ); - } - } - System.arraycopy(C_first_row, 0, C_last_row, 0, Silk_SigProc_FIX.SKP_Silk_MAX_ORDER_LPC); - - /* Initialize */ - CAb[ 0 ] = CAf[ 0 ] = C0 + WhiteNoiseFrac * C0 + 1e-9f; - - for( n = 0; n < D; n++ ) { - /* Update first row of correlation matrix (without first element) */ - /* Update last row of correlation matrix (without last element, stored in reversed order) */ - /* Update C * Af */ - /* Update C * flipud(Af) (stored in reversed order) */ - for( s = 0; s < nb_subfr; s++ ) { - x_ptr = x; - x_ptr_offset = x_offset + s * subfr_length; - tmp1 = x_ptr[ x_ptr_offset + n ]; - tmp2 = x_ptr[ x_ptr_offset + subfr_length - n - 1 ]; - for( k = 0; k < n; k++ ) { - C_first_row[ k ] -= x_ptr[ x_ptr_offset + n ] * x_ptr[ x_ptr_offset + n - k - 1 ]; - C_last_row[ k ] -= x_ptr[ x_ptr_offset + subfr_length - n - 1 ] * x_ptr[ x_ptr_offset + subfr_length - n + k ]; - Atmp = Af[ k ]; - tmp1 += x_ptr[ x_ptr_offset + n - k - 1 ] * Atmp; - tmp2 += x_ptr[ x_ptr_offset + subfr_length - n + k ] * Atmp; - } - for( k = 0; k <= n; k++ ) { - CAf[ k ] -= tmp1 * x_ptr[ x_ptr_offset + n - k ]; - CAb[ k ] -= tmp2 * x_ptr[ x_ptr_offset + subfr_length - n + k - 1 ]; - } - } - tmp1 = C_first_row[ n ]; - tmp2 = C_last_row[ n ]; - for( k = 0; k < n; k++ ) { - Atmp = Af[ k ]; - tmp1 += C_last_row[ n - k - 1 ] * Atmp; - tmp2 += C_first_row[ n - k - 1 ] * Atmp; - } - CAf[ n + 1 ] = tmp1; - CAb[ n + 1 ] = tmp2; - - /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */ - num = CAb[ n + 1 ]; - nrg_b = CAb[ 0 ]; - nrg_f = CAf[ 0 ]; - for( k = 0; k < n; k++ ) { - Atmp = Af[ k ]; - num += CAb[ n - k ] * Atmp; - nrg_b += CAb[ k + 1 ] * Atmp; - nrg_f += CAf[ k + 1 ] * Atmp; - } - assert( nrg_f > 0.0 ); - assert( nrg_b > 0.0 ); - - /* Calculate the next order reflection (parcor) coefficient */ - rc = -2.0 * num / ( nrg_f + nrg_b ); - assert( rc > -1.0 && rc < 1.0 ); - - /* Update the AR coefficients */ - for( k = 0; k < (n + 1) >> 1; k++ ) { - tmp1 = Af[ k ]; - tmp2 = Af[ n - k - 1 ]; - Af[ k ] = tmp1 + rc * tmp2; - Af[ n - k - 1 ] = tmp2 + rc * tmp1; - } - Af[ n ] = rc; - - /* Update C * Af and C * Ab */ - for( k = 0; k <= n + 1; k++ ) { - tmp1 = CAf[ k ]; - CAf[ k ] += rc * CAb[ n - k + 1 ]; - CAb[ n - k + 1 ] += rc * tmp1; - } - } - - /* Return residual energy */ - nrg_f = CAf[ 0 ]; - tmp1 = 1.0; - for( k = 0; k < D; k++ ) { - Atmp = Af[ k ]; - nrg_f += CAf[ k + 1 ] * Atmp; - tmp1 += Atmp * Atmp; - A[ k ] = (float)(-Atmp); - } - nrg_f -= WhiteNoiseFrac * C0 * tmp1; - - return (float)nrg_f; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_bwexpander.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_bwexpander.java deleted file mode 100644 index 34c3c6464..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_bwexpander.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Chirp (bandwidth expand) LP AR filter - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_bwexpander -{ - /** - * Chirp (bandwidth expand) LP AR filter. - * @param ar AR filter to be expanded (without leading 1). - * @param d Length of ar. - * @param chirp_Q16 Chirp factor (typically in the range 0 to 1). - */ - static void SKP_Silk_bwexpander( - short []ar, /* I/O AR filter to be expanded (without leading 1) */ - final int d, /* I Length of ar */ - int chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */ - ) - { - int i; - int chirp_minus_one_Q16; - - chirp_minus_one_Q16 = chirp_Q16 - 65536; - - /* NB: Dont use SKP_SMULWB, instead of SKP_RSHIFT_ROUND( SKP_MUL() , 16 ), below. */ - /* Bias in SKP_SMULWB can lead to unstable filters */ - for( i = 0; i < d - 1; i++ ) { - ar[ i ] = (short)Silk_SigProc_FIX.SKP_RSHIFT_ROUND( ( chirp_Q16 * ar[ i ]), 16 ); - chirp_Q16 += Silk_SigProc_FIX.SKP_RSHIFT_ROUND( ( chirp_Q16 * chirp_minus_one_Q16 ), 16 ); - } - ar[ d - 1 ] = (short)Silk_SigProc_FIX.SKP_RSHIFT_ROUND( ( chirp_Q16 * ar[ d - 1 ] ), 16 ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_bwexpander_32.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_bwexpander_32.java deleted file mode 100644 index 0971fbee7..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_bwexpander_32.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_bwexpander_32 -{ - /** - * Chirp (bandwidth expand) LP AR filter. - * @param ar AR filter to be expanded (without leading 1). - * @param d Length of ar. - * @param chirp_Q16 Chirp factor in Q16. - */ - static void SKP_Silk_bwexpander_32( - int []ar, /* I/O AR filter to be expanded (without leading 1) */ - final int d, /* I Length of ar */ - int chirp_Q16 /* I Chirp factor in Q16 */ - ) - { - int i; - int tmp_chirp_Q16; - - tmp_chirp_Q16 = chirp_Q16; - for( i = 0; i < d - 1; i++ ) { - ar[ i ] = Silk_macros.SKP_SMULWW( ar[ i ], tmp_chirp_Q16 ); - tmp_chirp_Q16 = Silk_macros.SKP_SMULWW( chirp_Q16, tmp_chirp_Q16 ); - } - ar[ d - 1 ] = Silk_macros.SKP_SMULWW( ar[ d - 1 ], tmp_chirp_Q16 ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_bwexpander_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_bwexpander_FLP.java deleted file mode 100644 index fc88c9962..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_bwexpander_FLP.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_bwexpander_FLP -{ - /** - * Chirp (bw expand) LP AR filter. - * @param ar AR filter to be expanded (without leading 1). - * @param ar_offset offset of valid data. - * @param d length of ar. - * @param chirp chirp factor (typically in range (0..1) ). - */ - static void SKP_Silk_bwexpander_FLP( - float[] ar, /* I/O AR filter to be expanded (without leading 1) */ - int ar_offset, - final int d, /* I length of ar */ - final float chirp /* I chirp factor (typically in range (0..1) ) */ - ) - { - int i; - float cfac = chirp; - - for( i = 0; i < d - 1; i++ ) - { - ar[ ar_offset+i ] *= cfac; - cfac *= chirp; - } - ar[ ar_offset + d - 1 ] *= cfac; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_code_signs.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_code_signs.java deleted file mode 100644 index 449b32dde..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_code_signs.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_code_signs -{ - /* shifting avoids if-statement */ -// #define SKP_enc_map(a) ( SKP_RSHIFT( (a), 15 ) + 1 ) - static int SKP_enc_map(int a) - { - return (a>>15)+1; - } - -// #define SKP_dec_map(a) ( SKP_LSHIFT( (a), 1 ) - 1 ) - static int SKP_dec_map(int a) - { - return (a<<1)-1; - } - - /** - * Encodes signs of excitation. - * @param sRC Range coder state. - * @param q Pulse signal. - * @param length Length of input. - * @param sigtype Signal type. - * @param QuantOffsetType QuantOffsetType. - * @param RateLevelIndex Rate level index. - */ - static void SKP_Silk_encode_signs( - SKP_Silk_range_coder_state sRC, /* I/O Range coder state */ - byte[] q, /* I Pulse signal */ - final int length, /* I Length of input */ - final int sigtype, /* I Signal type */ - final int QuantOffsetType, /* I Quantization offset type */ - final int RateLevelIndex /* I Rate level index */ - ) - { - int i; - int inData; - int[] cdf = new int[3]; - - i = Silk_macros.SKP_SMULBB( Silk_define.N_RATE_LEVELS - 1, ( sigtype << 1 ) + QuantOffsetType ) + RateLevelIndex; - cdf[ 0 ] = 0; - cdf[ 1 ] = Silk_tables_sign.SKP_Silk_sign_CDF[ i ]; - cdf[ 2 ] = 65535; - - for( i = 0; i < length; i++ ) - { - if( q[ i ] != 0 ) - { -// inData = SKP_enc_map( q[ i ] ); /* - = 0, + = 1 */ - inData = (q[i] >>15) + 1; /* - = 0, + = 1 */ - Silk_range_coder.SKP_Silk_range_encoder( sRC, inData, cdf, 0 ); - } - } - } - - /** - * Decodes signs of excitation. - * @param sRC Range coder state. - * @param q pulse signal. - * @param length length of output. - * @param sigtype Signal type. - * @param QuantOffsetType Quantization offset type. - * @param RateLevelIndex Rate Level Index. - */ - static void SKP_Silk_decode_signs( - SKP_Silk_range_coder_state sRC, /* I/O Range coder state */ - int q[], /* I/O pulse signal */ - final int length, /* I length of output */ - final int sigtype, /* I Signal type */ - final int QuantOffsetType, /* I Quantization offset type */ - final int RateLevelIndex /* I Rate Level Index */ - ) - { - int i; - int data; - int data_ptr[] = new int[1]; - int[] cdf = new int[3]; - - i = Silk_macros.SKP_SMULBB( Silk_define.N_RATE_LEVELS - 1, ( sigtype << 1 ) + QuantOffsetType ) + RateLevelIndex; - cdf[ 0 ] = 0; - cdf[ 1 ] = Silk_tables_sign.SKP_Silk_sign_CDF[ i ]; - cdf[ 2 ] = 65535; - - for( i = 0; i < length; i++ ) { - if( q[ i ] > 0 ) { - Silk_range_coder.SKP_Silk_range_decoder( data_ptr, 0, sRC, cdf, 0, 1 ); - data = data_ptr[0]; - /* attach sign */ - /* implementation with shift, subtraction, multiplication */ -// q[ i ] *= SKP_dec_map( data ); - q[ i ] *= (data<<1) - 1; - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_common_pitch_est_defines.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_common_pitch_est_defines.java deleted file mode 100644 index 3344f8d53..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_common_pitch_est_defines.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Definitions For Fix pitch estimator. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_common_pitch_est_defines -{ - static final int PITCH_EST_MAX_FS_KHZ = 24; /* Maximum sampling frequency used */ - - static final int PITCH_EST_FRAME_LENGTH_MS = 40; /* 40 ms */ - - static final int PITCH_EST_MAX_FRAME_LENGTH = (PITCH_EST_FRAME_LENGTH_MS * PITCH_EST_MAX_FS_KHZ); - static final int PITCH_EST_MAX_FRAME_LENGTH_ST_1 = (PITCH_EST_MAX_FRAME_LENGTH >> 2); - static final int PITCH_EST_MAX_FRAME_LENGTH_ST_2 = (PITCH_EST_MAX_FRAME_LENGTH >> 1); -//TODO: PITCH_EST_SUB_FRAME is neither defined nor used, temporally ignore it; -// static final int PITCH_EST_MAX_SF_FRAME_LENGTH = (PITCH_EST_SUB_FRAME * PITCH_EST_MAX_FS_KHZ); - - static final int PITCH_EST_MAX_LAG_MS = 18; /* 18 ms -> 56 Hz */ - static final int PITCH_EST_MIN_LAG_MS = 2; /* 2 ms -> 500 Hz */ - static final int PITCH_EST_MAX_LAG = (PITCH_EST_MAX_LAG_MS * PITCH_EST_MAX_FS_KHZ); - static final int PITCH_EST_MIN_LAG = (PITCH_EST_MIN_LAG_MS * PITCH_EST_MAX_FS_KHZ); - - static final int PITCH_EST_NB_SUBFR = 4; - - static final int PITCH_EST_D_SRCH_LENGTH = 24; - - static final int PITCH_EST_MAX_DECIMATE_STATE_LENGTH = 7; - - static final int PITCH_EST_NB_STAGE3_LAGS = 5; - - static final int PITCH_EST_NB_CBKS_STAGE2 = 3; - static final int PITCH_EST_NB_CBKS_STAGE2_EXT = 11; - - static final int PITCH_EST_CB_mn2 = 1; - static final int PITCH_EST_CB_mx2 = 2; - - static final int PITCH_EST_NB_CBKS_STAGE3_MAX = 34; - static final int PITCH_EST_NB_CBKS_STAGE3_MID = 24; - static final int PITCH_EST_NB_CBKS_STAGE3_MIN = 16; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_control.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_control.java deleted file mode 100644 index 99bb3a477..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_control.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Silk codec encoder/decoder control class. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_control -{ -} - -/** - * Class for controlling encoder operation - * - * @author Jing Dai - * @author Dingxin Xu - */ -class SKP_SILK_SDK_EncControlStruct -{ - /** - * (Input) Input signal sampling rate in Hertz; 8000/12000/16000/24000. - */ - int API_sampleRate; - - /** - * (Input) Maximum internal sampling rate in Hertz; 8000/12000/16000/24000. - */ - int maxInternalSampleRate; - - /** - * (Input) Number of samples per packet; must be equivalent of 20, 40, 60, 80 or 100 ms. - */ - int packetSize; - - /** - * (Input) Bitrate during active speech in bits/second; internally limited. - */ - int bitRate; - - /** - * (Inpupt) Uplink packet loss in percent (0-100). - */ - int packetLossPercentage; - - /** - * (Input) Complexity mode; 0 is lowest; 1 is medium and 2 is highest complexity. - */ - int complexity; - - /** - * (Input) Flag to enable in-band Forward Error Correction (FEC); 0/1 - */ - int useInBandFEC; - - /** - * (Input) Flag to enable discontinuous transmission (DTX); 0/1 - */ - int useDTX; -} - -/** - * Class for controlling decoder operation and reading decoder status. - * @author Jing Dai - * @author Dingxin Xu - */ -class SKP_SILK_SDK_DecControlStruct -{ - /** - * (Input) Output signal sampling rate in Hertz; 8000/12000/16000/24000. - */ - int API_sampleRate; - - /** - * (Output) Number of samples per frame. - */ - int frameSize; - - /** - * (Output) Frames per packet 1, 2, 3, 4, 5. - */ - int framesPerPacket; - - /** - * (Output) Flag to indicate that the decoder has remaining payloads internally. - */ - int moreInternalDecoderFrames; - - /** - * (Output) Distance between main payload and redundant payload in packets. - */ - int inBandFECOffset; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_control_codec_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_control_codec_FLP.java deleted file mode 100644 index d0377863c..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_control_codec_FLP.java +++ /dev/null @@ -1,665 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -import java.util.*; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_control_codec_FLP { - /** - * Control encoder SNR. - * - * @param psEnc - * Pointer to Silk encoder state FLP - * @param API_fs_Hz - * External (API) sampling rate (Hz). - * @param max_internal_fs_kHz - * Maximum internal sampling rate (kHz). - * @param PacketSize_ms - * Packet length (ms). - * @param TargetRate_bps - * Target max bitrate (if SNR_dB == 0). - * @param PacketLoss_perc - * Packet loss rate (in percent). - * @param INBandFEC_enabled - * Enable (1) / disable (0) inband FEC. - * @param DTX_enabled - * Enable / disable DTX. - * @param InputFramesize_ms - * Inputframe in ms. - * @param Complexity - * Complexity (0->low; 1->medium; 2->high). - * @return - */ - static int SKP_Silk_control_encoder_FLP( - SKP_Silk_encoder_state_FLP psEnc, /* I/O Pointer to Silk encoder state FLP */ - final int API_fs_Hz, /* I External (API) sampling rate (Hz) */ - final int max_internal_fs_kHz,/* I Maximum internal sampling rate (kHz) */ - final int PacketSize_ms, /* I Packet length (ms) */ - int TargetRate_bps, /* I Target max bitrate (if SNR_dB == 0) */ - final int PacketLoss_perc, /* I Packet loss rate (in percent) */ - final int INBandFEC_enabled, /* I Enable (1) / disable (0) inband FEC */ - final int DTX_enabled, /* I Enable / disable DTX */ - final int InputFramesize_ms, /* I Inputframe in ms */ - final int Complexity /* I Complexity (0->low; 1->medium; 2->high) */ - ) - { - int LBRRRate_thres_bps; - int k, fs_kHz, ret = 0; - float frac; - int[] rateTable; - - /* State machine for the SWB/WB switching */ - fs_kHz = psEnc.sCmn.fs_kHz; - - /* Only switch during low speech activity, when no frames are sitting in the payload buffer */ - if( API_fs_Hz == 8000 || fs_kHz == 0 || API_fs_Hz < fs_kHz * 1000 || fs_kHz > max_internal_fs_kHz ) - { - /* Switching is not possible, encoder just initialized, internal mode higher than external, */ - /* or internal mode higher than maximum allowed internal mode */ - fs_kHz = Math.min( API_fs_Hz/1000, max_internal_fs_kHz ); - } - else - { - /* Accumulate the difference between the target rate and limit for switching down */ - psEnc.sCmn.bitrateDiff += InputFramesize_ms * (TargetRate_bps - psEnc.sCmn.bitrate_threshold_down); - psEnc.sCmn.bitrateDiff = Math.min( psEnc.sCmn.bitrateDiff, 0 ); - - if( psEnc.speech_activity < 0.5f && psEnc.sCmn.nFramesInPayloadBuf == 0 ) - { /* Low speech activity and payload buffer empty */ - /* Check if we should switch down */ - if(Silk_define.SWITCH_TRANSITION_FILTERING!=0) - { - if( ( psEnc.sCmn.sLP.transition_frame_no == 0 ) && /* Transition phase not active */ - ( psEnc.sCmn.bitrateDiff <= -Silk_define.ACCUM_BITS_DIFF_THRESHOLD || /* Bitrate threshold is met */ - ( psEnc.sCmn.sSWBdetect.WB_detected * psEnc.sCmn.fs_kHz == 24 ) ) ) - { /* Forced down-switching due to WB input */ - psEnc.sCmn.sLP.transition_frame_no = 1; /* Begin transition phase */ - psEnc.sCmn.sLP.mode = 0; /* Switch down */ - } - else if( - ( psEnc.sCmn.sLP.transition_frame_no >= Silk_define.TRANSITION_FRAMES_DOWN ) && /* Transition phase complete */ - ( psEnc.sCmn.sLP.mode == 0 ) ) - { /* Ready to switch down */ - psEnc.sCmn.sLP.transition_frame_no = 0; /* Ready for new transition phase */ - psEnc.sCmn.bitrateDiff = 0; - - /* Switch to a lower sample frequency */ - if( psEnc.sCmn.fs_kHz == 24 ) - { - fs_kHz = 16; - } - else if( psEnc.sCmn.fs_kHz == 16 ) - { - fs_kHz = 12; - } - else - { - assert( psEnc.sCmn.fs_kHz == 12 ); - fs_kHz = 8; - } - } - } - else - { - if( psEnc.sCmn.bitrateDiff <= -Silk_define.ACCUM_BITS_DIFF_THRESHOLD ) - { /* Bitrate threshold is met */ - psEnc.sCmn.bitrateDiff = 0; - - /* Switch to a lower sample frequency */ - if( psEnc.sCmn.fs_kHz == 24 ) - { - fs_kHz = 16; - } - else if( psEnc.sCmn.fs_kHz == 16 ) - { - fs_kHz = 12; - } - else - { - assert( psEnc.sCmn.fs_kHz == 12 ); - fs_kHz = 8; - } - } - } - /* Check if we should switch up */ - if(Silk_define.SWITCH_TRANSITION_FILTERING != 0) - { - if( ( ( psEnc.sCmn.fs_kHz * 1000 < API_fs_Hz ) && - ( TargetRate_bps >= psEnc.sCmn.bitrate_threshold_up ) && - ( psEnc.sCmn.sSWBdetect.WB_detected * psEnc.sCmn.fs_kHz != 16 ) ) && - ( ( psEnc.sCmn.fs_kHz == 16 ) && ( max_internal_fs_kHz >= 24 ) || - ( psEnc.sCmn.fs_kHz == 12 ) && ( max_internal_fs_kHz >= 16 ) || - ( psEnc.sCmn.fs_kHz == 8 ) && ( max_internal_fs_kHz >= 12 ) ) - // #if SWITCH_TRANSITION_FILTERING - && ( psEnc.sCmn.sLP.transition_frame_no == 0 ) ) - { /* No transition phase running, ready to switch */ - psEnc.sCmn.sLP.mode = 1; /* Switch up */ - // #else - // ) { - // #endif - psEnc.sCmn.bitrateDiff = 0; - - /* Switch to a higher sample frequency */ - if( psEnc.sCmn.fs_kHz == 8 ) - { - fs_kHz = 12; - } - else if( psEnc.sCmn.fs_kHz == 12 ) - { - fs_kHz = 16; - } - else - { - assert( psEnc.sCmn.fs_kHz == 16 ); - fs_kHz = 24; - } - } - } - else - { - /* Check if we should switch up */ - if( ( ( psEnc.sCmn.fs_kHz * 1000 < API_fs_Hz ) && - ( TargetRate_bps >= psEnc.sCmn.bitrate_threshold_up ) && - ( psEnc.sCmn.sSWBdetect.WB_detected * psEnc.sCmn.fs_kHz != 16 ) ) && - ( ( psEnc.sCmn.fs_kHz == 16 ) && ( max_internal_fs_kHz >= 24 ) || - ( psEnc.sCmn.fs_kHz == 12 ) && ( max_internal_fs_kHz >= 16 ) || - ( psEnc.sCmn.fs_kHz == 8 ) && ( max_internal_fs_kHz >= 12 ) ) -// // #if SWITCH_TRANSITION_FILTERING -// && ( psEnc.sCmn.sLP.transition_frame_no == 0 ) ) -// { /* No transition phase running, ready to switch */ -// psEnc.sCmn.sLP.mode = 1; /* Switch up */ -// // #else - ) { - // #endif - psEnc.sCmn.bitrateDiff = 0; - - /* Switch to a higher sample frequency */ - if( psEnc.sCmn.fs_kHz == 8 ) - { - fs_kHz = 12; - } - else if( psEnc.sCmn.fs_kHz == 12 ) - { - fs_kHz = 16; - } - else - { - assert( psEnc.sCmn.fs_kHz == 16 ); - fs_kHz = 24; - } - } - } - } - } - - if(Silk_define.SWITCH_TRANSITION_FILTERING != 0) - { - /* After switching up, stop transition filter during speech inactivity */ - if( ( psEnc.sCmn.sLP.mode == 1 ) && - ( psEnc.sCmn.sLP.transition_frame_no >= Silk_define.TRANSITION_FRAMES_UP ) && - ( psEnc.speech_activity < 0.5f ) && - ( psEnc.sCmn.nFramesInPayloadBuf == 0 ) ) - { - - psEnc.sCmn.sLP.transition_frame_no = 0; - - /* Reset transition filter state */ - Arrays.fill(psEnc.sCmn.sLP.In_LP_State, 0, 2, 0); - } - } - - /* Resampler setup */ - if( psEnc.sCmn.fs_kHz != fs_kHz || psEnc.sCmn.prev_API_fs_Hz != API_fs_Hz ) - { - /* Allocate space for worst case temporary upsampling, 8 to 48 kHz, so a factor 6 */ - short[] x_buf_API_fs_Hz = new short[ ( Silk_define.MAX_API_FS_KHZ / 8 ) * ( 2 * Silk_define.MAX_FRAME_LENGTH + Silk_define.LA_SHAPE_MAX ) ]; - short[] x_bufFIX = new short[ 2 * Silk_define.MAX_FRAME_LENGTH + Silk_define.LA_SHAPE_MAX ]; - - int nSamples_temp = 2 * psEnc.sCmn.frame_length + psEnc.sCmn.la_shape; - - Silk_SigProc_FLP.SKP_float2short_array( x_bufFIX, 0, psEnc.x_buf, 0, 2 * Silk_define.MAX_FRAME_LENGTH + Silk_define.LA_SHAPE_MAX ); - - if( fs_kHz * 1000 < API_fs_Hz && psEnc.sCmn.fs_kHz != 0 ) - { - /* Resample buffered data in x_buf to API_fs_Hz */ - - SKP_Silk_resampler_state_struct temp_resampler_state = new SKP_Silk_resampler_state_struct(); - - /* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */ - ret += Silk_resampler.SKP_Silk_resampler_init( temp_resampler_state, psEnc.sCmn.fs_kHz * 1000, API_fs_Hz ); - - /* Temporary resampling of x_buf data to API_fs_Hz */ - ret += Silk_resampler.SKP_Silk_resampler( temp_resampler_state, x_buf_API_fs_Hz,0, x_bufFIX,0, nSamples_temp ); - - /* Calculate number of samples that has been temporarily upsampled */ - nSamples_temp = ( nSamples_temp * API_fs_Hz ) / ( psEnc.sCmn.fs_kHz * 1000 ); - - /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */ - ret += Silk_resampler.SKP_Silk_resampler_init( psEnc.sCmn.resampler_state, API_fs_Hz, fs_kHz * 1000 ); - - } - else - { - /* Copy data */ - System.arraycopy(x_bufFIX, 0, x_buf_API_fs_Hz, 0, nSamples_temp); - } - - if( 1000 * fs_kHz != API_fs_Hz ) - { - /* Correct resampler state (unless resampling by a factor 1) by resampling buffered data from API_fs_Hz to fs_kHz */ - ret += Silk_resampler.SKP_Silk_resampler( psEnc.sCmn.resampler_state, x_bufFIX,0, x_buf_API_fs_Hz,0, nSamples_temp ); - } - Silk_SigProc_FLP.SKP_short2float_array( psEnc.x_buf,0, x_bufFIX,0, 2 * Silk_define.MAX_FRAME_LENGTH + Silk_define.LA_SHAPE_MAX ); - } - - psEnc.sCmn.prev_API_fs_Hz = API_fs_Hz; - - /* Set internal sampling frequency */ - if( psEnc.sCmn.fs_kHz != fs_kHz ) { -//TODO:whether need to set 0 explicitly??? - /* reset part of the state */ -// SKP_memset( &psEnc->sShape, 0, sizeof( SKP_Silk_shape_state_FLP ) ); - psEnc.sShape.memZero(); -// SKP_memset( &psEnc->sPrefilt, 0, sizeof( SKP_Silk_prefilter_state_FLP ) ); - psEnc.sPrefilt.memZero(); -// SKP_memset( &psEnc->sNSQ, 0, sizeof( SKP_Silk_nsq_state ) ); - psEnc.sNSQ.memZero(); -// SKP_memset( &psEnc->sPred, 0, sizeof( SKP_Silk_predict_state_FLP ) ); - psEnc.sPred.memZero(); -// SKP_memset( psEnc->sNSQ.xq, 0, ( 2 * MAX_FRAME_LENGTH ) * sizeof( SKP_float ) ); -//TODO: psEnc.sNSQ.vq is of short[], why sizeof(SKP_float)??? - Arrays.fill(psEnc.sNSQ.xq, 0, 2 * Silk_define.MAX_FRAME_LENGTH, (short)0); -// SKP_memset( psEnc->sNSQ_LBRR.xq, 0, ( 2 * MAX_FRAME_LENGTH ) * sizeof( SKP_float ) ); - Arrays.fill(psEnc.sNSQ_LBRR.xq, (short)0); -// SKP_memset( psEnc->sCmn.LBRR_buffer, 0, MAX_LBRR_DELAY * sizeof( SKP_SILK_LBRR_struct ) ); - for(int i=0; i < Silk_define.MAX_LBRR_DELAY; i++) - { - psEnc.sCmn.LBRR_buffer[i].memZero(); - } - - if(Silk_define.SWITCH_TRANSITION_FILTERING != 0) - { - Arrays.fill(psEnc.sCmn.sLP.In_LP_State, 0, 2, 0); - if( psEnc.sCmn.sLP.mode == 1 ) - { - /* Begin transition phase */ - psEnc.sCmn.sLP.transition_frame_no = 1; - } - else - { - /* End transition phase */ - psEnc.sCmn.sLP.transition_frame_no = 0; - } - } - psEnc.sCmn.inputBufIx = 0; - psEnc.sCmn.nFramesInPayloadBuf = 0; - psEnc.sCmn.nBytesInPayloadBuf = 0; - psEnc.sCmn.oldest_LBRR_idx = 0; - psEnc.sCmn.TargetRate_bps = 0; /* Ensures that psEnc->SNR_dB is recomputed */ - -// SKP_memset( psEnc->sPred.prev_NLSFq, 0, MAX_LPC_ORDER * sizeof( SKP_float ) ); - Arrays.fill(psEnc.sPred.prev_NLSFq, 0, Silk_define.MAX_LPC_ORDER, 0); - - /* Initialize non-zero parameters */ - psEnc.sCmn.prevLag = 100; - psEnc.sCmn.prev_sigtype = Silk_define.SIG_TYPE_UNVOICED; - psEnc.sCmn.first_frame_after_reset = 1; - psEnc.sPrefilt.lagPrev = 100; - psEnc.sShape.LastGainIndex = 1; - psEnc.sNSQ.lagPrev = 100; - psEnc.sNSQ.prev_inv_gain_Q16 = 65536; - psEnc.sNSQ_LBRR.prev_inv_gain_Q16 = 65536; - - psEnc.sCmn.fs_kHz = fs_kHz; - if( psEnc.sCmn.fs_kHz == 8 ) - { - psEnc.sCmn.predictLPCOrder = Silk_define.MIN_LPC_ORDER; -// psEnc.sCmn.psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_10; -// psEnc.sCmn.psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_10; -// psEnc.psNLSF_CB_FLP[ 0 ] = &SKP_Silk_NLSF_CB0_10_FLP; -// psEnc.psNLSF_CB_FLP[ 1 ] = &SKP_Silk_NLSF_CB1_10_FLP; - psEnc.sCmn.psNLSF_CB[ 0 ] = Silk_tables_NLSF_CB0_10.SKP_Silk_NLSF_CB0_10; - psEnc.sCmn.psNLSF_CB[ 1 ] = Silk_tables_NLSF_CB1_10.SKP_Silk_NLSF_CB1_10; - psEnc.psNLSF_CB_FLP[ 0 ] = Silk_tables_NLSF_CB0_10_FLP.SKP_Silk_NLSF_CB0_10_FLP; - psEnc.psNLSF_CB_FLP[ 1 ] = Silk_tables_NLSF_CB1_10_FLP.SKP_Silk_NLSF_CB1_10_FLP; - } - else - { - psEnc.sCmn.predictLPCOrder = Silk_define.MAX_LPC_ORDER; - psEnc.sCmn.psNLSF_CB[ 0 ] = Silk_tables_NLSF_CB0_16.SKP_Silk_NLSF_CB0_16; - psEnc.sCmn.psNLSF_CB[ 1 ] = Silk_tables_NLSF_CB1_16.SKP_Silk_NLSF_CB1_16; - psEnc.psNLSF_CB_FLP[ 0 ] = Silk_tables_NLSF_CB0_16_FLP.SKP_Silk_NLSF_CB0_16_FLP; - psEnc.psNLSF_CB_FLP[ 1 ] = Silk_tables_NLSF_CB1_16_FLP.SKP_Silk_NLSF_CB1_16_FLP; - } - psEnc.sCmn.frame_length = Silk_define.FRAME_LENGTH_MS * fs_kHz; - psEnc.sCmn.subfr_length = psEnc.sCmn.frame_length / Silk_define.NB_SUBFR; - psEnc.sCmn.la_pitch = Silk_define.LA_PITCH_MS * fs_kHz; - psEnc.sCmn.la_shape = Silk_define.LA_SHAPE_MS * fs_kHz; - psEnc.sPred.min_pitch_lag = 3 * fs_kHz; - psEnc.sPred.max_pitch_lag = 18 * fs_kHz; - psEnc.sPred.pitch_LPC_win_length = Silk_define.FIND_PITCH_LPC_WIN_MS * fs_kHz; - if( psEnc.sCmn.fs_kHz == 24 ) - { - psEnc.mu_LTP = Silk_define_FLP.MU_LTP_QUANT_SWB; - psEnc.sCmn.bitrate_threshold_up = Silk_typedef.SKP_int32_MAX; - psEnc.sCmn.bitrate_threshold_down = Silk_define.SWB2WB_BITRATE_BPS; - } - else if( psEnc.sCmn.fs_kHz == 16 ) - { - psEnc.mu_LTP = Silk_define_FLP.MU_LTP_QUANT_WB; - psEnc.sCmn.bitrate_threshold_up = Silk_define.WB2SWB_BITRATE_BPS; - psEnc.sCmn.bitrate_threshold_down = Silk_define.WB2MB_BITRATE_BPS; - } - else if( psEnc.sCmn.fs_kHz == 12 ) - { - psEnc.mu_LTP = Silk_define_FLP.MU_LTP_QUANT_MB; - psEnc.sCmn.bitrate_threshold_up = Silk_define.MB2WB_BITRATE_BPS; - psEnc.sCmn.bitrate_threshold_down = Silk_define.MB2NB_BITRATE_BPS; - } - else - { - psEnc.mu_LTP = Silk_define_FLP.MU_LTP_QUANT_NB; - psEnc.sCmn.bitrate_threshold_up = Silk_define.NB2MB_BITRATE_BPS; - psEnc.sCmn.bitrate_threshold_down = 0; - } - psEnc.sCmn.fs_kHz_changed = 1; - - /* Check that settings are valid */ - assert( ( psEnc.sCmn.subfr_length * Silk_define.NB_SUBFR ) == psEnc.sCmn.frame_length ); - } - - /* Check that settings are valid */ - if( Silk_define.LOW_COMPLEXITY_ONLY !=0 && Complexity != 0 ) - { - ret = Silk_errors.SKP_SILK_ENC_INVALID_COMPLEXITY_SETTING; - } - - /* Set encoding complexity */ - if( Complexity == 0 || Silk_define.LOW_COMPLEXITY_ONLY !=0 ) - { - /* Low complexity */ - psEnc.sCmn.Complexity = 0; - psEnc.sCmn.pitchEstimationComplexity = Silk_define.PITCH_EST_COMPLEXITY_LC_MODE; - psEnc.pitchEstimationThreshold = Silk_define_FLP.FIND_PITCH_CORRELATION_THRESHOLD_LC_MODE; - psEnc.sCmn.pitchEstimationLPCOrder = 8; - psEnc.sCmn.shapingLPCOrder = 12; - psEnc.sCmn.nStatesDelayedDecision = 1; -// psEnc.NoiseShapingQuantizer = SKP_Silk_NSQ; - psEnc.noiseShapingQuantizerCB = new NSQImplNSQ(); - psEnc.sCmn.useInterpolatedNLSFs = 0; - psEnc.sCmn.LTPQuantLowComplexity = 1; - psEnc.sCmn.NLSF_MSVQ_Survivors = Silk_define.MAX_NLSF_MSVQ_SURVIVORS_LC_MODE; - } - else if( Complexity == 1 ) - { - /* Medium complexity */ - psEnc.sCmn.Complexity = 1; - psEnc.sCmn.pitchEstimationComplexity = Silk_define.PITCH_EST_COMPLEXITY_MC_MODE; - psEnc.pitchEstimationThreshold = Silk_define_FLP.FIND_PITCH_CORRELATION_THRESHOLD_MC_MODE; - psEnc.sCmn.pitchEstimationLPCOrder = 12; - psEnc.sCmn.shapingLPCOrder = 16; - psEnc.sCmn.nStatesDelayedDecision = 2; -// psEnc.NoiseShapingQuantizer = SKP_Silk_NSQ_del_dec; - psEnc.noiseShapingQuantizerCB = new NSQImplNSQDelDec(); - psEnc.sCmn.useInterpolatedNLSFs = 0; - psEnc.sCmn.LTPQuantLowComplexity = 0; - psEnc.sCmn.NLSF_MSVQ_Survivors = Silk_define.MAX_NLSF_MSVQ_SURVIVORS_MC_MODE; - } - else if( Complexity == 2 ) - { - /* High complexity */ - psEnc.sCmn.Complexity = 2; - psEnc.sCmn.pitchEstimationComplexity = Silk_define.PITCH_EST_COMPLEXITY_HC_MODE; - psEnc.pitchEstimationThreshold = Silk_define_FLP.FIND_PITCH_CORRELATION_THRESHOLD_HC_MODE; - psEnc.sCmn.pitchEstimationLPCOrder = 16; - psEnc.sCmn.shapingLPCOrder = 16; - psEnc.sCmn.nStatesDelayedDecision = 4; -// psEnc.NoiseShapingQuantizer = SKP_Silk_NSQ_del_dec; - psEnc.noiseShapingQuantizerCB = new NSQImplNSQDelDec(); - psEnc.sCmn.useInterpolatedNLSFs = 1; - psEnc.sCmn.LTPQuantLowComplexity = 0; - psEnc.sCmn.NLSF_MSVQ_Survivors = Silk_define.MAX_NLSF_MSVQ_SURVIVORS; - } - else - { - ret = Silk_errors.SKP_SILK_ENC_INVALID_COMPLEXITY_SETTING; - } - - /* Do not allow higher pitch estimation LPC order than predict LPC order */ - psEnc.sCmn.pitchEstimationLPCOrder = Math.min( psEnc.sCmn.pitchEstimationLPCOrder, psEnc.sCmn.predictLPCOrder ); - - assert( psEnc.sCmn.pitchEstimationLPCOrder <= Silk_define.FIND_PITCH_LPC_ORDER_MAX ); - assert( psEnc.sCmn.shapingLPCOrder <= Silk_define.SHAPE_LPC_ORDER_MAX ); - assert( psEnc.sCmn.nStatesDelayedDecision <= Silk_define.DEL_DEC_STATES_MAX ); - - /* Set bitrate/coding quality */ - TargetRate_bps = Math.min( TargetRate_bps, 100000 ); - if( psEnc.sCmn.fs_kHz == 8 ) - { - TargetRate_bps = Math.max( TargetRate_bps, Silk_define.MIN_TARGET_RATE_NB_BPS ); - } - else if( psEnc.sCmn.fs_kHz == 12 ) - { - TargetRate_bps = Math.max( TargetRate_bps, Silk_define.MIN_TARGET_RATE_MB_BPS ); - } - else if( psEnc.sCmn.fs_kHz == 16 ) - { - TargetRate_bps = Math.max( TargetRate_bps, Silk_define.MIN_TARGET_RATE_WB_BPS ); - } - else - { - TargetRate_bps = Math.max( TargetRate_bps, Silk_define.MIN_TARGET_RATE_SWB_BPS ); - } - if( TargetRate_bps != psEnc.sCmn.TargetRate_bps ) - { - psEnc.sCmn.TargetRate_bps = TargetRate_bps; - - /* If new TargetRate_bps, translate to SNR_dB value */ - if( psEnc.sCmn.fs_kHz == 8 ) - { - rateTable = Silk_tables_other.TargetRate_table_NB; - } - else if( psEnc.sCmn.fs_kHz == 12 ) - { - rateTable = Silk_tables_other.TargetRate_table_MB; - } - else if( psEnc.sCmn.fs_kHz == 16 ) - { - rateTable = Silk_tables_other.TargetRate_table_WB; - } - else - { - rateTable = Silk_tables_other.TargetRate_table_SWB; - } - for( k = 1; k < Silk_define.TARGET_RATE_TAB_SZ; k++ ) - { - /* Find bitrate interval in table and interpolate */ - if( TargetRate_bps < rateTable[ k ] ) - { - frac = (float)( TargetRate_bps - rateTable[ k - 1 ] ) / - (float)( rateTable[ k ] - rateTable[ k - 1 ] ); - psEnc.SNR_dB = 0.5f * ( Silk_tables_other.SNR_table_Q1[ k - 1 ] + frac * ( Silk_tables_other.SNR_table_Q1[ k ] - Silk_tables_other.SNR_table_Q1[ k - 1 ] ) ); - break; - } - } - } - - /* Set packet size */ - if( ( PacketSize_ms != 20 ) && - ( PacketSize_ms != 40 ) && - ( PacketSize_ms != 60 ) && - ( PacketSize_ms != 80 ) && - ( PacketSize_ms != 100 ) ) - { - ret = Silk_errors.SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED; - } - else - { - if( PacketSize_ms != psEnc.sCmn.PacketSize_ms ) - { - psEnc.sCmn.PacketSize_ms = PacketSize_ms; - - /* Packet length changes. Reset LBRR buffer */ - Silk_LBRR_reset.SKP_Silk_LBRR_reset( psEnc.sCmn ); - } - } - - /* Set packet loss rate measured by farend */ - if( ( PacketLoss_perc < 0 ) || ( PacketLoss_perc > 100 ) ) - { - ret = Silk_errors.SKP_SILK_ENC_INVALID_LOSS_RATE; - } - psEnc.sCmn.PacketLoss_perc = PacketLoss_perc; - -// #if USE_LBRR - if(Silk_define.USE_LBRR != 0) - { - if( INBandFEC_enabled < 0 || INBandFEC_enabled > 1 ) - { - ret = Silk_errors.SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING; - } - - /* Only change settings if first frame in packet */ - if( psEnc.sCmn.nFramesInPayloadBuf == 0 ) - { - psEnc.sCmn.LBRR_enabled = INBandFEC_enabled; - if( psEnc.sCmn.fs_kHz == 8 ) - { - LBRRRate_thres_bps = Silk_define.INBAND_FEC_MIN_RATE_BPS - 9000; - } - else if( psEnc.sCmn.fs_kHz == 12 ) - { - LBRRRate_thres_bps = Silk_define.INBAND_FEC_MIN_RATE_BPS - 6000;; - } - else if( psEnc.sCmn.fs_kHz == 16 ) - { - LBRRRate_thres_bps = Silk_define.INBAND_FEC_MIN_RATE_BPS - 3000; - } - else - { - LBRRRate_thres_bps = Silk_define.INBAND_FEC_MIN_RATE_BPS; - } - - if( psEnc.sCmn.TargetRate_bps >= LBRRRate_thres_bps ) - { - /* Set gain increase / rate reduction for LBRR usage */ - /* Coarsely tuned with PESQ for now. */ - /* Linear regression coefs G = 8 - 0.5 * loss */ - /* Meaning that at 16% loss main rate and redundant rate is the same, -> G = 0 */ - psEnc.sCmn.LBRR_GainIncreases = Math.max( 8 - ( psEnc.sCmn.PacketLoss_perc >> 1 ), 0 ); - - /* Set main stream rate compensation */ - if( psEnc.sCmn.LBRR_enabled != 0 && psEnc.sCmn.PacketLoss_perc > Silk_define.LBRR_LOSS_THRES ) - { - /* Tuned to give aprox same mean / weighted bitrate as no inband FEC */ - psEnc.inBandFEC_SNR_comp = 6.0f - 0.5f * psEnc.sCmn.LBRR_GainIncreases; - } - else - { - psEnc.inBandFEC_SNR_comp = 0; - psEnc.sCmn.LBRR_enabled = 0; - } - } - else - { - psEnc.inBandFEC_SNR_comp = 0; - psEnc.sCmn.LBRR_enabled = 0; - } - } - } -// #else - else - { - if( INBandFEC_enabled != 0 ) - { - ret = Silk_errors.SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING; - } - psEnc.sCmn.LBRR_enabled = 0; -// #endif - } - - /* Set DTX mode */ - if( DTX_enabled < 0 || DTX_enabled > 1 ) - { - ret = Silk_errors.SKP_SILK_ENC_INVALID_DTX_SETTING; - } - psEnc.sCmn.useDTX = DTX_enabled; - - return ret; - } - - /** - * Control low bitrate redundancy usage. - * @param psEnc Encoder state FLP. - * @param psEncCtrl Encoder control. - */ - static void SKP_Silk_LBRR_ctrl_FLP( - SKP_Silk_encoder_state_FLP psEnc, /* I/O Encoder state FLP*/ - SKP_Silk_encoder_control psEncCtrl /* I/O Encoder control */ - ) - { - int LBRR_usage; - - if (psEnc.sCmn.LBRR_enabled != 0) { - /* Control LBRR */ - - /* Usage Control based on sensitivity and packet loss caracteristics */ - /* - * For now only enable adding to next for active frames. Make more - * complex later - */ - LBRR_usage = Silk_define.SKP_SILK_NO_LBRR; - if (psEnc.speech_activity > Silk_define_FLP.LBRR_SPEECH_ACTIVITY_THRES - && psEnc.sCmn.PacketLoss_perc > Silk_define.LBRR_LOSS_THRES) - { // nb! maybe multiply loss prob and speech activity - LBRR_usage = Silk_define.SKP_SILK_ADD_LBRR_TO_PLUS1; - } - psEncCtrl.LBRR_usage = LBRR_usage; - } else { - psEncCtrl.LBRR_usage = Silk_define.SKP_SILK_NO_LBRR; - } - } -} - -/** - * The NSQ callback implementation. - * - * @author Dingxin Xu - */ -class NSQImplNSQ implements NoiseShapingQuantizerFP -{ - public void NoiseShapingQuantizer(SKP_Silk_encoder_state psEnc, - SKP_Silk_encoder_control psEncCtrl, SKP_Silk_nsq_state NSQ, - short[] x, byte[] q, int arg6, short[] arg7, short[] arg8, - short[] arg9, int[] arg10, int[] arg11, int[] arg12, int[] arg13, - int arg14, int arg15) { - // TODO Auto-generated method stub - Silk_NSQ.SKP_Silk_NSQ(psEnc, psEncCtrl, NSQ, x, q, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } -} - -/** - * The NSQ callback implementation - * - * @author Dingxin Xu - */ -class NSQImplNSQDelDec implements NoiseShapingQuantizerFP -{ - public void NoiseShapingQuantizer(SKP_Silk_encoder_state psEnc, - SKP_Silk_encoder_control psEncCtrl, SKP_Silk_nsq_state NSQ, - short[] x, byte[] q, int arg6, short[] arg7, short[] arg8, - short[] arg9, int[] arg10, int[] arg11, int[] arg12, int[] arg13, - int arg14, int arg15) { - // TODO Auto-generated method stub - Silk_NSQ_del_dec.SKP_Silk_NSQ_del_dec(psEnc, psEncCtrl, NSQ, x, q, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_corrMatrix_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_corrMatrix_FLP.java deleted file mode 100644 index 43af48992..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_corrMatrix_FLP.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Correlation matrix computations for LS estimate. - * - * @author Dingxin Xu - */ -public class Silk_corrMatrix_FLP -{ - /** - * Calculates correlation vector X'*t. - * @param x x vector [L+order-1] used to create X. - * @param x_offset offset of valid data. - * @param t Target vector [L]. - * @param t_offset offset of valid data. - * @param L Length of vecors. - * @param Order Max lag for correlation. - * @param Xt X'*t correlation vector [order]. - */ - static void SKP_Silk_corrVector_FLP( - final float []x, /* I x vector [L+order-1] used to create X */ - int x_offset, - final float []t, /* I Target vector [L] */ - int t_offset, - final int L, /* I Length of vecors */ - final int Order, /* I Max lag for correlation */ - final float []Xt /* O X'*t correlation vector [order] */ - ) - { - int lag; - final float []ptr1; - int ptr1_offset; - - ptr1 = x; /* Points to first sample of column 0 of X: X[:,0] */ - ptr1_offset = x_offset + Order-1; - for( lag = 0; lag < Order; lag++ ) { - /* Calculate X[:,lag]'*t */ - Xt[lag] = (float) Silk_inner_product_FLP.SKP_Silk_inner_product_FLP(ptr1, ptr1_offset, t, t_offset, L); - ptr1_offset--; /* Next column of X */ - } - } - - /** - * Calculates correlation matrix X'*X. - * @param x x vector [ L+order-1 ] used to create X. - * @param x_offset offset of valid data. - * @param L Length of vectors. - * @param Order Max lag for correlation. - * @param XX X'*X correlation matrix [order x order]. - * @param XX_offset offset of valid data. - */ - static void SKP_Silk_corrMatrix_FLP( - final float []x, /* I x vector [ L+order-1 ] used to create X */ - int x_offset, - final int L, /* I Length of vectors */ - final int Order, /* I Max lag for correlation */ - float []XX, /* O X'*X correlation matrix [order x order] */ - int XX_offset - ) - { - int j, lag; - double energy; - final float ptr1[], ptr2[]; - int ptr1_offset, ptr2_offset; - - ptr1 = x; /* First sample of column 0 of X */ - ptr1_offset = x_offset + Order-1; - - energy = Silk_energy_FLP.SKP_Silk_energy_FLP(ptr1, ptr1_offset, L);/* X[:,0]'*X[:,0] */ - -// matrix_ptr( XX, 0, 0, Order ) = ( SKP_float )energy; - XX[XX_offset + 0] = (float) energy; - - for( j = 1; j < Order; j++ ) { - /* Calculate X[:,j]'*X[:,j] */ - energy += ptr1[ ptr1_offset -j ] * ptr1[ ptr1_offset-j ] - ptr1[ ptr1_offset + L - j ] * ptr1[ ptr1_offset + L - j ]; -// matrix_ptr( XX, j, j, Order ) = ( SKP_float )energy; - XX[XX_offset + j*Order+j] = (float) energy; - } - - ptr2 = x; /* First sample of column 1 of X */ - ptr2_offset = x_offset + Order - 2; - for( lag = 1; lag < Order; lag++ ) { - /* Calculate X[:,0]'*X[:,lag] */ -// matrix_ptr( XX, lag, 0, Order ) = ( SKP_float )energy; -// matrix_ptr( XX, 0, lag, Order ) = ( SKP_float )energy; - energy = Silk_inner_product_FLP.SKP_Silk_inner_product_FLP(ptr1, ptr1_offset, ptr2, ptr2_offset, L); - /* Calculate X[:,j]'*X[:,j + lag] */ - for( j = 1; j < ( Order - lag ); j++ ) { -// matrix_ptr( XX, lag + j, j, Order ) = ( SKP_float )energy; -// matrix_ptr( XX, j, lag + j, Order ) = ( SKP_float )energy; - energy += ptr1[ ptr1_offset-j ] * ptr2[ ptr2_offset-j ] - ptr1[ ptr1_offset + L - j ] * ptr2[ ptr2_offset + L - j ]; - XX[XX_offset + (lag+j)*Order + j] = (float) energy; - XX[XX_offset + j*Order + (lag+j)] = (float) energy; - } - ptr2_offset--; /* Next column of X */ - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_create_init_destroy.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_create_init_destroy.java deleted file mode 100644 index c53395e90..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_create_init_destroy.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Initialize decoder state. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_create_init_destroy -{ - /** - * Initialize decoder state. - * @param psDec the decoder state. - * @return - */ - static int SKP_Silk_init_decoder( - SKP_Silk_decoder_state psDec /* I/O Decoder state pointer */ - ) - { - //psDec = new SKP_Silk_decoder_state(); - - /* Set sampling rate to 24 kHz, and init non-zero values */ - Silk_decoder_set_fs.SKP_Silk_decoder_set_fs( psDec, 24 ); - - /* Used to deactivate e.g. LSF interpolation and fluctuation reduction */ - psDec.first_frame_after_reset = 1; - psDec.prev_inv_gain_Q16 = 65536; - - /* Reset CNG state */ - Silk_CNG.SKP_Silk_CNG_Reset( psDec ); - - Silk_PLC.SKP_Silk_PLC_Reset(psDec); - return(0); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_dec_API.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_dec_API.java deleted file mode 100644 index 197b476e6..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_dec_API.java +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -import java.util.*; - -/** - * The Decoder API. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_dec_API -{ - - /** - * Reset the decoder state. - * - * @param decState the decoder state - * @return ret - */ - static int SKP_Silk_SDK_InitDecoder( - Object decState /* I/O: State */ - ) - { - int ret = 0; - SKP_Silk_decoder_state struc; - struc = (SKP_Silk_decoder_state )decState; - ret = Silk_create_init_destroy.SKP_Silk_init_decoder( struc ); - - return ret; - } - - /** - * Decode a frame. - * - * @param decState the decoder state. - * @param decControl the decoder control. - * @param lostFlag the lost flag. 0: no loss; 1: loss. - * @param inData encoding input vector. - * @param inData_offset the actual data offset in the input vector. - * @param nBytesIn number of input bytes. - * @param samplesOut decoded output speech vector. - * @param samplesOut_offset the actual data offset in the output vector. - * @param nSamplesOut number of samples. - * @return the returned value carries the error message. - * 0 indicates OK; other indicates error. - */ - static int SKP_Silk_SDK_Decode( - Object decState, /* I/O: State */ - SKP_SILK_SDK_DecControlStruct decControl, /* I/O: Control structure */ - int lostFlag, /* I: 0: no loss, 1 loss */ - byte[] inData, /* I: Encoded input vector */ - int inData_offset, - final int nBytesIn, /* I: Number of input Bytes */ - short[] samplesOut, /* O: Decoded output speech vector */ - int samplesOut_offset, - short[] nSamplesOut /* I/O: Number of samples (vector/decoded) */ - ) - { - int ret = 0, used_bytes, prev_fs_kHz; - SKP_Silk_decoder_state psDec; - - psDec = (SKP_Silk_decoder_state )decState; - - /**********************************/ - /* Test if first frame in payload */ - /**********************************/ - if( psDec.moreInternalDecoderFrames == 0 ) { - /* First Frame in Payload */ - psDec.nFramesDecoded = 0; /* Used to count frames in packet */ - } - - if( psDec.moreInternalDecoderFrames == 0 && /* First frame in packet */ - lostFlag == 0 && /* Not packet loss */ - nBytesIn > Silk_define.MAX_ARITHM_BYTES ) { /* Too long payload */ - /* Avoid trying to decode a too large packet */ - lostFlag = 1; - ret = Silk_errors.SKP_SILK_DEC_PAYLOAD_TOO_LARGE; - } - - /* Save previous sample frequency */ - prev_fs_kHz = psDec.fs_kHz; - - /* Call decoder for one frame */ - int[] used_bytes_ptr =new int[1]; - ret += Silk_decode_frame.SKP_Silk_decode_frame( psDec, samplesOut, samplesOut_offset, nSamplesOut, inData, inData_offset, - nBytesIn, lostFlag, used_bytes_ptr ); - used_bytes = used_bytes_ptr[0]; - - if( used_bytes !=0) /* Only Call if not a packet loss */ - { - if( psDec.nBytesLeft > 0 && psDec.FrameTermination == Silk_define.SKP_SILK_MORE_FRAMES && psDec.nFramesDecoded < 5 ) { - /* We have more frames in the Payload */ - psDec.moreInternalDecoderFrames = 1; - } else { - /* Last frame in Payload */ - psDec.moreInternalDecoderFrames = 0; - psDec.nFramesInPacket = psDec.nFramesDecoded; - - /* Track inband FEC usage */ - if( psDec.vadFlag == Silk_define.VOICE_ACTIVITY ) { - if( psDec.FrameTermination == Silk_define.SKP_SILK_LAST_FRAME ) { - psDec.no_FEC_counter++; - if( psDec.no_FEC_counter > Silk_define.NO_LBRR_THRES ) { - psDec.inband_FEC_offset = 0; - } - } else if( psDec.FrameTermination == Silk_define.SKP_SILK_LBRR_VER1 ) { - psDec.inband_FEC_offset = 1; /* FEC info with 1 packet delay */ - psDec.no_FEC_counter = 0; - } else if( psDec.FrameTermination == Silk_define.SKP_SILK_LBRR_VER2 ) { - psDec.inband_FEC_offset = 2; /* FEC info with 2 packets delay */ - psDec.no_FEC_counter = 0; - } - } - } - } - - if( Silk_define.MAX_API_FS_KHZ * 1000 < decControl.API_sampleRate || - 8000 > decControl.API_sampleRate ) { - ret = Silk_errors.SKP_SILK_DEC_INVALID_SAMPLING_FREQUENCY; - return( ret ); - } - - /* Resample if needed */ - if( psDec.fs_kHz * 1000 != decControl.API_sampleRate ) { - short[] samplesOut_tmp = new short[Silk_define.MAX_API_FS_KHZ * Silk_define.FRAME_LENGTH_MS]; - Silk_typedef.SKP_assert( psDec.fs_kHz <= Silk_define.MAX_API_FS_KHZ ); - - /* Copy to a tmp buffer as the resampling writes to samplesOut */ - System.arraycopy(samplesOut, samplesOut_offset+0, samplesOut_tmp, 0, nSamplesOut[0]); - /* (Re-)initialize resampler state when switching internal sampling frequency */ - if( prev_fs_kHz != psDec.fs_kHz || psDec.prev_API_sampleRate != decControl.API_sampleRate ) { - ret = Silk_resampler.SKP_Silk_resampler_init( psDec.resampler_state, psDec.fs_kHz*1000, decControl.API_sampleRate ); - } - - /* Resample the output to API_sampleRate */ - ret += Silk_resampler.SKP_Silk_resampler( psDec.resampler_state, samplesOut, samplesOut_offset, samplesOut_tmp, 0, nSamplesOut[0]); - - /* Update the number of output samples */ - nSamplesOut[0] = (short)((nSamplesOut[0] * decControl.API_sampleRate) / (psDec.fs_kHz * 1000)); - } - - psDec.prev_API_sampleRate = decControl.API_sampleRate; - - /* Copy all parameters that are needed out of internal structure to the control stucture */ - decControl.frameSize = psDec.frame_length; - decControl.framesPerPacket = psDec.nFramesInPacket; - decControl.inBandFECOffset = psDec.inband_FEC_offset; - decControl.moreInternalDecoderFrames = psDec.moreInternalDecoderFrames; - - return ret; - } - - /** - * Find LBRR information in a packet. - * - * @param inData encoded input vector. - * @param inData_offset offset of the valid data. - * @param nBytesIn number of input bytes. - * @param lost_offset offset from lost packet. - * @param LBRRData LBRR payload. - * @param LBRRData_offset offset of the valid data. - * @param nLBRRBytes number of LBRR bytes. - */ - static void SKP_Silk_SDK_search_for_LBRR( - byte[] inData, /* I: Encoded input vector */ - int inData_offset, - final short nBytesIn, /* I: Number of input Bytes */ - int lost_offset, /* I: Offset from lost packet */ - byte[] LBRRData, /* O: LBRR payload */ - int LBRRData_offset, - short[] nLBRRBytes /* O: Number of LBRR Bytes */ - ) - { - SKP_Silk_decoder_state sDec = new SKP_Silk_decoder_state(); // Local decoder state to avoid interfering with running decoder */ - SKP_Silk_decoder_control sDecCtrl = new SKP_Silk_decoder_control(); - int[] TempQ = new int[ Silk_define.MAX_FRAME_LENGTH ]; - - if( lost_offset < 1 || lost_offset > Silk_define.MAX_LBRR_DELAY ) { - /* No useful FEC in this packet */ - nLBRRBytes[0] = 0; - return; - } - - sDec.nFramesDecoded = 0; - sDec.fs_kHz = 0; /* Force update parameters LPC_order etc */ - Arrays.fill(sDec.prevNLSF_Q15, 0, Silk_define.MAX_LPC_ORDER, 0); - - for(int i=0; i 0 && sDec.nBytesLeft >= 0 ) { - /* The wanted FEC is present in the packet */ - nLBRRBytes[0] = (short)sDec.nBytesLeft; - System.arraycopy(inData, inData_offset+nBytesIn - sDec.nBytesLeft, LBRRData, LBRRData_offset+0, sDec.nBytesLeft); - break; - } - if( sDec.nBytesLeft > 0 && sDec.FrameTermination == Silk_define.SKP_SILK_MORE_FRAMES ) { - sDec.nFramesDecoded++; - } else { - LBRRData = null; - nLBRRBytes[0] = 0; - break; - } - } - } - - /** - * Getting type of content for a packet. - * @param inData encoded input vector. - * @param nBytesIn number of input bytes. - * @param Silk_TOC type of content. - */ - static void SKP_Silk_SDK_get_TOC( - byte[] inData, /* I: Encoded input vector */ - final short nBytesIn, /* I: Number of input bytes */ - SKP_Silk_TOC_struct Silk_TOC /* O: Type of content */ - ) - { - SKP_Silk_decoder_state sDec = new SKP_Silk_decoder_state(); - SKP_Silk_decoder_control sDecCtrl = new SKP_Silk_decoder_control(); - int[] TempQ = new int[ Silk_define.MAX_FRAME_LENGTH ]; - - sDec.nFramesDecoded = 0; - sDec.fs_kHz = 0; /* Force update parameters LPC_order etc */ - Silk_range_coder.SKP_Silk_range_dec_init( sDec.sRC, inData, 0, nBytesIn ); - - Silk_TOC.corrupt = 0; - while( true ) { - Silk_decode_parameters.SKP_Silk_decode_parameters( sDec, sDecCtrl, TempQ, 0 ); - - Silk_TOC.vadFlags[ sDec.nFramesDecoded ] = sDec.vadFlag; - Silk_TOC.sigtypeFlags[ sDec.nFramesDecoded ] = sDecCtrl.sigtype; - - if( sDec.sRC.error != 0) { - /* Corrupt stream */ - Silk_TOC.corrupt = 1; - break; - } -//TODO:note the semicolon; -// }; - if( sDec.nBytesLeft > 0 && sDec.FrameTermination == Silk_define.SKP_SILK_MORE_FRAMES ) { - sDec.nFramesDecoded++; - } else { - break; - } - } - if( Silk_TOC.corrupt !=0 || sDec.FrameTermination == Silk_define.SKP_SILK_MORE_FRAMES || - sDec.nFramesInPacket > Silk_SDK_API.SILK_MAX_FRAMES_PER_PACKET ) { - /* Corrupt packet */ - { - Silk_TOC.corrupt = 0; - Silk_TOC.framesInPacket = 0; - Silk_TOC.fs_kHz = 0; - Silk_TOC.inbandLBRR = 0; - - for(int i=0; i>31; - - psDec.exc_Q10[ i ] = (q[ i ] << 10) + offset_Q10; - psDec.exc_Q10[ i ] = ( psDec.exc_Q10[ i ] ^ dither ) - dither; - - rand_seed += q[ i ]; - } - - - pexc_Q10 = psDec.exc_Q10; - pexc_Q10_offset = 0; - - pres_Q10 = psDec.res_Q10; - pres_Q10_offset = 0; - - pxq = psDec.outBuf; - pxq_offset = psDec.frame_length; - - psDec.sLTP_buf_idx = psDec.frame_length; - /* Loop over subframes */ - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - A_Q12 = psDecCtrl.PredCoef_Q12[ k >> 1 ]; - - /* Preload LPC coeficients to array on stack. Gives small performance gain */ - System.arraycopy(A_Q12, 0, A_Q12_tmp, 0, psDec.LPC_order); - - B_Q14 = psDecCtrl.LTPCoef_Q14; - B_Q14_offset = k*Silk_define.LTP_ORDER; - - Gain_Q16 = psDecCtrl.Gains_Q16[ k ]; - LTP_scale_Q14 = psDecCtrl.LTP_scale_Q14; - sigtype = psDecCtrl.sigtype; - - inv_gain_Q16 = Silk_typedef.SKP_int32_MAX/(Gain_Q16>>1); - inv_gain_Q16 = Math.min(inv_gain_Q16, Silk_typedef.SKP_int16_MAX); - - /* Calculate Gain adjustment factor */ - gain_adj_Q16 = 1 << 16; - if( inv_gain_Q16 != psDec.prev_inv_gain_Q16 ) { - gain_adj_Q16 = Silk_Inlines.SKP_DIV32_varQ( inv_gain_Q16, psDec.prev_inv_gain_Q16, 16 ); - } - - /* Avoid abrupt transition from voiced PLC to unvoiced normal decoding */ - if( psDec.lossCnt !=0 && psDec.prev_sigtype == Silk_define.SIG_TYPE_VOICED && - psDecCtrl.sigtype == Silk_define.SIG_TYPE_UNVOICED && k < ( Silk_define.NB_SUBFR >> 1 ) ) { - - Arrays.fill(B_Q14, B_Q14_offset, B_Q14_offset+Silk_define.LTP_ORDER, (short)0); - - B_Q14[ B_Q14_offset + Silk_define.LTP_ORDER/2 ] = ( short )1 << 12; /* 0.25 */ - - sigtype = Silk_define.SIG_TYPE_VOICED; - psDecCtrl.pitchL[ k ] = psDec.lagPrev; - LTP_scale_Q14 = 1 << 14; - } - - if( sigtype == Silk_define.SIG_TYPE_VOICED ) { - /* Voiced */ - - lag = psDecCtrl.pitchL[ k ]; - /* Re-whitening */ - if( ( k & ( 3 - (NLSF_interpolation_flag << 1))) == 0 ) { - /* Rewhiten with new A coefs */ - start_idx = psDec.frame_length - lag - psDec.LPC_order - Silk_define.LTP_ORDER / 2; - start_idx = Silk_SigProc_FIX.SKP_LIMIT_int( start_idx, 0, psDec.frame_length - psDec.LPC_order ); - - Arrays.fill(FiltState, 0, psDec.LPC_order, 0); - - Silk_MA.SKP_Silk_MA_Prediction( psDec.outBuf, start_idx + k * ( psDec.frame_length >> 2 ), - A_Q12, 0, FiltState, sLTP, start_idx, psDec.frame_length - start_idx, psDec.LPC_order ); - - - /* After rewhitening the LTP state is unscaled */ - inv_gain_Q32 = ( inv_gain_Q16 << 16 ); - - if( k == 0 ) { - /* Do LTP downscaling */ - inv_gain_Q32 = ( Silk_macros.SKP_SMULWB( inv_gain_Q32, psDecCtrl.LTP_scale_Q14 )<< 2 ); - } - for( i = 0; i < (lag + Silk_define.LTP_ORDER/2); i++ ) { - psDec.sLTP_Q16[ psDec.sLTP_buf_idx - i - 1 ] = Silk_macros.SKP_SMULWB( inv_gain_Q32, sLTP[ psDec.frame_length - i - 1 ] ); - } - } else { - /* Update LTP state when Gain changes */ - if( gain_adj_Q16 != 1 << 16 ) { - for( i = 0; i < ( lag + Silk_define.LTP_ORDER / 2 ); i++ ) { - psDec.sLTP_Q16[ psDec.sLTP_buf_idx - i - 1 ] = Silk_macros.SKP_SMULWW( gain_adj_Q16, psDec.sLTP_Q16[ psDec.sLTP_buf_idx - i - 1 ] ); - } - } - } - } - - /* Scale short term state */ - for( i = 0; i < Silk_define.MAX_LPC_ORDER; i++ ) { - psDec.sLPC_Q14[ i ] = Silk_macros.SKP_SMULWW( gain_adj_Q16, psDec.sLPC_Q14[ i ] ); - } - - /* Save inv_gain */ - Silk_typedef.SKP_assert( inv_gain_Q16 != 0 ); - psDec.prev_inv_gain_Q16 = inv_gain_Q16; - - /* Long-term prediction */ - if( sigtype == Silk_define.SIG_TYPE_VOICED ) { - /* Setup pointer */ - pred_lag_ptr = psDec.sLTP_Q16; - pred_lag_ptr_offset = psDec.sLTP_buf_idx - lag + Silk_define.LTP_ORDER / 2; - - for( i = 0; i < psDec.subfr_length; i++ ) { - /* Unrolled loop */ - LTP_pred_Q14 = Silk_macros.SKP_SMULWB( pred_lag_ptr[ pred_lag_ptr_offset +0 ], B_Q14[ B_Q14_offset + 0 ] ); - LTP_pred_Q14 = Silk_macros.SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ pred_lag_ptr_offset -1 ], B_Q14[ B_Q14_offset + 1 ] ); - LTP_pred_Q14 = Silk_macros.SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ pred_lag_ptr_offset -2 ], B_Q14[ B_Q14_offset + 2 ] ); - LTP_pred_Q14 = Silk_macros.SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ pred_lag_ptr_offset -3 ], B_Q14[ B_Q14_offset + 3 ] ); - LTP_pred_Q14 = Silk_macros.SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ pred_lag_ptr_offset -4 ], B_Q14[ B_Q14_offset + 4 ] ); - pred_lag_ptr_offset++; - - /* Generate LPC residual */ - pres_Q10[ pres_Q10_offset + i ] = ( pexc_Q10[ pexc_Q10_offset + i ] + Silk_SigProc_FIX.SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ) ); - - /* Update states */ - psDec.sLTP_Q16[ psDec.sLTP_buf_idx ] = ( pres_Q10[ pres_Q10_offset + i ]<< 6 ); - psDec.sLTP_buf_idx++; - } - } else { - System.arraycopy(pexc_Q10, pexc_Q10_offset + 0, pres_Q10, pres_Q10_offset + 0, psDec.subfr_length); - } - - - for( i = 0; i < psDec.subfr_length; i++ ) { - /* Partially unrolled */ - LPC_pred_Q10 = Silk_macros.SKP_SMULWB( psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 2 ], A_Q12_tmp[ 1 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 3 ], A_Q12_tmp[ 2 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 4 ], A_Q12_tmp[ 3 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 5 ], A_Q12_tmp[ 4 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 6 ], A_Q12_tmp[ 5 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 7 ], A_Q12_tmp[ 6 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 8 ], A_Q12_tmp[ 7 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 9 ], A_Q12_tmp[ 8 ] ); - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - 10 ], A_Q12_tmp[ 9 ] ); - - for( j = 10; j < psDec.LPC_order; j ++ ) { - LPC_pred_Q10 = Silk_macros.SKP_SMLAWB( LPC_pred_Q10, psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i - j - 1 ], A_Q12_tmp[ j ] ); - } - - /* Add prediction to LPC residual */ - vec_Q10[ i ] = ( pres_Q10[ pres_Q10_offset + i ]+ LPC_pred_Q10 ); - - /* Update states */ - psDec.sLPC_Q14[ Silk_define.MAX_LPC_ORDER + i ] = ( vec_Q10[ i ]<< 4 ); - } - /* Scale with Gain */ - for( i = 0; i < psDec.subfr_length; i++ ) { - pxq[ pxq_offset+i ] = ( short )Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( Silk_macros.SKP_SMULWW( vec_Q10[ i ], Gain_Q16 ), 10 ) ); - } - - /* Update LPC filter state */ - System.arraycopy(psDec.sLPC_Q14, psDec.subfr_length, psDec.sLPC_Q14, 0, Silk_define.MAX_LPC_ORDER); - - pexc_Q10_offset += psDec.subfr_length; - pres_Q10_offset += psDec.subfr_length; - pxq_offset += psDec.subfr_length; - } - - /* Copy to output */ - System.arraycopy(psDec.outBuf, psDec.frame_length, xq, xq_offset+0, psDec.frame_length); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decode_frame.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decode_frame.java deleted file mode 100644 index 97e87b7d9..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decode_frame.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Decode frame - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_decode_frame -{ - /** - * Decode frame. - * @param psDec reference to Silk decoder state. - * @param pOut reference to output speech frame. - * @param pOut_offset offset of the valid data. - * @param pN reference to size of output frame. - * @param pCode reference to payload. - * @param pCode_offset offset the valid data. - * @param nBytes payload length. - * @param action action from Jitter buffer. - * @param decBytes Used bytes to decoder this frame. - * @return the returned value carries the error message. - * 0 indicates OK; other indicates error. - */ - static int SKP_Silk_decode_frame( - SKP_Silk_decoder_state psDec, /* I/O Pointer to Silk decoder state */ - short[] pOut, /* O Pointer to output speech frame */ - int pOut_offset, - short[] pN, /* O Pointer to size of output frame */ - byte[] pCode, /* I Pointer to payload */ - int pCode_offset, - final int nBytes, /* I Payload length */ - int action, /* I Action from Jitter Buffer */ - int[] decBytes /* O Used bytes to decode this frame */ - ) - { - SKP_Silk_decoder_control sDecCtrl = new SKP_Silk_decoder_control(); - int L, fs_Khz_old, LPC_order_old, ret = 0; - int[] Pulses = new int[ Silk_define.MAX_FRAME_LENGTH ]; - - - L = psDec.frame_length; - sDecCtrl.LTP_scale_Q14 = 0; - - /* Safety checks */ - Silk_typedef.SKP_assert( L > 0 && L <= Silk_define.MAX_FRAME_LENGTH ); - - /********************************************/ - /* Decode Frame if packet is not lost */ - /********************************************/ - decBytes[0] = 0; - if( action == 0 ) { - /********************************************/ - /* Initialize arithmetic coder */ - /********************************************/ - fs_Khz_old = psDec.fs_kHz; - LPC_order_old = psDec.LPC_order; - if( psDec.nFramesDecoded == 0 ) { - /* Initialize range decoder state */ - Silk_range_coder.SKP_Silk_range_dec_init( psDec.sRC, pCode, pCode_offset, nBytes ); - } - - /********************************************/ - /* Decode parameters and pulse signal */ - /********************************************/ - Silk_decode_parameters.SKP_Silk_decode_parameters( psDec, sDecCtrl, Pulses, 1 ); - - if( psDec.sRC.error !=0 ) { - psDec.nBytesLeft = 0; - - action = 1; /* PLC operation */ - /* revert fs if changed in decode_parameters */ - Silk_decoder_set_fs.SKP_Silk_decoder_set_fs( psDec, fs_Khz_old ); - - /* Avoid crashing */ - decBytes[0] = psDec.sRC.bufferLength; - - if( psDec.sRC.error == Silk_define.RANGE_CODER_DEC_PAYLOAD_TOO_LONG ) { - ret = Silk_errors.SKP_SILK_DEC_PAYLOAD_TOO_LARGE; - } else { - ret = Silk_errors.SKP_SILK_DEC_PAYLOAD_ERROR; - } - } else { - decBytes[0] = psDec.sRC.bufferLength - psDec.nBytesLeft; - psDec.nFramesDecoded++; - - /* Update lengths. Sampling frequency could have changed */ - L = psDec.frame_length; - - /********************************************************/ - /* Run inverse NSQ */ - /********************************************************/ - Silk_decode_core.SKP_Silk_decode_core( psDec, sDecCtrl, pOut, pOut_offset, Pulses ); - - /********************************************************/ - /* Update PLC state */ - /********************************************************/ - Silk_PLC.SKP_Silk_PLC( psDec, sDecCtrl, pOut, pOut_offset, L, action ); - - psDec.lossCnt = 0; - psDec.prev_sigtype = sDecCtrl.sigtype; - - /* A frame has been decoded without errors */ - psDec.first_frame_after_reset = 0; - } - } - /*************************************************************/ - /* Generate Concealment Frame if packet is lost, or corrupt */ - /*************************************************************/ - if( action == 1 ) { - /* Handle packet loss by extrapolation */ - Silk_PLC.SKP_Silk_PLC( psDec, sDecCtrl, pOut, pOut_offset, L, action ); - psDec.lossCnt++; - - } - - /*************************/ - /* Update output buffer. */ - /*************************/ - System.arraycopy(pOut, pOut_offset+0, psDec.outBuf, 0, L ); - - /****************************************************************/ - /* Ensure smooth connection of extrapolated and good frames */ - /****************************************************************/ - Silk_PLC.SKP_Silk_PLC_glue_frames( psDec, sDecCtrl, pOut, pOut_offset, L ); - - /************************************************/ - /* Comfort noise generation / estimation */ - /************************************************/ - Silk_CNG.SKP_Silk_CNG( psDec, sDecCtrl, pOut , pOut_offset, L ); - - /********************************************/ - /* HP filter output */ - /********************************************/ - Silk_typedef.SKP_assert( ( ( psDec.fs_kHz == 12 ) && ( L % 3 ) == 0 ) || - ( ( psDec.fs_kHz != 12 ) && ( L % 2 ) == 0 ) ); - Silk_biquad.SKP_Silk_biquad( pOut, pOut_offset, psDec.HP_B, psDec.HP_A, psDec.HPState, pOut, pOut_offset, L ); - - /********************************************/ - /* set output frame length */ - /********************************************/ - pN[0] = (short)L; - - /* Update some decoder state variables */ - psDec.lagPrev = sDecCtrl.pitchL[ Silk_define.NB_SUBFR - 1 ]; - - return ret; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decode_parameters.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decode_parameters.java deleted file mode 100644 index 8d9ab56b2..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decode_parameters.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -import java.util.*; - -/** - * Decode parameters from payload - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_decode_parameters -{ - /** - * Decode parameters from payload. - * @param psDec decoder state. - * @param psDecCtrl Decoder control. - * @param q Excitation signal - * @param fullDecoding Flag to tell if only arithmetic decoding - */ - static void SKP_Silk_decode_parameters( - SKP_Silk_decoder_state psDec, /* I/O State */ - SKP_Silk_decoder_control psDecCtrl, /* I/O Decoder control */ - int[] q, /* O Excitation signal */ - final int fullDecoding /* I Flag to tell if only arithmetic decoding */ - ) - { - int i, k, Ix, fs_kHz_dec, nBytesUsed; - int[] Ix_ptr = new int[1]; - int[] Ixs = new int[ Silk_define.NB_SUBFR ]; - int[] GainsIndices = new int[ Silk_define.NB_SUBFR ]; - int[] NLSFIndices = new int[ Silk_define.NLSF_MSVQ_MAX_CB_STAGES ]; - int[] pNLSF_Q15 = new int[ Silk_define.MAX_LPC_ORDER ]; - int [] pNLSF0_Q15 = new int[ Silk_define.MAX_LPC_ORDER ]; - - short[] cbk_ptr_Q14; - SKP_Silk_NLSF_CB_struct psNLSF_CB = null; - - SKP_Silk_range_coder_state psRC = psDec.sRC; - /************************/ - /* Decode sampling rate */ - /************************/ - /* only done for first frame of packet */ - if( psDec.nFramesDecoded == 0 ) { - Silk_range_coder.SKP_Silk_range_decoder( Ix_ptr, 0, psRC, Silk_tables_other.SKP_Silk_SamplingRates_CDF, 0, Silk_tables_other.SKP_Silk_SamplingRates_offset ); - Ix = Ix_ptr[0]; - - /* check that sampling rate is supported */ - if( Ix < 0 || Ix > 3 ) { - psRC.error = Silk_define.RANGE_CODER_ILLEGAL_SAMPLING_RATE; - return; - } - fs_kHz_dec = Silk_tables_other.SKP_Silk_SamplingRates_table[ Ix ]; - Silk_decoder_set_fs.SKP_Silk_decoder_set_fs( psDec, fs_kHz_dec ); - } - - /*******************************************/ - /* Decode signal type and quantizer offset */ - /*******************************************/ - if( psDec.nFramesDecoded == 0 ) { - /* first frame in packet: independent coding */ - Silk_range_coder.SKP_Silk_range_decoder( Ix_ptr, 0, psRC, Silk_tables_type_offset.SKP_Silk_type_offset_CDF, 0, Silk_tables_type_offset.SKP_Silk_type_offset_CDF_offset ); - Ix = Ix_ptr[0]; - } else { - /* condidtional coding */ - Silk_range_coder.SKP_Silk_range_decoder( Ix_ptr, 0, psRC, Silk_tables_type_offset.SKP_Silk_type_offset_joint_CDF[ psDec.typeOffsetPrev ], 0, - Silk_tables_type_offset.SKP_Silk_type_offset_CDF_offset ); - Ix = Ix_ptr[0]; - } - psDecCtrl.sigtype = Ix>>1; - psDecCtrl.QuantOffsetType = Ix & 1; - psDec.typeOffsetPrev = Ix; - - /****************/ - /* Decode gains */ - /****************/ - /* first subframe */ - if( psDec.nFramesDecoded == 0 ) { - /* first frame in packet: independent coding */ - Silk_range_coder.SKP_Silk_range_decoder( GainsIndices, 0, psRC, Silk_tables_gain.SKP_Silk_gain_CDF[ psDecCtrl.sigtype ], 0, Silk_tables_gain.SKP_Silk_gain_CDF_offset ); - } else { - /* condidtional coding */ - Silk_range_coder.SKP_Silk_range_decoder( GainsIndices, 0, psRC, Silk_tables_gain.SKP_Silk_delta_gain_CDF, 0, Silk_tables_gain.SKP_Silk_delta_gain_CDF_offset ); - } - - /* remaining subframes */ - for( i = 1; i < Silk_define.NB_SUBFR; i++ ) { - Silk_range_coder.SKP_Silk_range_decoder( GainsIndices, i, psRC, Silk_tables_gain.SKP_Silk_delta_gain_CDF, 0, Silk_tables_gain.SKP_Silk_delta_gain_CDF_offset ); - } - - /* Dequant Gains */ - int LastGainIndex_ptr[] = new int[1]; - LastGainIndex_ptr[0] = psDec.LastGainIndex; - Silk_gain_quant.SKP_Silk_gains_dequant( psDecCtrl.Gains_Q16, GainsIndices, LastGainIndex_ptr, psDec.nFramesDecoded ); - psDec.LastGainIndex = LastGainIndex_ptr[0]; - - /****************/ - /* Decode NLSFs */ - /****************/ - /* Set pointer to NLSF VQ CB for the current signal type */ - psNLSF_CB = psDec.psNLSF_CB[ psDecCtrl.sigtype ]; - - /* Arithmetically decode NLSF path */ - Silk_range_coder.SKP_Silk_range_decoder_multi( NLSFIndices, psRC, psNLSF_CB.StartPtr, psNLSF_CB.MiddleIx, psNLSF_CB.nStages ); - - - /* From the NLSF path, decode an NLSF vector */ - Silk_NLSF_MSVQ_decode.SKP_Silk_NLSF_MSVQ_decode( pNLSF_Q15, psNLSF_CB, NLSFIndices, psDec.LPC_order ); - - - /************************************/ - /* Decode NLSF interpolation factor */ - /************************************/ - int[] NLSFInterpCoef_Q2_ptr = new int[1]; - NLSFInterpCoef_Q2_ptr[0] = psDecCtrl.NLSFInterpCoef_Q2; - - Silk_range_coder.SKP_Silk_range_decoder( NLSFInterpCoef_Q2_ptr, 0, psRC, Silk_tables_other.SKP_Silk_NLSF_interpolation_factor_CDF, 0, - Silk_tables_other.SKP_Silk_NLSF_interpolation_factor_offset ); - psDecCtrl.NLSFInterpCoef_Q2 = NLSFInterpCoef_Q2_ptr[0]; - - /* If just reset, e.g., because internal Fs changed, do not allow interpolation */ - /* improves the case of packet loss in the first frame after a switch */ - if( psDec.first_frame_after_reset == 1 ) { - psDecCtrl.NLSFInterpCoef_Q2 = 4; - } - - if( fullDecoding !=0) { - /* Convert NLSF parameters to AR prediction filter coefficients */ - Silk_NLSF2A_stable.SKP_Silk_NLSF2A_stable( psDecCtrl.PredCoef_Q12[ 1 ], pNLSF_Q15, psDec.LPC_order ); - if( psDecCtrl.NLSFInterpCoef_Q2 < 4 ) { - /* Calculation of the interpolated NLSF0 vector from the interpolation factor, */ - /* the previous NLSF1, and the current NLSF1 */ - for( i = 0; i < psDec.LPC_order; i++ ) { - pNLSF0_Q15[ i ] = psDec.prevNLSF_Q15[ i ] + ( ( psDecCtrl.NLSFInterpCoef_Q2 * - ( pNLSF_Q15[ i ] - psDec.prevNLSF_Q15[ i ] ) ) >> 2 ); - } - - /* Convert NLSF parameters to AR prediction filter coefficients */ - Silk_NLSF2A_stable.SKP_Silk_NLSF2A_stable( psDecCtrl.PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec.LPC_order ); - } else { - /* Copy LPC coefficients for first half from second half */ - System.arraycopy(psDecCtrl.PredCoef_Q12[1], 0, psDecCtrl.PredCoef_Q12[0], 0, psDec.LPC_order); - } - } - - System.arraycopy(pNLSF_Q15, 0, psDec.prevNLSF_Q15, 0, psDec.LPC_order); - - /* After a packet loss do BWE of LPC coefs */ - if( psDec.lossCnt !=0 ) { - Silk_bwexpander.SKP_Silk_bwexpander( psDecCtrl.PredCoef_Q12[ 0 ], psDec.LPC_order, Silk_define.BWE_AFTER_LOSS_Q16 ); - Silk_bwexpander.SKP_Silk_bwexpander( psDecCtrl.PredCoef_Q12[ 1 ], psDec.LPC_order, Silk_define.BWE_AFTER_LOSS_Q16 ); - } - - if( psDecCtrl.sigtype == Silk_define.SIG_TYPE_VOICED ) { - /*********************/ - /* Decode pitch lags */ - /*********************/ - /* Get lag index */ - if( psDec.fs_kHz == 8 ) { - Silk_range_coder.SKP_Silk_range_decoder(Ixs, 0, psRC, Silk_tables_pitch_lag.SKP_Silk_pitch_lag_NB_CDF, 0, Silk_tables_pitch_lag.SKP_Silk_pitch_lag_NB_CDF_offset); - } else if( psDec.fs_kHz == 12 ) { - Silk_range_coder.SKP_Silk_range_decoder(Ixs, 0, psRC, Silk_tables_pitch_lag.SKP_Silk_pitch_lag_MB_CDF, 0, Silk_tables_pitch_lag.SKP_Silk_pitch_lag_MB_CDF_offset); - } else if( psDec.fs_kHz == 16 ) { - Silk_range_coder.SKP_Silk_range_decoder(Ixs, 0, psRC, Silk_tables_pitch_lag.SKP_Silk_pitch_lag_WB_CDF, 0, Silk_tables_pitch_lag.SKP_Silk_pitch_lag_WB_CDF_offset); - } else { - Silk_range_coder.SKP_Silk_range_decoder(Ixs, 0, psRC, Silk_tables_pitch_lag.SKP_Silk_pitch_lag_SWB_CDF, 0, Silk_tables_pitch_lag.SKP_Silk_pitch_lag_SWB_CDF_offset); - } - - /* Get countour index */ - if( psDec.fs_kHz == 8 ) { - /* Less codevectors used in 8 khz mode */ - Silk_range_coder.SKP_Silk_range_decoder(Ixs, 1, psRC, Silk_tables_pitch_lag.SKP_Silk_pitch_contour_NB_CDF, 0, Silk_tables_pitch_lag.SKP_Silk_pitch_contour_NB_CDF_offset); - } else { - /* Joint for 12, 16, and 24 khz */ -// SKP_Silk_range_decoder( &Ixs[ 1 ], psRC, SKP_Silk_pitch_contour_CDF, SKP_Silk_pitch_contour_CDF_offset ); - Silk_range_coder.SKP_Silk_range_decoder( Ixs, 1, psRC, Silk_tables_pitch_lag.SKP_Silk_pitch_contour_CDF, 0, Silk_tables_pitch_lag.SKP_Silk_pitch_contour_CDF_offset ); - } - - /* Decode pitch values */ - Silk_decode_pitch.SKP_Silk_decode_pitch( Ixs[ 0 ], Ixs[ 1 ], psDecCtrl.pitchL, psDec.fs_kHz ); - - /********************/ - /* Decode LTP gains */ - /********************/ - /* Decode PERIndex value */ - int PERIndex_ptr[] = new int[1]; - PERIndex_ptr[0] = psDecCtrl.PERIndex; - - Silk_range_coder.SKP_Silk_range_decoder( PERIndex_ptr, 0, psRC, Silk_tables_LTP.SKP_Silk_LTP_per_index_CDF, 0, - Silk_tables_LTP.SKP_Silk_LTP_per_index_CDF_offset ); - psDecCtrl.PERIndex = PERIndex_ptr[0]; - - /* Decode Codebook Index */ - cbk_ptr_Q14 = Silk_tables_LTP.SKP_Silk_LTP_vq_ptrs_Q14[ psDecCtrl.PERIndex ]; // set pointer to start of codebook - - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - Silk_range_coder.SKP_Silk_range_decoder( Ix_ptr, 0, psRC, Silk_tables_LTP.SKP_Silk_LTP_gain_CDF_ptrs[psDecCtrl.PERIndex], 0 , - Silk_tables_LTP.SKP_Silk_LTP_gain_CDF_offsets[ psDecCtrl.PERIndex ] ); - Ix = Ix_ptr[0]; - for( i = 0; i < Silk_define.LTP_ORDER; i++ ) { - psDecCtrl.LTPCoef_Q14[ Silk_macros.SKP_SMULBB( k, Silk_define.LTP_ORDER ) + i ] = cbk_ptr_Q14[ Silk_macros.SKP_SMULBB( Ix, Silk_define.LTP_ORDER ) + i ]; - } - } - - /**********************/ - /* Decode LTP scaling */ - /**********************/ - Silk_range_coder.SKP_Silk_range_decoder( Ix_ptr, 0, psRC, Silk_tables_other.SKP_Silk_LTPscale_CDF, 0, Silk_tables_other.SKP_Silk_LTPscale_offset ); - Ix = Ix_ptr[0]; - psDecCtrl.LTP_scale_Q14 = Silk_tables_other.SKP_Silk_LTPScales_table_Q14[ Ix ]; - } else { - Arrays.fill(psDecCtrl.pitchL, 0, Silk_define.NB_SUBFR, 0); - Arrays.fill(psDecCtrl.LTPCoef_Q14, 0, Silk_define.NB_SUBFR, (short)0); - psDecCtrl.PERIndex = 0; - psDecCtrl.LTP_scale_Q14 = 0; - } - - /***************/ - /* Decode seed */ - /***************/ - Silk_range_coder.SKP_Silk_range_decoder( Ix_ptr, 0, psRC, Silk_tables_other.SKP_Silk_Seed_CDF, 0, Silk_tables_other.SKP_Silk_Seed_offset ); - Ix = Ix_ptr[0]; - psDecCtrl.Seed = Ix; - /*********************************************/ - /* Decode quantization indices of excitation */ - /*********************************************/ - Silk_decode_pulses.SKP_Silk_decode_pulses( psRC, psDecCtrl, q, psDec.frame_length ); - - /*********************************************/ - /* Decode VAD flag */ - /*********************************************/ - int[] vadFlag_ptr = new int[1]; - vadFlag_ptr[0] = psDec.vadFlag; - Silk_range_coder.SKP_Silk_range_decoder( vadFlag_ptr, 0, psRC, Silk_tables_other.SKP_Silk_vadflag_CDF, 0, Silk_tables_other.SKP_Silk_vadflag_offset ); - psDec.vadFlag = vadFlag_ptr[0]; - - /**************************************/ - /* Decode Frame termination indicator */ - /**************************************/ - int[] FrameTermination_ptr = new int[1]; - FrameTermination_ptr[0] = psDec.FrameTermination; - Silk_range_coder.SKP_Silk_range_decoder( FrameTermination_ptr, 0, psRC, Silk_tables_other.SKP_Silk_FrameTermination_CDF, 0, Silk_tables_other.SKP_Silk_FrameTermination_offset ); - psDec.FrameTermination = FrameTermination_ptr[0]; - - /****************************************/ - /* get number of bytes used so far */ - /****************************************/ - int nBytesUsed_ptr[] = new int[1]; - Silk_range_coder.SKP_Silk_range_coder_get_length( psRC, nBytesUsed_ptr ); - nBytesUsed = nBytesUsed_ptr[0]; - - psDec.nBytesLeft = psRC.bufferLength - nBytesUsed; - if( psDec.nBytesLeft < 0 ) { - psRC.error = Silk_define.RANGE_CODER_READ_BEYOND_BUFFER; - } - - /****************************************/ - /* check remaining bits in last byte */ - /****************************************/ - if( psDec.nBytesLeft == 0 ) { - Silk_range_coder.SKP_Silk_range_coder_check_after_decoding( psRC ); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decode_pitch.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decode_pitch.java deleted file mode 100644 index 25f7f0853..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decode_pitch.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Pitch analyzer function. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_decode_pitch -{ - /** - * Pitch analyzer function. - * @param lagIndex - * @param contourIndex - * @param pitch_lags 4 pitch values. - * @param Fs_kHz sampling frequency(kHz). - */ - static void SKP_Silk_decode_pitch( - int lagIndex, /* I */ - int contourIndex, /* O */ - int pitch_lags[], /* O 4 pitch values */ - int Fs_kHz /* I sampling frequency (kHz) */ - ) - { - int lag, i, min_lag; - - min_lag = Silk_macros.SKP_SMULBB(Silk_common_pitch_est_defines.PITCH_EST_MIN_LAG_MS, Fs_kHz); - - /* Only for 24 / 16 kHz version for now */ - lag = min_lag + lagIndex; - if( Fs_kHz == 8 ) { - /* Only a small codebook for 8 khz */ - for( i = 0; i < Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR; i++ ) { - pitch_lags[ i ] = lag + Silk_pitch_est_tables.SKP_Silk_CB_lags_stage2[ i ][ contourIndex ]; - } - } else { - for( i = 0; i < Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR; i++ ) { - pitch_lags[ i ] = lag + Silk_pitch_est_tables.SKP_Silk_CB_lags_stage3[ i ][ contourIndex ]; - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decode_pulses.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decode_pulses.java deleted file mode 100644 index 06acfaf19..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decode_pulses.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -import java.util.*; - -/** - * Decode quantization indices of excitation. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_decode_pulses -{ - /** - * Decode quantization indices of excitation. - * @param psRC Range coder state. - * @param psDecCtrl Decoder control. - * @param q Excitation signal. - * @param frame_length Frame length (preliminary). - */ - static void SKP_Silk_decode_pulses( - SKP_Silk_range_coder_state psRC, /* I/O Range coder state */ - SKP_Silk_decoder_control psDecCtrl, /* I/O Decoder control */ - int q[], /* O Excitation signal */ - final int frame_length /* I Frame length (preliminary) */ - ) - { - int i, j, k, iter, abs_q, nLS, bit; - int[] sum_pulses = new int[ Silk_define.MAX_NB_SHELL_BLOCKS ]; - int[] nLshifts = new int[ Silk_define.MAX_NB_SHELL_BLOCKS ]; - int[] pulses_ptr; - int pulses_ptr_offset; - int[] cdf_ptr; - - /*********************/ - /* Decode rate level */ - /*********************/ - int RateLevelIndex_ptr[] = new int[1]; - RateLevelIndex_ptr[0] = psDecCtrl.RateLevelIndex; - Silk_range_coder.SKP_Silk_range_decoder( RateLevelIndex_ptr, 0, psRC, - Silk_tables_pulses_per_block.SKP_Silk_rate_levels_CDF[ psDecCtrl.sigtype ], 0, Silk_tables_pulses_per_block.SKP_Silk_rate_levels_CDF_offset ); - psDecCtrl.RateLevelIndex = RateLevelIndex_ptr[0]; - - /* Calculate number of shell blocks */ - iter = frame_length / Silk_define.SHELL_CODEC_FRAME_LENGTH; - - /***************************************************/ - /* Sum-Weighted-Pulses Decoding */ - /***************************************************/ - cdf_ptr = Silk_tables_pulses_per_block.SKP_Silk_pulses_per_block_CDF[ psDecCtrl.RateLevelIndex ]; - - for( i = 0; i < iter; i++ ) { - nLshifts[ i ] = 0; - Silk_range_coder.SKP_Silk_range_decoder( sum_pulses, i, psRC, cdf_ptr, 0, Silk_tables_pulses_per_block.SKP_Silk_pulses_per_block_CDF_offset ); - - /* LSB indication */ - while( sum_pulses[ i ] == ( Silk_define.MAX_PULSES + 1 ) ) { - nLshifts[ i ]++; - Silk_range_coder.SKP_Silk_range_decoder( sum_pulses, i, psRC, - Silk_tables_pulses_per_block.SKP_Silk_pulses_per_block_CDF[ Silk_define.N_RATE_LEVELS - 1 ], 0, Silk_tables_pulses_per_block.SKP_Silk_pulses_per_block_CDF_offset ); - } - } - - /***************************************************/ - /* Shell decoding */ - /***************************************************/ - for( i = 0; i < iter; i++ ) { - if( sum_pulses[ i ] > 0 ) { - Silk_shell_coder.SKP_Silk_shell_decoder( q, Silk_macros.SKP_SMULBB( i, Silk_define.SHELL_CODEC_FRAME_LENGTH ), psRC, sum_pulses[ i ] ); - } else { - Arrays.fill(q, (Silk_macros.SKP_SMULBB(i, Silk_define.SHELL_CODEC_FRAME_LENGTH)), - ((Silk_macros.SKP_SMULBB(i, Silk_define.SHELL_CODEC_FRAME_LENGTH)) + Silk_define.SHELL_CODEC_FRAME_LENGTH), 0); - } - } - - /***************************************************/ - /* LSB Decoding */ - /***************************************************/ - for( i = 0; i < iter; i++ ) { - if( nLshifts[ i ] > 0 ) { - nLS = nLshifts[ i ]; - pulses_ptr = q; - pulses_ptr_offset = Silk_macros.SKP_SMULBB(i, Silk_define.SHELL_CODEC_FRAME_LENGTH); - - for( k = 0; k < Silk_define.SHELL_CODEC_FRAME_LENGTH; k++ ) { - abs_q = pulses_ptr[pulses_ptr_offset + k]; - for( j = 0; j < nLS; j++ ) { - abs_q = abs_q << 1; - int bit_ptr[] = new int[1]; - Silk_range_coder.SKP_Silk_range_decoder( bit_ptr, 0, psRC, Silk_tables_other.SKP_Silk_lsb_CDF, 0, 1 ); - bit = bit_ptr[0]; - abs_q += bit; - } - pulses_ptr[pulses_ptr_offset + k] = abs_q; - } - } - } - - /****************************************/ - /* Decode and add signs to pulse signal */ - /****************************************/ - Silk_code_signs.SKP_Silk_decode_signs( psRC, q, frame_length, psDecCtrl.sigtype, - psDecCtrl.QuantOffsetType, psDecCtrl.RateLevelIndex); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decoder_set_fs.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decoder_set_fs.java deleted file mode 100644 index d3bdf64a8..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_decoder_set_fs.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -import java.util.*; - -/** - * Set decoder sampling rate. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_decoder_set_fs -{ - /** - * Set decoder sampling rate. - * @param psDec the decoder state. - * @param fs_kHz the sampling frequency(kHz). - */ - static void SKP_Silk_decoder_set_fs( - SKP_Silk_decoder_state psDec, /* I/O Decoder state pointer */ - int fs_kHz /* I Sampling frequency (kHz) */ - ) - { - if( psDec.fs_kHz != fs_kHz ) { - psDec.fs_kHz = fs_kHz; - psDec.frame_length = Silk_define.FRAME_LENGTH_MS*fs_kHz; - - psDec.subfr_length = (Silk_define.FRAME_LENGTH_MS/Silk_define.NB_SUBFR)*fs_kHz; - - if( psDec.fs_kHz == 8 ) { - psDec.LPC_order = Silk_define.MIN_LPC_ORDER; - psDec.psNLSF_CB[0] = Silk_tables_NLSF_CB0_10.SKP_Silk_NLSF_CB0_10; - psDec.psNLSF_CB[1] = Silk_tables_NLSF_CB1_10.SKP_Silk_NLSF_CB1_10; - } else { - psDec.LPC_order = Silk_define.MAX_LPC_ORDER; - psDec.psNLSF_CB[0] = Silk_tables_NLSF_CB0_16.SKP_Silk_NLSF_CB0_16; - psDec.psNLSF_CB[1] = Silk_tables_NLSF_CB1_16.SKP_Silk_NLSF_CB1_16; - } - /* Reset part of the decoder state */ - Arrays.fill(psDec.sLPC_Q14, 0, Silk_define.MAX_LPC_ORDER, 0); - - Arrays.fill(psDec.outBuf, 0, Silk_define.MAX_FRAME_LENGTH, (short)0); - - Arrays.fill(psDec.prevNLSF_Q15, 0, Silk_define.MAX_LPC_ORDER, 0); - - - psDec.sLTP_buf_idx = 0; - psDec.lagPrev = 100; - psDec.LastGainIndex = 1; - psDec.prev_sigtype = 0; - psDec.first_frame_after_reset = 1; - - if( fs_kHz == 24 ) { - psDec.HP_A = Silk_tables_other.SKP_Silk_Dec_A_HP_24; - psDec.HP_B = Silk_tables_other.SKP_Silk_Dec_B_HP_24; - } else if( fs_kHz == 16 ) { - psDec.HP_A = Silk_tables_other.SKP_Silk_Dec_A_HP_16; - psDec.HP_B = Silk_tables_other.SKP_Silk_Dec_B_HP_16; - } else if( fs_kHz == 12 ) { - psDec.HP_A = Silk_tables_other.SKP_Silk_Dec_A_HP_12; - psDec.HP_B = Silk_tables_other.SKP_Silk_Dec_B_HP_12; - } else if( fs_kHz == 8 ) { - psDec.HP_A = Silk_tables_other.SKP_Silk_Dec_A_HP_8; - psDec.HP_B = Silk_tables_other.SKP_Silk_Dec_B_HP_8; - } else { - /* unsupported sampling rate */ - Silk_typedef.SKP_assert( false ); - } - } - /* Check that settings are valid */ - Silk_typedef.SKP_assert( psDec.frame_length > 0 && psDec.frame_length <= Silk_define.MAX_FRAME_LENGTH ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_define.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_define.java deleted file mode 100644 index ae93cbd7d..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_define.java +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * This class contains a number of defines that controls the operation of SILK. - * Most of these should be left alone for ensuring proper operation. However, a - * few can be changed if operation different from the default is desired. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_define -{ - static final int MAX_FRAMES_PER_PACKET = 5; - - /* MAX DELTA LAG used for multiframe packets */ - static final int MAX_DELTA_LAG = 10; - - /* Lower limit on bitrate for each mode */ - static final int MIN_TARGET_RATE_NB_BPS = 5000; - static final int MIN_TARGET_RATE_MB_BPS = 7000; - static final int MIN_TARGET_RATE_WB_BPS = 8000; - static final int MIN_TARGET_RATE_SWB_BPS = 20000; - - /* Transition bitrates between modes */ - static final int SWB2WB_BITRATE_BPS = 26000; - static final int WB2SWB_BITRATE_BPS = 32000; - static final int WB2MB_BITRATE_BPS = 15000; - static final int MB2WB_BITRATE_BPS = 20000; - static final int MB2NB_BITRATE_BPS = 10000; - static final int NB2MB_BITRATE_BPS = 14000; - - /* Integration/hysteresis threshold for lowering internal sample frequency */ - /* 30000000 -> 6 sec if bitrate is 5000 bps below limit; 3 sec if bitrate is 10000 bps below limit */ - static final int ACCUM_BITS_DIFF_THRESHOLD = 30000000; - static final int TARGET_RATE_TAB_SZ = 8; - - /* DTX settings */ - static final int NO_SPEECH_FRAMES_BEFORE_DTX = 5; /* eq 100 ms */ - static final int MAX_CONSECUTIVE_DTX = 20; /* eq 400 ms */ - - static final int USE_LBRR = 1; - - /* Amount of concecutive no FEC packets before telling JB */ - static final int NO_LBRR_THRES = 10; - - /* Maximum delay between real packet and LBRR packet */ - static final int MAX_LBRR_DELAY = 2; - static final int LBRR_IDX_MASK = 1; - - static final int INBAND_FEC_MIN_RATE_BPS = 18000; /* Dont use inband FEC below this total target rate */ - static final int LBRR_LOSS_THRES = 2; /* Start adding LBRR at this loss rate (needs tuning) */ - - /* LBRR usage defines */ - static final int SKP_SILK_NO_LBRR = 0; /* No LBRR information for this packet */ - static final int SKP_SILK_ADD_LBRR_TO_PLUS1 = 1; /* Add LBRR for this packet to packet n + 1 */ - static final int SKP_SILK_ADD_LBRR_TO_PLUS2 = 2; /* Add LBRR for this packet to packet n + 2 */ - - /* Frame termination indicator defines */ - static final int SKP_SILK_LAST_FRAME = 0; /* Last frames in packet */ - static final int SKP_SILK_MORE_FRAMES = 1; /* More frames to follow this one */ - static final int SKP_SILK_LBRR_VER1 = 2; /* LBRR information from packet n - 1 */ - static final int SKP_SILK_LBRR_VER2 = 3; /* LBRR information from packet n - 2 */ - static final int SKP_SILK_EXT_LAYER = 4; /* Extension layers added */ - - /* Number of Second order Sections for SWB detection HP filter */ - static final int NB_SOS = 3; - static final int HP_8_KHZ_THRES= 10; /* average energy per sample, above 8 kHz */ - static final int CONCEC_SWB_SMPLS_THRES= 480 * 15; /* 300 ms */ - static final int WB_DETECT_ACTIVE_SPEECH_MS_THRES = 15000; /* ms of active speech needed for WB detection */ - - /* Low complexity setting */ - static final int LOW_COMPLEXITY_ONLY = 0; - - /* Activate bandwidth transition filtering for mode switching */ - static final int SWITCH_TRANSITION_FILTERING = 1; - - /* Decoder Parameters */ - static final int DEC_HP_ORDER = 2; - - /* Maximum sampling frequency, should be 16 for embedded */ - static final int MAX_FS_KHZ = 24; - static final int MAX_API_FS_KHZ= 48; - - /* Signal Types used by silk */ - static final int SIG_TYPE_VOICED = 0; - static final int SIG_TYPE_UNVOICED = 1; - - /* VAD Types used by silk */ - static final int NO_VOICE_ACTIVITY = 0; - static final int VOICE_ACTIVITY = 1; - - /* Number of samples per frame */ - static final int FRAME_LENGTH_MS = 20; /* 20 ms */ - static final int MAX_FRAME_LENGTH = (FRAME_LENGTH_MS * MAX_FS_KHZ); - - /* Milliseconds of lookahead for pitch analysis */ - static final int LA_PITCH_MS = 3; - static final int LA_PITCH_MAX = (LA_PITCH_MS * MAX_FS_KHZ); - - /* Milliseconds of lookahead for noise shape analysis */ - static final int LA_SHAPE_MS = 5; - static final int LA_SHAPE_MAX = (LA_SHAPE_MS * MAX_FS_KHZ); - - /* Order of LPC used in find pitch */ - static final int FIND_PITCH_LPC_ORDER_MAX = 16; - - /* Length of LPC window used in find pitch */ - static final int FIND_PITCH_LPC_WIN_MS = (30 + (LA_PITCH_MS << 1)); - static final int FIND_PITCH_LPC_WIN_MAX = (FIND_PITCH_LPC_WIN_MS * MAX_FS_KHZ); - - static final int PITCH_EST_COMPLEXITY_HC_MODE = Silk_SigProc_FIX.SKP_Silk_PITCH_EST_MAX_COMPLEX; - static final int PITCH_EST_COMPLEXITY_MC_MODE = Silk_SigProc_FIX.SKP_Silk_PITCH_EST_MID_COMPLEX; - static final int PITCH_EST_COMPLEXITY_LC_MODE = Silk_SigProc_FIX.SKP_Silk_PITCH_EST_MIN_COMPLEX; - - - /* Max number of bytes in payload output buffer (may contain multiple frames) */ - static final int MAX_ARITHM_BYTES = 1024; - - static final int RANGE_CODER_WRITE_BEYOND_BUFFER = -1; - static final int RANGE_CODER_CDF_OUT_OF_RANGE = -2; - static final int RANGE_CODER_NORMALIZATION_FAILED = -3; - static final int RANGE_CODER_ZERO_INTERVAL_WIDTH = -4; - static final int RANGE_CODER_DECODER_CHECK_FAILED = -5; - static final int RANGE_CODER_READ_BEYOND_BUFFER = -6; - static final int RANGE_CODER_ILLEGAL_SAMPLING_RATE = -7; - static final int RANGE_CODER_DEC_PAYLOAD_TOO_LONG = -8; - - /* dB level of lowest gain quantization level */ - static final int MIN_QGAIN_DB = 6; - /* dB level of highest gain quantization level */ - static final int MAX_QGAIN_DB = 86; - /* Number of gain quantization levels */ - static final int N_LEVELS_QGAIN = 64; - /* Max increase in gain quantization index */ - static final int MAX_DELTA_GAIN_QUANT = 40; - /* Max decrease in gain quantization index */ - static final int MIN_DELTA_GAIN_QUANT = -4; - - /* Quantization offsets (multiples of 4) */ - static final int OFFSET_VL_Q10 = 32; - static final int OFFSET_VH_Q10 = 100; - static final int OFFSET_UVL_Q10 = 100; - static final int OFFSET_UVH_Q10 = 256; - - /* Maximum numbers of iterations used to stabilize a LPC vector */ - static final int MAX_LPC_STABILIZE_ITERATIONS = 20; - - static final int MAX_LPC_ORDER = 16; - static final int MIN_LPC_ORDER = 10; - - /* Find Pred Coef defines */ - static final int LTP_ORDER = 5; - - /* LTP quantization settings */ - static final int NB_LTP_CBKS = 3; - - /* Number of subframes */ - static final int NB_SUBFR = 4; - - /* Flag to use harmonic noise shaping */ - static final int USE_HARM_SHAPING = 1; - - /* Max LPC order of noise shaping filters */ - static final int SHAPE_LPC_ORDER_MAX = 16; - - static final int HARM_SHAPE_FIR_TAPS = 3; - - /* Length of LPC window used in noise shape analysis */ - static final int SHAPE_LPC_WIN_MS = 15; - static final int SHAPE_LPC_WIN_16_KHZ = (SHAPE_LPC_WIN_MS * 16); - static final int SHAPE_LPC_WIN_24_KHZ = (SHAPE_LPC_WIN_MS * 24); - static final int SHAPE_LPC_WIN_MAX = (SHAPE_LPC_WIN_MS * MAX_FS_KHZ); - - /* Maximum number of delayed decision states */ - static final int DEL_DEC_STATES_MAX = 4; - - static final int LTP_BUF_LENGTH = 512; - static final int LTP_MASK = (LTP_BUF_LENGTH - 1); - - static final int DECISION_DELAY = 32; - static final int DECISION_DELAY_MASK = (DECISION_DELAY - 1); - - /* number of subframes for excitation entropy coding */ - static final int SHELL_CODEC_FRAME_LENGTH = 16; - static final int MAX_NB_SHELL_BLOCKS = (MAX_FRAME_LENGTH / SHELL_CODEC_FRAME_LENGTH); - - /* number of rate levels, for entropy coding of excitation */ - static final int N_RATE_LEVELS = 10; - - /* maximum sum of pulses per shell coding frame */ - static final int MAX_PULSES = 18; - - static final int MAX_MATRIX_SIZE = MAX_LPC_ORDER; /* Max of LPC Order and LTP order */ - -//TODO: convert a macro to a method. - static int NSQ_LPC_BUF_LENGTH() - { - if(MAX_LPC_ORDER > DECISION_DELAY) - return MAX_LPC_ORDER; - else - return DECISION_DELAY; - } - /***********************/ - /* High pass filtering */ - /***********************/ - static final int HIGH_PASS_INPUT = 1; - - /***************************/ - /* Voice activity detector */ - /***************************/ - static final int VAD_N_BANDS = 4; /* 0-1, 1-2, 2-4, and 4-8 kHz */ - - static final int VAD_INTERNAL_SUBFRAMES_LOG2 = 2; - static final int VAD_INTERNAL_SUBFRAMES = (1 << VAD_INTERNAL_SUBFRAMES_LOG2); - - static final int VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 = 1024; /* Must be < 4096 */ - static final int VAD_NOISE_LEVELS_BIAS = 50 ; - - /* Sigmoid settings */ - static final int VAD_NEGATIVE_OFFSET_Q5 = 128 ; /* sigmoid is 0 at -128 */ - static final int VAD_SNR_FACTOR_Q16 = 45000 ; - - /* smoothing for SNR measurement */ - static final int VAD_SNR_SMOOTH_COEF_Q18 = 4096; - - /******************/ - /* NLSF quantizer */ - /******************/ - static final int NLSF_MSVQ_MAX_CB_STAGES = 10; /* Update manually when changing codebooks */ - static final int NLSF_MSVQ_MAX_VECTORS_IN_STAGE = 128;/* Update manually when changing codebooks */ - static final int NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END = 16; /* Update manually when changing codebooks */ - - static final int NLSF_MSVQ_FLUCTUATION_REDUCTION = 1; - static final int MAX_NLSF_MSVQ_SURVIVORS = 16; - static final int MAX_NLSF_MSVQ_SURVIVORS_LC_MODE = 2; - static final int MAX_NLSF_MSVQ_SURVIVORS_MC_MODE = 4; - - /* Based on above defines, calculate how much memory is necessary to allocate */ - static int NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED_LC_MODE() - { - if(NLSF_MSVQ_MAX_VECTORS_IN_STAGE > ( MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END )) - return NLSF_MSVQ_MAX_VECTORS_IN_STAGE; - else - return MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END; - } - - static int NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED() - { - if( NLSF_MSVQ_MAX_VECTORS_IN_STAGE > ( MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END ) ) - return NLSF_MSVQ_MAX_VECTORS_IN_STAGE; - else - return MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END; - } - - static final int NLSF_MSVQ_SURV_MAX_REL_RD = 4; - - /* Transition filtering for mode switching */ - static final int TRANSITION_TIME_UP_MS = 5120; // 5120 = 64 * FRAME_LENGTH_MS * ( TRANSITION_INT_NUM - 1 ) = 64*(20*4) - static final int TRANSITION_TIME_DOWN_MS = 2560; // 2560 = 32 * FRAME_LENGTH_MS * ( TRANSITION_INT_NUM - 1 ) = 32*(20*4) - static final int TRANSITION_NB = 3; /* Hardcoded in tables */ - static final int TRANSITION_NA = 2; /* Hardcoded in tables */ - static final int TRANSITION_INT_NUM = 5; /* Hardcoded in tables */ - static final int TRANSITION_FRAMES_UP = ( TRANSITION_TIME_UP_MS / FRAME_LENGTH_MS ); - static final int TRANSITION_FRAMES_DOWN = ( TRANSITION_TIME_DOWN_MS / FRAME_LENGTH_MS ); - static final int TRANSITION_INT_STEPS_UP = ( TRANSITION_FRAMES_UP / ( TRANSITION_INT_NUM - 1 ) ); - static final int TRANSITION_INT_STEPS_DOWN = ( TRANSITION_FRAMES_DOWN / ( TRANSITION_INT_NUM - 1 ) ); - -//TODO:no need to convert from C to Java? - /* Row based */ -// #define matrix_ptr(Matrix_base_adr, row, column, N) *(Matrix_base_adr + ((row)*(N)+(column))) -// #define matrix_adr(Matrix_base_adr, row, column, N) (Matrix_base_adr + ((row)*(N)+(column))) - - /* Column based */ -// #ifndef matrix_c_ptr -// # define matrix_c_ptr(Matrix_base_adr, row, column, M) *(Matrix_base_adr + ((row)+(M)*(column))) -// #endif -// #define matrix_c_adr(Matrix_base_adr, row, column, M) (Matrix_base_adr + ((row)+(M)*(column))) - - /* BWE factors to apply after packet loss */ - static final int BWE_AFTER_LOSS_Q16 = 63570; - - /* Defines for CN generation */ - static final int CNG_BUF_MASK_MAX = 255; /* 2^floor(log2(MAX_FRAME_LENGTH)) */ - static final int CNG_GAIN_SMTH_Q16 = 4634; /* 0.25^(1/4) */ - static final int CNG_NLSF_SMTH_Q16 = 16348; /* 0.25 */ -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_define_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_define_FLP.java deleted file mode 100644 index 34d5f020f..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_define_FLP.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_define_FLP -{ - /*******************/ - /* Pitch estimator */ - /*******************/ - - /* Level of noise floor for whitening filter LPC analysis in pitch analysis */ - static final float FIND_PITCH_WHITE_NOISE_FRACTION = 1e-3f; - - /* Bandwidth expansion for whitening filter in pitch analysis */ - static final float FIND_PITCH_BANDWITH_EXPANSION = 0.99f; - - /* Threshold used by pitch estimator for early escape */ - static final float FIND_PITCH_CORRELATION_THRESHOLD_HC_MODE = 0.7f; - static final float FIND_PITCH_CORRELATION_THRESHOLD_MC_MODE = 0.75f; - static final float FIND_PITCH_CORRELATION_THRESHOLD_LC_MODE = 0.8f; - - /***********************/ - /* Long-Term predictor */ - /***********************/ - - /* Regualarization factor for correlation matrix. Equivalent to adding noise at -50 dB */ - static final float FIND_LTP_COND_FAC = 1e-5f; - static final float FIND_LPC_COND_FAC = 6e-5f; - - /* Find prediction coefficients defines */ - static final float LTP_DAMPING = 0.001f; - static final float LTP_SMOOTHING = 0.1f; - - /* LTP quantization settings */ - static final float MU_LTP_QUANT_NB = 0.03f; - static final float MU_LTP_QUANT_MB = 0.025f; - static final float MU_LTP_QUANT_WB = 0.02f; - static final float MU_LTP_QUANT_SWB = 0.016f; - - /***********************/ - /* High pass filtering */ - /***********************/ - - /* Smoothing parameters for low end of pitch frequency range estimation */ - static final float VARIABLE_HP_SMTH_COEF1 = 0.1f; - static final float VARIABLE_HP_SMTH_COEF2 = 0.015f; - - /* Min and max values for low end of pitch frequency range estimation */ - static final float VARIABLE_HP_MIN_FREQ = 80.0f; - static final float VARIABLE_HP_MAX_FREQ = 150.0f; - - /* Max absolute difference between log2 of pitch frequency and smoother state, to enter the smoother */ - static final float VARIABLE_HP_MAX_DELTA_FREQ = 0.4f; - - /***********/ - /* Various */ - /***********/ - - /* Required speech activity for counting frame as active */ - static final float WB_DETECT_ACTIVE_SPEECH_LEVEL_THRES = 0.7f; - - static final float SPEECH_ACTIVITY_DTX_THRES = 0.1f; - - /* Speech Activity LBRR enable threshold (needs tuning) */ - static final float LBRR_SPEECH_ACTIVITY_THRES = 0.5f; - - static final float Q14_CONVERSION_FAC = 6.1035e-005f; // 1 / 2^14 -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_detect_SWB_input.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_detect_SWB_input.java deleted file mode 100644 index b34ec6630..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_detect_SWB_input.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Detect SWB input by measuring energy above 8 kHz. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_detect_SWB_input -{ - /** - * Detect SWB input by measuring energy above 8 kHz. - * @param psSWBdetect encoder state - * @param samplesIn input to encoder - * @param samplesIn_offset offset of valid data. - * @param nSamplesIn length of input - */ - static void SKP_Silk_detect_SWB_input( - SKP_Silk_detect_SWB_state psSWBdetect, /* (I/O) encoder state */ - short[] samplesIn, /* (I) input to encoder */ - int samplesIn_offset, - int nSamplesIn /* (I) length of input */ - ) - { - int HP_8_kHz_len, i, shift[] = new int[1]; - short[] in_HP_8_kHz = new short[ Silk_define.MAX_FRAME_LENGTH ]; - int[] energy_32 = new int[1]; - - /* High pass filter with cutoff at 8 khz */ - HP_8_kHz_len = Math.min( nSamplesIn, Silk_define.MAX_FRAME_LENGTH ); - HP_8_kHz_len = Math.max( HP_8_kHz_len, 0 ); - - /* Cutoff around 9 khz */ - /* A = conv(conv([8192,14613, 6868], [8192,12883, 7337]), [8192,11586, 7911]); */ - /* B = conv(conv([575, -948, 575], [575, -221, 575]), [575, 104, 575]); */ - Silk_biquad.SKP_Silk_biquad( samplesIn, samplesIn_offset, Silk_tables_other.SKP_Silk_SWB_detect_B_HP_Q13[ 0 ], Silk_tables_other.SKP_Silk_SWB_detect_A_HP_Q13[ 0 ], - psSWBdetect.S_HP_8_kHz[ 0 ], in_HP_8_kHz, 0, HP_8_kHz_len ); - for( i = 1; i < Silk_define.NB_SOS; i++ ) - { - Silk_biquad.SKP_Silk_biquad( in_HP_8_kHz, 0, Silk_tables_other.SKP_Silk_SWB_detect_B_HP_Q13[ i ], Silk_tables_other.SKP_Silk_SWB_detect_A_HP_Q13[ i ], - psSWBdetect.S_HP_8_kHz[ i ], in_HP_8_kHz, 0, HP_8_kHz_len ); - } - - /* Calculate energy in HP signal */ - Silk_sum_sqr_shift.SKP_Silk_sum_sqr_shift( energy_32, shift, in_HP_8_kHz, 0, HP_8_kHz_len ); - - /* Count concecutive samples above threshold, after adjusting threshold for number of input samples and shift */ - if( energy_32[0] > Silk_macros.SKP_SMULBB( Silk_define.HP_8_KHZ_THRES, HP_8_kHz_len ) >> shift[0] ) - { - psSWBdetect.ConsecSmplsAboveThres += nSamplesIn; - if( psSWBdetect.ConsecSmplsAboveThres > Silk_define.CONCEC_SWB_SMPLS_THRES ) - { - psSWBdetect.SWB_detected = 1; - } - } - else - { - psSWBdetect.ConsecSmplsAboveThres -= nSamplesIn; - psSWBdetect.ConsecSmplsAboveThres = Math.max( psSWBdetect.ConsecSmplsAboveThres, 0 ); - } - - /* If sufficient speech activity and no SWB detected, we detect the signal as being WB */ - if( ( psSWBdetect.ActiveSpeech_ms > Silk_define.WB_DETECT_ACTIVE_SPEECH_MS_THRES ) && ( psSWBdetect.SWB_detected == 0 ) ) - { - psSWBdetect.WB_detected = 1; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_enc_API.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_enc_API.java deleted file mode 100644 index a6f714977..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_enc_API.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Encoder API. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_enc_API -{ - /*** - * TODO: TEST - */ - static int frame_cnt = 0; - - /** - * Read control structure from encoder. - * @param encState State Vecotr. - * @param encStatus Control Structure. - * @return - */ - static int SKP_Silk_SDK_QueryEncoder - ( - Object encState, /* I: State Vector */ - SKP_SILK_SDK_EncControlStruct encStatus /* O: Control Structure */ - ) - { - SKP_Silk_encoder_state_FLP psEnc; - int ret = 0; - - psEnc = ( SKP_Silk_encoder_state_FLP )encState; - - encStatus.API_sampleRate = psEnc.sCmn.API_fs_Hz; - encStatus.maxInternalSampleRate = Silk_macros.SKP_SMULBB( psEnc.sCmn.maxInternal_fs_kHz, 1000 ); - encStatus.packetSize = ( psEnc.sCmn.API_fs_Hz * psEnc.sCmn.PacketSize_ms / 1000 ); /* convert samples -> ms */ - encStatus.bitRate = psEnc.sCmn.TargetRate_bps; - encStatus.packetLossPercentage = psEnc.sCmn.PacketLoss_perc; - encStatus.complexity = psEnc.sCmn.Complexity; - encStatus.useInBandFEC = psEnc.sCmn.useInBandFEC; - encStatus.useDTX = psEnc.sCmn.useDTX; - return ret; - } - - /** - * Init or Reset encoder. - * @param encState - * @param encStatus - * @return - */ - static int SKP_Silk_SDK_InitEncoder - ( - Object encState, /* I/O: State */ - SKP_SILK_SDK_EncControlStruct encStatus /* O: Control structure */ - ) - { - SKP_Silk_encoder_state_FLP psEnc; - int ret = 0; - - - psEnc = ( SKP_Silk_encoder_state_FLP )encState; - - /* Reset Encoder */ - if( (ret += Silk_init_encoder_FLP.SKP_Silk_init_encoder_FLP( psEnc )) != 0 ) - { - assert( false ); - } - - /* Read control structure */ - if( (ret += SKP_Silk_SDK_QueryEncoder( encState, encStatus )) != 0 ) - { - assert( false ); - } - return ret; - } - - /** - * Encode frame with Silk. - * @param encState State - * @param encControl Control structure - * @param samplesIn Speech sample input vector - * @param samplesIn_offset offset of valid data. - * @param nSamplesIn Number of samples in input vector - * @param outData Encoded output vector - * @param outData_offset offset of valid data. - * @param nBytesOut Number of bytes in outData (input: Max bytes) - * @return - */ - static int SKP_Silk_SDK_Encode - ( - Object encState, /* I/O: State */ - SKP_SILK_SDK_EncControlStruct encControl, /* I: Control structure */ - final short[] samplesIn, /* I: Speech sample input vector */ - int samplesIn_offset, - int nSamplesIn, /* I: Number of samples in input vector */ - byte[] outData, /* O: Encoded output vector */ - int outData_offset, - short[] nBytesOut /* I/O: Number of bytes in outData (input: Max bytes) */ - ) - { - int max_internal_fs_kHz, PacketSize_ms, PacketLoss_perc, UseInBandFEC, UseDTX, ret = 0; - int nSamplesToBuffer, Complexity, input_ms, nSamplesFromInput = 0; - int TargetRate_bps, API_fs_Hz; - short MaxBytesOut; - SKP_Silk_encoder_state_FLP psEnc = ( SKP_Silk_encoder_state_FLP )encState; - - assert( encControl != null ); - - /* Check sampling frequency first, to avoid divide by zero later */ - if( ( ( encControl.API_sampleRate != 8000 ) && - ( encControl.API_sampleRate != 12000 ) && - ( encControl.API_sampleRate != 16000 ) && - ( encControl.API_sampleRate != 24000 ) && - ( encControl.API_sampleRate != 32000 ) && - ( encControl.API_sampleRate != 44100 ) && - ( encControl.API_sampleRate != 48000 ) ) || - ( ( encControl.maxInternalSampleRate != 8000 ) && - ( encControl.maxInternalSampleRate != 12000 ) && - ( encControl.maxInternalSampleRate != 16000 ) && - ( encControl.maxInternalSampleRate != 24000 ) ) ) - { - ret = Silk_errors.SKP_SILK_ENC_FS_NOT_SUPPORTED; - assert( false ); - return( ret ); - } - - /* Set encoder parameters from control structure */ - API_fs_Hz = encControl.API_sampleRate; - max_internal_fs_kHz = encControl.maxInternalSampleRate / 1000; /* convert Hz -> kHz */ - PacketSize_ms = 1000 * encControl.packetSize / API_fs_Hz; - TargetRate_bps = encControl.bitRate; - PacketLoss_perc = encControl.packetLossPercentage; - UseInBandFEC = encControl.useInBandFEC; - Complexity = encControl.complexity; - UseDTX = encControl.useDTX; - /* Save values in state */ - psEnc.sCmn.API_fs_Hz = API_fs_Hz; - psEnc.sCmn.maxInternal_fs_kHz = max_internal_fs_kHz; - psEnc.sCmn.useInBandFEC = UseInBandFEC; - - /* Only accept input lengths that are a multiplum of 10 ms */ - input_ms = 1000 * nSamplesIn / API_fs_Hz; - if( ( input_ms % 10) != 0 || nSamplesIn < 0 ) - { - ret = Silk_errors.SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; - assert( false ); - return( ret ); - } - - /* Make sure no more than one packet can be produced */ - if( nSamplesIn > ( psEnc.sCmn.PacketSize_ms * API_fs_Hz / 1000 ) ) - { - ret = Silk_errors.SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; - assert( false ); - return( ret ); - } - if( ( ret = Silk_control_codec_FLP.SKP_Silk_control_encoder_FLP( psEnc, API_fs_Hz, max_internal_fs_kHz, PacketSize_ms, TargetRate_bps, - PacketLoss_perc, UseInBandFEC, UseDTX, input_ms, Complexity) ) != 0 ) - { - assert( false ); - return( ret ); - } - /* Detect energy above 8 kHz */ - if( Math.min( API_fs_Hz, 1000 * max_internal_fs_kHz ) == 24000 && psEnc.sCmn.sSWBdetect.SWB_detected == 0 && psEnc.sCmn.sSWBdetect.WB_detected == 0 ) - { - Silk_detect_SWB_input.SKP_Silk_detect_SWB_input( psEnc.sCmn.sSWBdetect, samplesIn,samplesIn_offset, nSamplesIn ); - } - - /* Input buffering/resampling and encoding */ - MaxBytesOut = 0; /* return 0 output bytes if no encoder called */ - while( true ) - { - nSamplesToBuffer = psEnc.sCmn.frame_length - psEnc.sCmn.inputBufIx; - if( API_fs_Hz == Silk_macros.SKP_SMULBB( 1000, psEnc.sCmn.fs_kHz ) ) - { - nSamplesToBuffer = Math.min( nSamplesToBuffer, nSamplesIn ); - nSamplesFromInput = nSamplesToBuffer; - /* Copy to buffer */ - System.arraycopy(samplesIn, samplesIn_offset, psEnc.sCmn.inputBuf, psEnc.sCmn.inputBufIx, nSamplesFromInput); - } - else - { - nSamplesToBuffer = Math.min( nSamplesToBuffer, nSamplesIn * psEnc.sCmn.fs_kHz * 1000 / API_fs_Hz ); - nSamplesFromInput = ( nSamplesToBuffer * API_fs_Hz / ( psEnc.sCmn.fs_kHz * 1000 ) ); - /* Resample and write to buffer */ - ret += Silk_resampler.SKP_Silk_resampler(psEnc.sCmn.resampler_state, - psEnc.sCmn.inputBuf, psEnc.sCmn.inputBufIx, samplesIn, samplesIn_offset, nSamplesFromInput); - -///*TEST****************************************************************************/ -// /** -// * test for inputbuf -// */ -// short[] inputbuf = psEnc.sCmn.inputBuf; -// String inputbuf_filename = "D:/gsoc/inputbuf-res/inputbuf-res"; -// inputbuf_filename += frame_cnt; -// DataInputStream inputbuf_datain = null; -// try -// { -// inputbuf_datain = new DataInputStream( -// new FileInputStream( -// new File(inputbuf_filename))); -// byte[] buffer = new byte[2]; -// for(int ii = 0; ii < inputbuf.length; ii++ ) -// { -// try -// { -// -// int res = inputbuf_datain.read(buffer); -// if(res != buffer.length) -// { -// throw new IOException("Unexpected End of Stream"); -// } -// inputbuf[ii] = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).getShort(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// catch (FileNotFoundException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// finally -// { -// if(inputbuf_datain != null) -// { -// try -// { -// inputbuf_datain.close(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// frame_cnt++; -///*TEST END****************************************************************************/ - } - samplesIn_offset += nSamplesFromInput; - nSamplesIn -= nSamplesFromInput; - psEnc.sCmn.inputBufIx += nSamplesToBuffer; - - /* Silk encoder */ - if( psEnc.sCmn.inputBufIx >= psEnc.sCmn.frame_length ) - { - /* Enough data in input buffer, so encode */ - if( MaxBytesOut == 0 ) - { - /* No payload obtained so far */ - MaxBytesOut = nBytesOut[0]; - short MaxBytesOut_ptr[] = new short[1]; - MaxBytesOut_ptr[0] = MaxBytesOut; -// if( ( ret = Silk_encode_frame_FLP.SKP_Silk_encode_frame_FLP( psEnc, outData, outData_offset, -// MaxBytesOut_ptr, psEnc.sCmn.inputBuf, psEnc.sCmn.inputBufIx ) ) != 0 ) - if( ( ret = Silk_encode_frame_FLP.SKP_Silk_encode_frame_FLP( psEnc, outData, outData_offset, - MaxBytesOut_ptr, psEnc.sCmn.inputBuf, 0 ) ) != 0 ) - { - assert( false ); - } - MaxBytesOut = MaxBytesOut_ptr[0]; - } - else - { - /* outData already contains a payload */ -// if( ( ret = Silk_encode_frame_FLP.SKP_Silk_encode_frame_FLP( psEnc, outData, outData_offset, -// nBytesOut, psEnc.sCmn.inputBuf, psEnc.sCmn.inputBufIx) ) != 0 ) - if( ( ret = Silk_encode_frame_FLP.SKP_Silk_encode_frame_FLP( psEnc, outData, outData_offset, - nBytesOut, psEnc.sCmn.inputBuf, 0) ) != 0 ) - { - assert( false ); - } - /* Check that no second payload was created */ - assert( nBytesOut[0] == 0 ); - } - psEnc.sCmn.inputBufIx = 0; - } - else - { - break; - } - } - - nBytesOut[0] = MaxBytesOut; - if( psEnc.sCmn.useDTX!=0 && psEnc.sCmn.inDTX!=0 ) - { - /* DTX simulation */ - nBytesOut[0] = 0; - } - - return ret; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_encode_frame_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_encode_frame_FLP.java deleted file mode 100644 index b54741b2c..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_encode_frame_FLP.java +++ /dev/null @@ -1,701 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -import java.util.*; - -/** - * Encode frame. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_encode_frame_FLP -{ - /** - * TODO: TEST - */ - static int frame_cnt = 0; - /** - * Encode frame. - * @param psEnc Encoder state FLP - * @param pCode payload - * @param pCode_offset offset of valid data. - * @param pnBytesOut Number of payload bytes; input: max length; output: used. - * @param pIn Input speech frame - * @param pIn_offset offset of valid data. - * @return - */ - static int SKP_Silk_encode_frame_FLP( - SKP_Silk_encoder_state_FLP psEnc, /* I/O Encoder state FLP */ - byte[] pCode, - int pCode_offset, - short[] pnBytesOut, /* I/O Number of payload bytes; */ - /* input: max length; output: used */ - short[] pIn, /* I Input speech frame */ - int pIn_offset - ) - { - SKP_Silk_encoder_control_FLP sEncCtrl = new SKP_Silk_encoder_control_FLP(); - int k, nBytes[] = new int[1], ret = 0; - float[] x_frame, res_pitch_frame; - int x_frame_offset, res_pitch_frame_offset; - short[] pIn_HP = new short[ Silk_define.MAX_FRAME_LENGTH ]; - short[] pIn_HP_LP = new short[ Silk_define.MAX_FRAME_LENGTH ]; - float[] xfw = new float[ Silk_define.MAX_FRAME_LENGTH ]; - float[] res_pitch = new float[ 2 * Silk_define.MAX_FRAME_LENGTH + Silk_define.LA_PITCH_MAX ]; - int LBRR_idx, frame_terminator; - - /* Low bitrate redundancy parameters */ - byte[] LBRRpayload = new byte[Silk_define.MAX_ARITHM_BYTES]; - short[] nBytesLBRR = new short[1]; - - int[] FrameTermination_CDF; - - - sEncCtrl.sCmn.Seed = psEnc.sCmn.frameCounter++ & 3; - /**************************************************************/ - /* Setup Input Pointers, and insert frame in input buffer */ - /*************************************************************/ - /* pointers aligned with start of frame to encode */ - x_frame = psEnc.x_buf; - x_frame_offset = psEnc.x_buf_offset + psEnc.sCmn.frame_length; // start of frame to encode - res_pitch_frame = res_pitch; - res_pitch_frame_offset = psEnc.sCmn.frame_length; // start of pitch LPC residual frame - - /****************************/ - /* Voice Activity Detection */ - /****************************/ - Silk_wrappers_FLP.SKP_Silk_VAD_FLP( psEnc, sEncCtrl, pIn, pIn_offset ); - - /*******************************************/ - /* High-pass filtering of the input signal */ - /*******************************************/ - if (Silk_define.HIGH_PASS_INPUT !=0) { - /* Variable high-pass filter */ - Silk_HP_variable_cutoff_FLP.SKP_Silk_HP_variable_cutoff_FLP( psEnc, sEncCtrl, pIn_HP, 0, pIn, pIn_offset ); - } else { - System.arraycopy(pIn, pIn_offset, pIn_HP, 0, psEnc.sCmn.frame_length); - } - - -// /*TEST****************************************************************************/ -// /** -// * test for psEnc.x_buf -// */ -// short[] pin_hp = pIn_HP; -// String pin_hp_filename = "D:/gsoc/pin_hp/pin_hp"; -// pin_hp_filename += frame_cnt; -// DataInputStream pin_hp_datain = null; -// try -// { -// pin_hp_datain = new DataInputStream( -// new FileInputStream( -// new File(pin_hp_filename))); -// byte[] buffer = new byte[2]; -// for(int ii = 0; ii < pin_hp.length; ii++ ) -// { -// try -// { -// -// int res = pin_hp_datain.read(buffer); -// if(res != buffer.length) -// { -// throw new IOException("Unexpected End of Stream"); -// } -// pin_hp[ii] = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).getShort(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// catch (FileNotFoundException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// finally -// { -// if(pin_hp_datain != null) -// { -// try -// { -// pin_hp_datain.close(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// frame_cnt++; -/*TEST END****************************************************************************/ - if (Silk_define.SWITCH_TRANSITION_FILTERING != 0) { - /* Ensure smooth bandwidth transitions */ - Silk_LP_variable_cutoff.SKP_Silk_LP_variable_cutoff( psEnc.sCmn.sLP, pIn_HP_LP, 0, pIn_HP, 0, psEnc.sCmn.frame_length ); - } else { - System.arraycopy(pIn_HP, 0, pIn_HP_LP, 0, psEnc.sCmn.frame_length); - } - -///*TEST****************************************************************************/ -// /** -// * test for psEnc.x_buf -// */ -// short[] pin_hp_lp = pIn_HP_LP; -// String pin_hp_lp_filename = "D:/gsoc/pin_hp_lp/pin_hp_lp"; -// pin_hp_lp_filename += frame_cnt; -// DataInputStream pin_hp_lp_datain = null; -// try -// { -// pin_hp_lp_datain = new DataInputStream( -// new FileInputStream( -// new File(pin_hp_lp_filename))); -// byte[] buffer = new byte[2]; -// for(int ii = 0; ii < pin_hp_lp.length; ii++ ) -// { -// try -// { -// -// int res = pin_hp_lp_datain.read(buffer); -// if(res != buffer.length) -// { -// throw new IOException("Unexpected End of Stream"); -// } -// pin_hp_lp[ii] = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).getShort(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// catch (FileNotFoundException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// finally -// { -// if(pin_hp_lp_datain != null) -// { -// try -// { -// pin_hp_lp_datain.close(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// frame_cnt++; -///*TEST END****************************************************************************/ - - -///*TEST****************************************************************************/ -// /** -// * test for psEnc.x_buf -// */ -// float[] x_buf = psEnc.x_buf; -// String x_buf_filename = "D:/gsoc/x_buf/x_buf"; -// x_buf_filename += frame_cnt; -// DataInputStream x_buf_datain = null; -// try -// { -// x_buf_datain = new DataInputStream( -// new FileInputStream( -// new File(x_buf_filename))); -// byte[] buffer = new byte[4]; -// for(int ii = 0; ii < x_buf.length; ii++ ) -// { -// try -// { -// -// int res = x_buf_datain.read(buffer); -// if(res != 4) -// { -// throw new IOException("Unexpected End of Stream"); -// } -// x_buf[ii] = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).getFloat(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// catch (FileNotFoundException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// finally -// { -// if(x_buf_datain != null) -// { -// try -// { -// x_buf_datain.close(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// frame_cnt++; -///*TEST END****************************************************************************/ - /*******************************************/ - /* Copy new frame to front of input buffer */ - /*******************************************/ - Silk_SigProc_FLP.SKP_short2float_array( x_frame, x_frame_offset +psEnc.sCmn.la_shape, - pIn_HP_LP, 0, psEnc.sCmn.frame_length ); - -///*TEST****************************************************************************/ -// /** -// * test for psEnc.x_buf -// */ -// float[] x_buf = psEnc.x_buf; -// String x_buf_filename = "D:/gsoc/x_buf/x_buf"; -// x_buf_filename += frame_cnt; -// DataInputStream x_buf_datain = null; -// try -// { -// x_buf_datain = new DataInputStream( -// new FileInputStream( -// new File(x_buf_filename))); -// byte[] buffer = new byte[4]; -// for(int ii = 0; ii < x_buf.length; ii++ ) -// { -// try -// { -// -// int res = x_buf_datain.read(buffer); -// if(res != 4) -// { -// throw new IOException("Unexpected End of Stream"); -// } -// x_buf[ii] = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).getFloat(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// catch (FileNotFoundException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// finally -// { -// if(x_buf_datain != null) -// { -// try -// { -// x_buf_datain.close(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// frame_cnt++; -///*TEST END****************************************************************************/ - - /* Add tiny signal to avoid high CPU load from denormalized floating point numbers */ - for( k = 0; k < 8; k++ ) { - x_frame[ x_frame_offset + psEnc.sCmn.la_shape + k * ( psEnc.sCmn.frame_length >> 3 ) ] += ( 1 - ( k & 2 ) ) * 1e-6f; - } -/*TEST****************************************************************************/ - /** - * test for psEnc.x_buf - */ - /** - * Test for NLSF - */ -// float[] x_buf = new float[ psEnc.x_buf.length ]; -// float[] x_buf = psEnc.x_buf; -// String x_buf_filename = "D:/gsoc/x_buf/x_buf"; -// x_buf_filename += frame_cnt; -// DataInputStream x_buf_datain = null; -// try -// { -// x_buf_datain = new DataInputStream( -// new FileInputStream( -// new File(x_buf_filename))); -// byte[] buffer = new byte[4]; -// for(int ii = 0; ii < x_buf.length; ii++ ) -// { -// try -// { -// -// int res = x_buf_datain.read(buffer); -// if(res != 4) -// { -// throw new IOException("Unexpected End of Stream"); -// } -// x_buf[ii] = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).getFloat(); -//// NLSF[ii] = nlsf[ii]; -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// catch (FileNotFoundException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// finally -// { -// if(x_buf_datain != null) -// { -// try -// { -// x_buf_datain.close(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// frame_cnt++; -/*TEST END****************************************************************************/ - /*****************************************/ - /* Find pitch lags, initial LPC analysis */ - /*****************************************/ - Silk_find_pitch_lags_FLP.SKP_Silk_find_pitch_lags_FLP( psEnc, sEncCtrl, res_pitch, x_frame, x_frame_offset ); - - /************************/ - /* Noise shape analysis */ - /************************/ - Silk_noise_shape_analysis_FLP.SKP_Silk_noise_shape_analysis_FLP( psEnc, sEncCtrl, - res_pitch_frame, res_pitch_frame_offset, x_frame, x_frame_offset ); - - /*****************************************/ - /* Prefiltering for noise shaper */ - /*****************************************/ - Silk_prefilter_FLP.SKP_Silk_prefilter_FLP( psEnc, sEncCtrl, xfw, x_frame, x_frame_offset ); - - /***************************************************/ - /* Find linear prediction coefficients (LPC + LTP) */ - /***************************************************/ - Silk_find_pred_coefs_FLP.SKP_Silk_find_pred_coefs_FLP( psEnc, sEncCtrl, res_pitch ); - - /****************************************/ - /* Process gains */ - /****************************************/ - Silk_process_gains_FLP.SKP_Silk_process_gains_FLP( psEnc, sEncCtrl ); - - /****************************************/ - /* Low Bitrate Redundant Encoding */ - /****************************************/ - nBytesLBRR[0] = Silk_define.MAX_ARITHM_BYTES; - SKP_Silk_LBRR_encode_FLP( psEnc, sEncCtrl, LBRRpayload, nBytesLBRR, xfw ); - - /*****************************************/ - /* Noise shaping quantization */ - /*****************************************/ - Silk_wrappers_FLP.SKP_Silk_NSQ_wrapper_FLP( psEnc, sEncCtrl, xfw, 0, psEnc.sCmn.q, 0, 0 ); - - /**************************************************/ - /* Convert speech activity into VAD and DTX flags */ - /**************************************************/ - if( psEnc.speech_activity < Silk_define_FLP.SPEECH_ACTIVITY_DTX_THRES ) { - psEnc.sCmn.vadFlag = Silk_define.NO_VOICE_ACTIVITY; - psEnc.sCmn.noSpeechCounter++; - if( psEnc.sCmn.noSpeechCounter > Silk_define.NO_SPEECH_FRAMES_BEFORE_DTX ) { - psEnc.sCmn.inDTX = 1; - } - if( psEnc.sCmn.noSpeechCounter > Silk_define.MAX_CONSECUTIVE_DTX ) { - psEnc.sCmn.noSpeechCounter = 0; - psEnc.sCmn.inDTX = 0; - } - } else { - psEnc.sCmn.noSpeechCounter = 0; - psEnc.sCmn.inDTX = 0; - psEnc.sCmn.vadFlag = Silk_define.VOICE_ACTIVITY; - } - - /****************************************/ - /* Initialize arithmetic coder */ - /****************************************/ - if( psEnc.sCmn.nFramesInPayloadBuf == 0 ) - { - Silk_range_coder.SKP_Silk_range_enc_init( psEnc.sCmn.sRC ); - psEnc.sCmn.nBytesInPayloadBuf = 0; - } - - /****************************************/ - /* Encode Parameters */ - /****************************************/ - Silk_encode_parameters.SKP_Silk_encode_parameters( psEnc.sCmn, sEncCtrl.sCmn, psEnc.sCmn.sRC, psEnc.sCmn.q ); - FrameTermination_CDF = Silk_tables_other.SKP_Silk_FrameTermination_CDF; - - /****************************************/ - /* Update Buffers and State */ - /****************************************/ - /* Update input buffer */ - System.arraycopy(psEnc.x_buf, psEnc.x_buf_offset + psEnc.sCmn.frame_length, - psEnc.x_buf, psEnc.x_buf_offset, psEnc.sCmn.frame_length + psEnc.sCmn.la_shape); - - /* Parameters needed for next frame */ - psEnc.sCmn.prev_sigtype = sEncCtrl.sCmn.sigtype; - psEnc.sCmn.prevLag = sEncCtrl.sCmn.pitchL[ Silk_define.NB_SUBFR - 1]; - psEnc.sCmn.first_frame_after_reset = 0; - - if( psEnc.sCmn.sRC.error != 0 ) { - /* Encoder returned error: Clear payload buffer */ - psEnc.sCmn.nFramesInPayloadBuf = 0; - } else { - psEnc.sCmn.nFramesInPayloadBuf++; - } - - /****************************************/ - /* Finalize payload and copy to output */ - /****************************************/ - if( psEnc.sCmn.nFramesInPayloadBuf * Silk_define.FRAME_LENGTH_MS >= psEnc.sCmn.PacketSize_ms ) { - - LBRR_idx = ( psEnc.sCmn.oldest_LBRR_idx + 1 ) & Silk_define.LBRR_IDX_MASK; - - /* Check if FEC information should be added */ - frame_terminator = Silk_define.SKP_SILK_LAST_FRAME; - if( psEnc.sCmn.LBRR_buffer[ LBRR_idx ].usage == Silk_define.SKP_SILK_ADD_LBRR_TO_PLUS1 ) { - frame_terminator = Silk_define.SKP_SILK_LBRR_VER1; - } - if( psEnc.sCmn.LBRR_buffer[ psEnc.sCmn.oldest_LBRR_idx ].usage == Silk_define.SKP_SILK_ADD_LBRR_TO_PLUS2 ) { - frame_terminator = Silk_define.SKP_SILK_LBRR_VER2; - LBRR_idx = psEnc.sCmn.oldest_LBRR_idx; - } - - /* Add the frame termination info to stream */ - Silk_range_coder.SKP_Silk_range_encoder( psEnc.sCmn.sRC, frame_terminator, FrameTermination_CDF,0 ); - - /* Payload length so far */ - Silk_range_coder.SKP_Silk_range_coder_get_length( psEnc.sCmn.sRC, nBytes ); - - /* Check that there is enough space in external output buffer, and move data */ - if( pnBytesOut[0] >= nBytes[0] ) { - Silk_range_coder.SKP_Silk_range_enc_wrap_up( psEnc.sCmn.sRC ); - System.arraycopy(psEnc.sCmn.sRC.buffer, 0, pCode, pCode_offset, nBytes[0]); - - if( frame_terminator > Silk_define.SKP_SILK_MORE_FRAMES && - pnBytesOut[0] >= nBytes[0] + psEnc.sCmn.LBRR_buffer[ LBRR_idx ].nBytes ) { - /* Get old packet and add to payload. */ - System.arraycopy(psEnc.sCmn.LBRR_buffer[ LBRR_idx ].payload, 0, - pCode, pCode_offset+nBytes[0], psEnc.sCmn.LBRR_buffer[ LBRR_idx ].nBytes); - nBytes[0] += psEnc.sCmn.LBRR_buffer[ LBRR_idx ].nBytes; - } - pnBytesOut[0] = (short) nBytes[0]; - - /* Update FEC buffer */ - System.arraycopy(LBRRpayload, 0, - psEnc.sCmn.LBRR_buffer[ psEnc.sCmn.oldest_LBRR_idx ].payload, 0, nBytesLBRR[0]); - psEnc.sCmn.LBRR_buffer[ psEnc.sCmn.oldest_LBRR_idx ].nBytes = nBytesLBRR[0]; - /* The below line describes how FEC should be used */ - psEnc.sCmn.LBRR_buffer[ psEnc.sCmn.oldest_LBRR_idx ].usage = sEncCtrl.sCmn.LBRR_usage; - psEnc.sCmn.oldest_LBRR_idx = ( ( psEnc.sCmn.oldest_LBRR_idx + 1 ) & Silk_define.LBRR_IDX_MASK ); - - /* Reset the number of frames in payload buffer */ - psEnc.sCmn.nFramesInPayloadBuf = 0; - } else { - /* Not enough space: Payload will be discarded */ - pnBytesOut[0] = 0; - nBytes[0] = 0; - psEnc.sCmn.nFramesInPayloadBuf = 0; - ret = Silk_errors.SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT; - } - } else { - /* No payload for you this time */ - pnBytesOut[0] = 0; - - /* Encode that more frames follows */ - frame_terminator = Silk_define.SKP_SILK_MORE_FRAMES; - Silk_range_coder.SKP_Silk_range_encoder( psEnc.sCmn.sRC, frame_terminator, FrameTermination_CDF, 0); - - /* Payload length so far */ - Silk_range_coder.SKP_Silk_range_coder_get_length( psEnc.sCmn.sRC, nBytes ); - } - - /* Check for arithmetic coder errors */ - if( psEnc.sCmn.sRC.error != 0 ) { - ret = Silk_errors.SKP_SILK_ENC_INTERNAL_ERROR; - } - - /* simulate number of ms buffered in channel because of exceeding TargetRate */ - psEnc.BufferedInChannel_ms += ( 8.0f * 1000.0f * ( nBytes[0] - psEnc.sCmn.nBytesInPayloadBuf ) ) / psEnc.sCmn.TargetRate_bps; - psEnc.BufferedInChannel_ms -= Silk_define.FRAME_LENGTH_MS; - psEnc.BufferedInChannel_ms = Silk_SigProc_FLP.SKP_LIMIT_float( psEnc.BufferedInChannel_ms, 0.0f, 100.0f ); - psEnc.sCmn.nBytesInPayloadBuf = nBytes[0]; - - if( psEnc.speech_activity > Silk_define_FLP.WB_DETECT_ACTIVE_SPEECH_LEVEL_THRES ) { - psEnc.sCmn.sSWBdetect.ActiveSpeech_ms = Silk_SigProc_FIX.SKP_ADD_POS_SAT32( psEnc.sCmn.sSWBdetect.ActiveSpeech_ms, Silk_define.FRAME_LENGTH_MS ); - } - - return( ret ); - } - - /** - * Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate. - * @param psEnc Encoder state FLP. - * @param psEncCtrl Encoder control FLP. - * @param pCode Payload. - * @param pnBytesOut Payload bytes; in: max; out: used. - * @param xfw Input signal. - */ - static void SKP_Silk_LBRR_encode_FLP( - SKP_Silk_encoder_state_FLP psEnc, /* I/O Encoder state FLP */ - SKP_Silk_encoder_control_FLP psEncCtrl, /* I/O Encoder control FLP */ - byte []pCode, /* O Payload */ - short []pnBytesOut, /* I/O Payload bytes; in: max; out: used */ - float xfw[] /* I Input signal */ - ) - { - int[] Gains_Q16 = new int[ Silk_define.NB_SUBFR ]; - int k, TempGainsIndices[] = new int[ Silk_define.NB_SUBFR ], frame_terminator; - int nBytes[] = new int[1], nFramesInPayloadBuf; - float TempGains[] = new float[ Silk_define.NB_SUBFR ]; - int typeOffset, LTP_scaleIndex, Rate_only_parameters = 0; - /* Control use of inband LBRR */ - Silk_control_codec_FLP.SKP_Silk_LBRR_ctrl_FLP( psEnc, psEncCtrl.sCmn ); - - if( psEnc.sCmn.LBRR_enabled != 0 ) { - /* Save original gains */ - System.arraycopy(psEncCtrl.sCmn.GainsIndices, 0, TempGainsIndices, 0, Silk_define.NB_SUBFR); - System.arraycopy(psEncCtrl.Gains, 0, TempGains, 0, Silk_define.NB_SUBFR); - - typeOffset = psEnc.sCmn.typeOffsetPrev; // Temp save as cannot be overwritten - LTP_scaleIndex = psEncCtrl.sCmn.LTP_scaleIndex; - - /* Set max rate where quant signal is encoded */ - if( psEnc.sCmn.fs_kHz == 8 ) { - Rate_only_parameters = 13500; - } else if( psEnc.sCmn.fs_kHz == 12 ) { - Rate_only_parameters = 15500; - } else if( psEnc.sCmn.fs_kHz == 16 ) { - Rate_only_parameters = 17500; - } else if( psEnc.sCmn.fs_kHz == 24 ) { - Rate_only_parameters = 19500; - } else { - assert( false ); - } - - if( psEnc.sCmn.Complexity > 0 && psEnc.sCmn.TargetRate_bps > Rate_only_parameters ) { - if( psEnc.sCmn.nFramesInPayloadBuf == 0 ) { - /* First frame in packet copy everything */ -//TODO:use clone rather than memory copy. - psEnc.sNSQ_LBRR = (SKP_Silk_nsq_state) psEnc.sNSQ.clone(); - - psEnc.sCmn.LBRRprevLastGainIndex = psEnc.sShape.LastGainIndex; - /* Increase Gains to get target LBRR rate */ - psEncCtrl.sCmn.GainsIndices[ 0 ] += psEnc.sCmn.LBRR_GainIncreases; - psEncCtrl.sCmn.GainsIndices[ 0 ] = Silk_SigProc_FIX.SKP_LIMIT( psEncCtrl.sCmn.GainsIndices[ 0 ], 0, Silk_define.N_LEVELS_QGAIN - 1 ); - } - /* Decode to get Gains in sync with decoder */ - int LBRRprevLastGainIndex_ptr[] = new int[1]; - LBRRprevLastGainIndex_ptr[0] = psEnc.sCmn.LBRRprevLastGainIndex; - Silk_gain_quant.SKP_Silk_gains_dequant( Gains_Q16, psEncCtrl.sCmn.GainsIndices, - LBRRprevLastGainIndex_ptr, psEnc.sCmn.nFramesInPayloadBuf ); - psEnc.sCmn.LBRRprevLastGainIndex = LBRRprevLastGainIndex_ptr[0]; - - /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - psEncCtrl.Gains[ k ] = Gains_Q16[ k ] / 65536.0f; - } - - /*****************************************/ - /* Noise shaping quantization */ - /*****************************************/ - Silk_wrappers_FLP.SKP_Silk_NSQ_wrapper_FLP( psEnc, psEncCtrl, xfw, 0, psEnc.sCmn.q_LBRR, 0, 1 ); - } else { - Arrays.fill(psEnc.sCmn.q_LBRR, (byte)0); - psEncCtrl.sCmn.LTP_scaleIndex = 0; - } - /****************************************/ - /* Initialize arithmetic coder */ - /****************************************/ - if( psEnc.sCmn.nFramesInPayloadBuf == 0 ) { - Silk_range_coder.SKP_Silk_range_enc_init( psEnc.sCmn.sRC_LBRR ); - psEnc.sCmn.nBytesInPayloadBuf = 0; - } - - /****************************************/ - /* Encode Parameters */ - /****************************************/ - Silk_encode_parameters.SKP_Silk_encode_parameters( psEnc.sCmn, psEncCtrl.sCmn, psEnc.sCmn.sRC_LBRR, psEnc.sCmn.q_LBRR ); - /****************************************/ - /* Encode Parameters */ - /****************************************/ - if( psEnc.sCmn.sRC_LBRR.error != 0) { - /* Encoder returned error: Clear payload buffer */ - nFramesInPayloadBuf = 0; - } else { - nFramesInPayloadBuf = psEnc.sCmn.nFramesInPayloadBuf + 1; - } - - /****************************************/ - /* Finalize payload and copy to output */ - /****************************************/ - if( Silk_macros.SKP_SMULBB( nFramesInPayloadBuf, Silk_define.FRAME_LENGTH_MS ) >= psEnc.sCmn.PacketSize_ms ) { - - /* Check if FEC information should be added */ - frame_terminator = Silk_define.SKP_SILK_LAST_FRAME; - - /* Add the frame termination info to stream */ - Silk_range_coder.SKP_Silk_range_encoder( psEnc.sCmn.sRC_LBRR, frame_terminator, Silk_tables_other.SKP_Silk_FrameTermination_CDF, 0 ); - - /* Payload length so far */ - Silk_range_coder.SKP_Silk_range_coder_get_length( psEnc.sCmn.sRC_LBRR, nBytes ); - - /* Check that there is enough space in external output buffer and move data */ - if( pnBytesOut[0] >= nBytes[0] ) { - Silk_range_coder.SKP_Silk_range_enc_wrap_up( psEnc.sCmn.sRC_LBRR ); - System.arraycopy(psEnc.sCmn.sRC_LBRR.buffer, 0, pCode, 0, nBytes[0]); - - pnBytesOut[0] = (short) nBytes[0]; - } else { - /* Not enough space: Payload will be discarded */ - pnBytesOut[0] = 0; - assert( false ); - } - } else { - /* No payload for you this time */ - pnBytesOut[0] = 0; - - /* Encode that more frames follows */ - frame_terminator = Silk_define.SKP_SILK_MORE_FRAMES; - Silk_range_coder.SKP_Silk_range_encoder( psEnc.sCmn.sRC_LBRR, frame_terminator, Silk_tables_other.SKP_Silk_FrameTermination_CDF, 0 ); - } - - /* Restore original Gains */ - System.arraycopy(TempGainsIndices, 0, psEncCtrl.sCmn.GainsIndices, 0, Silk_define.NB_SUBFR); - System.arraycopy(TempGains, 0, psEncCtrl.Gains, 0, Silk_define.NB_SUBFR); - - /* Restore LTP scale index and typeoffset */ - psEncCtrl.sCmn.LTP_scaleIndex = LTP_scaleIndex; - psEnc.sCmn.typeOffsetPrev = typeOffset; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_encode_parameters.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_encode_parameters.java deleted file mode 100644 index df221b690..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_encode_parameters.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Encode parameters to create the payload. - * - * @author Dingxin Xu - */ -public class Silk_encode_parameters -{ - /** - * Encode parameters to create the payload. - * @param psEncC Encoder state. - * @param psEncCtrlC Encoder control. - * @param psRC Range encoder state. - * @param q Quantization indices. - */ - static void SKP_Silk_encode_parameters( - SKP_Silk_encoder_state psEncC, /* I/O Encoder state */ - SKP_Silk_encoder_control psEncCtrlC, /* I/O Encoder control */ - SKP_Silk_range_coder_state psRC, /* I/O Range encoder state */ - byte []q /* I Quantization indices */ - ) - { - int i, k, typeOffset; - final SKP_Silk_NLSF_CB_struct psNLSF_CB; - - - /************************/ - /* Encode sampling rate */ - /************************/ - /* only done for first frame in packet */ - if( psEncC.nFramesInPayloadBuf == 0 ) { - /* get sampling rate index */ - for( i = 0; i < 3; i++ ) { - if( Silk_tables_other.SKP_Silk_SamplingRates_table[ i ] == psEncC.fs_kHz ) { - break; - } - } - Silk_range_coder.SKP_Silk_range_encoder( psRC, i, Silk_tables_other.SKP_Silk_SamplingRates_CDF, 0 ); - } - - /*******************************************/ - /* Encode signal type and quantizer offset */ - /*******************************************/ - typeOffset = 2 * psEncCtrlC.sigtype + psEncCtrlC.QuantOffsetType; - if( psEncC.nFramesInPayloadBuf == 0 ) { - /* first frame in packet: independent coding */ - Silk_range_coder.SKP_Silk_range_encoder( psRC, typeOffset, Silk_tables_type_offset.SKP_Silk_type_offset_CDF, 0); - } else { - /* condidtional coding */ - Silk_range_coder.SKP_Silk_range_encoder( psRC, typeOffset, Silk_tables_type_offset.SKP_Silk_type_offset_joint_CDF[ psEncC.typeOffsetPrev ], 0); - } - psEncC.typeOffsetPrev = typeOffset; - - /****************/ - /* Encode gains */ - /****************/ - /* first subframe */ - if( psEncC.nFramesInPayloadBuf == 0 ) { - /* first frame in packet: independent coding */ - Silk_range_coder.SKP_Silk_range_encoder( psRC, psEncCtrlC.GainsIndices[ 0 ], Silk_tables_gain.SKP_Silk_gain_CDF[ psEncCtrlC.sigtype ], 0); - } else { - /* condidtional coding */ - Silk_range_coder.SKP_Silk_range_encoder( psRC, psEncCtrlC.GainsIndices[ 0 ], Silk_tables_gain.SKP_Silk_delta_gain_CDF, 0); - } - - /* remaining subframes */ - for( i = 1; i < Silk_define.NB_SUBFR; i++ ) { - Silk_range_coder.SKP_Silk_range_encoder( psRC, psEncCtrlC.GainsIndices[ i ], Silk_tables_gain.SKP_Silk_delta_gain_CDF, 0); - } - - - /****************/ - /* Encode NLSFs */ - /****************/ - /* Range encoding of the NLSF path */ - psNLSF_CB = psEncC.psNLSF_CB[ psEncCtrlC.sigtype ]; - Silk_range_coder.SKP_Silk_range_encoder_multi( psRC, psEncCtrlC.NLSFIndices, psNLSF_CB.StartPtr, psNLSF_CB.nStages ); - - /* Encode NLSF interpolation factor */ - assert( psEncC.useInterpolatedNLSFs == 1 || psEncCtrlC.NLSFInterpCoef_Q2 == ( 1 << 2 ) ); - Silk_range_coder.SKP_Silk_range_encoder( psRC, psEncCtrlC.NLSFInterpCoef_Q2, Silk_tables_other.SKP_Silk_NLSF_interpolation_factor_CDF, 0); - - - if( psEncCtrlC.sigtype == Silk_define.SIG_TYPE_VOICED ) { - /*********************/ - /* Encode pitch lags */ - /*********************/ - - - /* lag index */ - if( psEncC.fs_kHz == 8 ) { - Silk_range_coder.SKP_Silk_range_encoder( psRC, psEncCtrlC.lagIndex, Silk_tables_pitch_lag.SKP_Silk_pitch_lag_NB_CDF, 0); - } else if( psEncC.fs_kHz == 12 ) { - Silk_range_coder.SKP_Silk_range_encoder( psRC, psEncCtrlC.lagIndex, Silk_tables_pitch_lag.SKP_Silk_pitch_lag_MB_CDF, 0); - } else if( psEncC.fs_kHz == 16 ) { - Silk_range_coder.SKP_Silk_range_encoder( psRC, psEncCtrlC.lagIndex, Silk_tables_pitch_lag.SKP_Silk_pitch_lag_WB_CDF, 0); - } else { - Silk_range_coder.SKP_Silk_range_encoder( psRC, psEncCtrlC.lagIndex, Silk_tables_pitch_lag.SKP_Silk_pitch_lag_SWB_CDF, 0); - } - - - /* countour index */ - if( psEncC.fs_kHz == 8 ) { - /* Less codevectors used in 8 khz mode */ - Silk_range_coder.SKP_Silk_range_encoder( psRC, psEncCtrlC.contourIndex, Silk_tables_pitch_lag.SKP_Silk_pitch_contour_NB_CDF, 0); - } else { - /* Joint for 12, 16, 24 khz */ - Silk_range_coder.SKP_Silk_range_encoder( psRC, psEncCtrlC.contourIndex, Silk_tables_pitch_lag.SKP_Silk_pitch_contour_CDF, 0); - } - - /********************/ - /* Encode LTP gains */ - /********************/ - - /* PERIndex value */ - Silk_range_coder.SKP_Silk_range_encoder( psRC, psEncCtrlC.PERIndex, Silk_tables_LTP.SKP_Silk_LTP_per_index_CDF, 0); - - /* Codebook Indices */ - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - Silk_range_coder.SKP_Silk_range_encoder( psRC, psEncCtrlC.LTPIndex[ k ], Silk_tables_LTP.SKP_Silk_LTP_gain_CDF_ptrs[ psEncCtrlC.PERIndex ], 0); - } - - /**********************/ - /* Encode LTP scaling */ - /**********************/ - Silk_range_coder.SKP_Silk_range_encoder( psRC, psEncCtrlC.LTP_scaleIndex, Silk_tables_other.SKP_Silk_LTPscale_CDF, 0); - } - - - /***************/ - /* Encode seed */ - /***************/ - Silk_range_coder.SKP_Silk_range_encoder( psRC, psEncCtrlC.Seed, Silk_tables_other.SKP_Silk_Seed_CDF, 0); - - /*********************************************/ - /* Encode quantization indices of excitation */ - /*********************************************/ - Silk_encode_pulses.SKP_Silk_encode_pulses( psRC, psEncCtrlC.sigtype, psEncCtrlC.QuantOffsetType, q, psEncC.frame_length ); - - - /*********************************************/ - /* Encode VAD flag */ - /*********************************************/ - Silk_range_coder.SKP_Silk_range_encoder( psRC, psEncC.vadFlag, Silk_tables_other.SKP_Silk_vadflag_CDF, 0); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_encode_pulses.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_encode_pulses.java deleted file mode 100644 index 7a8710591..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_encode_pulses.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Encode quantization indices of excitation. - * - * @author Dingxin Xu - */ -public class Silk_encode_pulses -{ - /** - * - * @param pulses_comb - * @param pulses_in - * @param pulses_in_offset offset of valid data. - * @param max_pulses max value for sum of pulses. - * @param len number of output values. - * @return - */ - static int combine_and_check( /* return ok */ - int []pulses_comb, /* O */ - final int []pulses_in, /* I */ - int pulses_in_offset, - int max_pulses, /* I max value for sum of pulses */ - int len /* I number of output values */ - ) - { - int k, sum; - - for( k = 0; k < len; k++ ) { - sum = pulses_in[ pulses_in_offset + 2 * k ] + pulses_in[ pulses_in_offset+ 2 * k + 1 ]; - if( sum > max_pulses ) { - return 1; - } - pulses_comb[ k ] = sum; - } - return 0; - } - - /** - * Encode quantization indices of excitation. - * @param psRC Range coder state - * @param sigtype Sigtype - * @param QuantOffsetType QuantOffsetType - * @param q quantization - * @param frame_length Frame length - */ - static void SKP_Silk_encode_pulses( - SKP_Silk_range_coder_state psRC, /* I/O Range coder state */ - final int sigtype, /* I Sigtype */ - final int QuantOffsetType,/* I QuantOffsetType */ - final byte q[], /* I quantization indices */ - final int frame_length /* I Frame length */ - ) - { - int i, k, j, iter, bit, nLS, scale_down, RateLevelIndex = 0; - int abs_q, minSumBits_Q6, sumBits_Q6; - int[] abs_pulses = new int[ Silk_define.MAX_FRAME_LENGTH ]; - int[] sum_pulses = new int[ Silk_define.MAX_NB_SHELL_BLOCKS ]; - int[] nRshifts = new int[ Silk_define.MAX_NB_SHELL_BLOCKS ]; - int[] pulses_comb = new int[ 8 ]; - int []abs_pulses_ptr; - int abs_pulses_ptr_offset; - byte []pulses_ptr; - int pulses_ptr_offset; - final int [] cdf_ptr; - short[] nBits_ptr; - - - /****************************/ - /* Prepare for shell coding */ - /****************************/ - /* Calculate number of shell blocks */ - iter = frame_length / Silk_define.SHELL_CODEC_FRAME_LENGTH; - - /* Take the absolute value of the pulses */ - for( i = 0; i < frame_length; i+=4 ) { - abs_pulses[i+0] = q[i+0] > 0 ? q[i+0] : (-q[i+0]); - abs_pulses[i+1] = q[i+1] > 0 ? q[i+1] : (-q[i+1]); - abs_pulses[i+2] = q[i+2] > 0 ? q[i+2] : (-q[i+2]); - abs_pulses[i+3] = q[i+3] > 0 ? q[i+3] : (-q[i+3]); - } - - /* Calc sum pulses per shell code frame */ - abs_pulses_ptr = abs_pulses; - abs_pulses_ptr_offset = 0; - for( i = 0; i < iter; i++ ) { - nRshifts[ i ] = 0; - - while( true ) { - /* 1+1 -> 2 */ - scale_down = combine_and_check( pulses_comb, abs_pulses_ptr, abs_pulses_ptr_offset, - Silk_tables_pulses_per_block.SKP_Silk_max_pulses_table[ 0 ], 8 ); - - /* 2+2 -> 4 */ - scale_down += combine_and_check( pulses_comb, pulses_comb, 0, - Silk_tables_pulses_per_block.SKP_Silk_max_pulses_table[ 1 ], 4 ); - - /* 4+4 -> 8 */ - scale_down += combine_and_check( pulses_comb, pulses_comb, 0, - Silk_tables_pulses_per_block.SKP_Silk_max_pulses_table[ 2 ], 2 ); - - /* 8+8 -> 16 */ - sum_pulses[ i ] = pulses_comb[ 0 ] + pulses_comb[ 1 ]; - if( sum_pulses[ i ] > Silk_tables_pulses_per_block.SKP_Silk_max_pulses_table[ 3 ] ) { - scale_down++; - } - - if( scale_down !=0 ) { - /* We need to down scale the quantization signal */ - nRshifts[ i ]++; - for( k = 0; k < Silk_define.SHELL_CODEC_FRAME_LENGTH; k++ ) { - abs_pulses_ptr[ abs_pulses_ptr_offset + k ] = ( abs_pulses_ptr[ abs_pulses_ptr_offset + k ] >>1 ); - } - } else { - /* Jump out of while(1) loop and go to next shell coding frame */ - break; - } - } - abs_pulses_ptr_offset += Silk_define.SHELL_CODEC_FRAME_LENGTH; - } - - /**************/ - /* Rate level */ - /**************/ - /* find rate level that leads to fewest bits for coding of pulses per block info */ - minSumBits_Q6 = Integer.MAX_VALUE; - for( k = 0; k < Silk_define.N_RATE_LEVELS - 1; k++ ) { - nBits_ptr = Silk_tables_pulses_per_block.SKP_Silk_pulses_per_block_BITS_Q6[ k ]; - sumBits_Q6 = Silk_tables_pulses_per_block.SKP_Silk_rate_levels_BITS_Q6[sigtype][ k ]; - for( i = 0; i < iter; i++ ) { - if( nRshifts[ i ] > 0 ) { - sumBits_Q6 += nBits_ptr[ Silk_define.MAX_PULSES + 1 ]; - } else { - sumBits_Q6 += nBits_ptr[ sum_pulses[ i ] ]; - } - } - if( sumBits_Q6 < minSumBits_Q6 ) { - minSumBits_Q6 = sumBits_Q6; - RateLevelIndex = k; - } - } - Silk_range_coder.SKP_Silk_range_encoder( psRC, RateLevelIndex, - Silk_tables_pulses_per_block.SKP_Silk_rate_levels_CDF[ sigtype ], 0); - - /***************************************************/ - /* Sum-Weighted-Pulses Encoding */ - /***************************************************/ - cdf_ptr = Silk_tables_pulses_per_block.SKP_Silk_pulses_per_block_CDF[ RateLevelIndex ]; - for( i = 0; i < iter; i++ ) { - if( nRshifts[ i ] == 0 ) { - Silk_range_coder.SKP_Silk_range_encoder( psRC, sum_pulses[ i ], cdf_ptr, 0); - } else { - Silk_range_coder.SKP_Silk_range_encoder( psRC, Silk_define.MAX_PULSES + 1, cdf_ptr, 0); - for( k = 0; k < nRshifts[ i ] - 1; k++ ) { - Silk_range_coder.SKP_Silk_range_encoder( psRC, Silk_define.MAX_PULSES + 1, - Silk_tables_pulses_per_block.SKP_Silk_pulses_per_block_CDF[ Silk_define.N_RATE_LEVELS - 1 ], 0); - } - Silk_range_coder.SKP_Silk_range_encoder( psRC, sum_pulses[ i ], - Silk_tables_pulses_per_block.SKP_Silk_pulses_per_block_CDF[ Silk_define.N_RATE_LEVELS - 1 ], 0); - } - } - - /******************/ - /* Shell Encoding */ - /******************/ - for( i = 0; i < iter; i++ ) { - if( sum_pulses[ i ] > 0 ) { - Silk_shell_coder.SKP_Silk_shell_encoder( psRC, abs_pulses, i * Silk_define.SHELL_CODEC_FRAME_LENGTH); - } - } - - /****************/ - /* LSB Encoding */ - /****************/ - for( i = 0; i < iter; i++ ) { - if( nRshifts[ i ] > 0 ) { - pulses_ptr = q; - pulses_ptr_offset = i * Silk_define.SHELL_CODEC_FRAME_LENGTH; - nLS = nRshifts[ i ] - 1; - for( k = 0; k < Silk_define.SHELL_CODEC_FRAME_LENGTH; k++ ) { - abs_q = pulses_ptr[pulses_ptr_offset + k] > 0 ? pulses_ptr[pulses_ptr_offset + k]: (-pulses_ptr[pulses_ptr_offset + k]); - for( j = nLS; j > 0; j-- ) { - bit = ( abs_q >> j ) & 1; - Silk_range_coder.SKP_Silk_range_encoder( psRC, bit, Silk_tables_other.SKP_Silk_lsb_CDF, 0); - } - bit = abs_q & 1; - Silk_range_coder.SKP_Silk_range_encoder( psRC, bit, Silk_tables_other.SKP_Silk_lsb_CDF, 0); - } - } - } - - /****************/ - /* Encode signs */ - /****************/ - Silk_code_signs.SKP_Silk_encode_signs( psRC, q, frame_length, sigtype, QuantOffsetType, RateLevelIndex ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_energy_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_energy_FLP.java deleted file mode 100644 index d31c48e08..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_energy_FLP.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_energy_FLP -{ - /** - * sum of squares of a float array, with result as double. - * @param data - * @param data_offset - * @param dataSize - * @return - */ -//TODO: float or double??? - static double SKP_Silk_energy_FLP - ( - float[] data, - int data_offset, - int dataSize - ) - { - int i, dataSize4; - double result; - - /* 4x unrolled loop */ - result = 0.0f; - dataSize4 = dataSize & 0xFFFC; - for( i = 0; i < dataSize4; i += 4 ) - { - result += data[data_offset+ i + 0 ] * data[data_offset+ i + 0 ] + - data[data_offset+ i + 1 ] * data[data_offset+ i + 1 ] + - data[data_offset+ i + 2 ] * data[data_offset+ i + 2 ] + - data[data_offset+ i + 3 ] * data[data_offset+ i + 3 ]; - } - - /* add any remaining products */ - for( ; i < dataSize; i++ ) - { - result += data[data_offset+ i ] * data[data_offset+ i ]; - } - - assert( result >= 0.0 ); - return result; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_errors.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_errors.java deleted file mode 100644 index 8f8138336..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_errors.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Error messages. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_errors { - /******************/ - /* Error messages */ - /******************/ - static final int SKP_SILK_NO_ERROR = 0; - - /**************************/ - /* Encoder error messages */ - /**************************/ - - /** - * Input length is not a multiplum of 10 ms, or length is longer than the - * packet length. - */ - static final int SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES = -1; - - /** Sampling frequency not 8000, 12000, 16000 or 24000 Hertz */ - static final int SKP_SILK_ENC_FS_NOT_SUPPORTED = -2; - - /** Packet size not 20, 40, 60, 80 or 100 ms */ - static final int SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED = -3; - - /** Allocated payload buffer too short */ - static final int SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT = -4; - - /** Loss rate not between 0 and 100 percent */ - static final int SKP_SILK_ENC_INVALID_LOSS_RATE = -5; - - /** Complexity setting not valid, use 0, 1 or 2 */ - static final int SKP_SILK_ENC_INVALID_COMPLEXITY_SETTING = -6; - - /** Inband FEC setting not valid, use 0 or 1 */ - static final int SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING = -7; - - /** DTX setting not valid, use 0 or 1 */ - static final int SKP_SILK_ENC_INVALID_DTX_SETTING = -8; - - /** Internal encoder error */ - static final int SKP_SILK_ENC_INTERNAL_ERROR = -9; - - /**************************/ - /* Decoder error messages */ - /**************************/ - - /** Output sampling frequency lower than internal decoded sampling frequency */ - static final int SKP_SILK_DEC_INVALID_SAMPLING_FREQUENCY = -10; - - /** Payload size exceeded the maximum allowed 1024 bytes */ - static final int SKP_SILK_DEC_PAYLOAD_TOO_LARGE = -11; - - /** Payload has bit errors */ - static final int SKP_SILK_DEC_PAYLOAD_ERROR = -12; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_find_LPC_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_find_LPC_FLP.java deleted file mode 100644 index 1cd0f0dd4..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_find_LPC_FLP.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Dingxin Xu - */ -public class Silk_find_LPC_FLP -{ - /** - * - * @param NLSF NLSFs. - * @param interpIndex NLSF interp. index for NLSF interp. - * @param prev_NLSFq Previous NLSFs, for NLSF interpolation. - * @param useInterpNLSFs Flag. - * @param LPC_order LPC order. - * @param x Input signal. - * @param subfr_length Subframe length incl preceeding samples. - */ - static void SKP_Silk_find_LPC_FLP( - float NLSF[], /* O NLSFs */ - int []interpIndex, /* O NLSF interp. index for NLSF interp. */ - final float prev_NLSFq[], /* I Previous NLSFs, for NLSF interpolation */ - final int useInterpNLSFs, /* I Flag */ - final int LPC_order, /* I LPC order */ - final float x[], /* I Input signal */ - final int subfr_length /* I Subframe length incl preceeding samples */ - ) - { - int k; - float[] a = new float[ Silk_define.MAX_LPC_ORDER ]; - - /* Used only for NLSF interpolation */ - double res_nrg, res_nrg_2nd, res_nrg_interp; - float a_tmp[] = new float[ Silk_define.MAX_LPC_ORDER ], NLSF0[] = new float[ Silk_define.MAX_LPC_ORDER ]; - float LPC_res[] = new float[ ( Silk_define.MAX_FRAME_LENGTH + Silk_define.NB_SUBFR * Silk_define.MAX_LPC_ORDER ) / 2 ]; - - /* Default: No interpolation */ - interpIndex[0] = 4; - - /* Burg AR analysis for the full frame */ - res_nrg = Silk_burg_modified_FLP.SKP_Silk_burg_modified_FLP( a, x, 0, subfr_length, Silk_define.NB_SUBFR, - Silk_define_FLP.FIND_LPC_COND_FAC, LPC_order ); - - if( useInterpNLSFs == 1 ) { - - /* Optimal solution for last 10 ms; subtract residual energy here, as that's easier than */ - /* adding it to the residual energy of the first 10 ms in each iteration of the search below */ - res_nrg -= Silk_burg_modified_FLP.SKP_Silk_burg_modified_FLP( a_tmp, x, ( Silk_define.NB_SUBFR / 2 ) * subfr_length, - subfr_length, Silk_define.NB_SUBFR / 2, Silk_define_FLP.FIND_LPC_COND_FAC, LPC_order ); - - /* Convert to NLSFs */ - Silk_wrappers_FLP.SKP_Silk_A2NLSF_FLP( NLSF, a_tmp, LPC_order ); - - /* Search over interpolation indices to find the one with lowest residual energy */ - res_nrg_2nd = Float.MAX_VALUE; - for( k = 3; k >= 0; k-- ) { - /* Interpolate NLSFs for first half */ - Silk_wrappers_FLP.SKP_Silk_interpolate_wrapper_FLP( NLSF0, prev_NLSFq, NLSF, 0.25f * k, LPC_order ); - - /* Convert to LPC for residual energy evaluation */ - Silk_wrappers_FLP.SKP_Silk_NLSF2A_stable_FLP( a_tmp, NLSF0, LPC_order ); - - /* Calculate residual energy with LSF interpolation */ - Silk_LPC_analysis_filter_FLP.SKP_Silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 0, 2 * subfr_length, LPC_order ); - res_nrg_interp = - Silk_energy_FLP.SKP_Silk_energy_FLP( LPC_res, LPC_order, subfr_length - LPC_order ) + - Silk_energy_FLP.SKP_Silk_energy_FLP( LPC_res, LPC_order + subfr_length, subfr_length - LPC_order ); - - /* Determine whether current interpolated NLSFs are best so far */ - if( res_nrg_interp < res_nrg ) { - /* Interpolation has lower residual energy */ - res_nrg = res_nrg_interp; - interpIndex[0] = k; - } else if( res_nrg_interp > res_nrg_2nd ) { - /* No reason to continue iterating - residual energies will continue to climb */ - break; - } - res_nrg_2nd = res_nrg_interp; - } - } - - if( interpIndex[0] == 4 ) { - /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */ - Silk_wrappers_FLP.SKP_Silk_A2NLSF_FLP( NLSF, a, LPC_order ); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_find_LTP_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_find_LTP_FLP.java deleted file mode 100644 index 2decc6024..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_find_LTP_FLP.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_find_LTP_FLP -{ - /** - * - * @param b LTP coefs. - * @param WLTP Weight for LTP quantization. - * @param LTPredCodGain LTP coding gain. - * @param r_first LPC residual, signal + state for 10 ms. - * @param r_last LPC residual, signal + state for 10 ms. - * @param r_last_offset offset of valid data. - * @param lag LTP lags. - * @param Wght Weights. - * @param subfr_length Subframe length. - * @param mem_offset Number of samples in LTP memory. - */ - static void SKP_Silk_find_LTP_FLP( - float b[], /* O LTP coefs */ - float WLTP[], /* O Weight for LTP quantization */ - float LTPredCodGain[], /* O LTP coding gain */ - final float r_first[], /* I LPC residual, signal + state for 10 ms */ - final float r_last[], /* I LPC residual, signal + state for 10 ms */ - int r_last_offset, - final int lag[ ], /* I LTP lags */ - final float Wght[ ], /* I Weights */ - final int subfr_length, /* I Subframe length */ - final int mem_offset /* I Number of samples in LTP memory */ - ) - { - int i,k; - float b_ptr[], temp, WLTP_ptr[]; - float LPC_res_nrg, LPC_LTP_res_nrg; - float d[] = new float[Silk_define.NB_SUBFR], m, g, delta_b[]=new float[Silk_define.LTP_ORDER]; - float w[] = new float[Silk_define.NB_SUBFR], nrg[] = new float[Silk_define.NB_SUBFR], regu; - float Rr[] = new float[Silk_define.LTP_ORDER], rr[] = new float[Silk_define.NB_SUBFR]; - float r_ptr[], lag_ptr[]; - int r_ptr_offset, lag_ptr_offset; - - b_ptr = b; - int b_ptr_offset = 0; - WLTP_ptr = WLTP; - int WLTP_ptr_offset = 0; - r_ptr = r_first; - r_ptr_offset = mem_offset; - - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - if( k == ( Silk_define.NB_SUBFR >> 1 ) ) { /* Shift residual for last 10 ms */ - r_ptr = r_last; - r_ptr_offset = r_last_offset + mem_offset; - } - lag_ptr = r_ptr; - lag_ptr_offset = r_ptr_offset - (lag[k] + Silk_define.LTP_ORDER/2); - - Silk_corrMatrix_FLP.SKP_Silk_corrMatrix_FLP(lag_ptr, lag_ptr_offset, subfr_length, Silk_define.LTP_ORDER, WLTP_ptr, WLTP_ptr_offset); - Silk_corrMatrix_FLP.SKP_Silk_corrVector_FLP(lag_ptr, lag_ptr_offset, r_ptr, r_ptr_offset, subfr_length, Silk_define.LTP_ORDER, Rr); - - - rr[k] = (float) Silk_energy_FLP.SKP_Silk_energy_FLP(r_ptr, r_ptr_offset, subfr_length); - - regu = Silk_define_FLP.LTP_DAMPING * ( rr[ k ] + 1.0f ); - - Silk_regularize_correlations_FLP.SKP_Silk_regularize_correlations_FLP(WLTP_ptr, WLTP_ptr_offset, rr, k, regu, Silk_define.LTP_ORDER); - Silk_solve_LS_FLP.SKP_Silk_solve_LDL_FLP( WLTP_ptr, WLTP_ptr_offset, Silk_define.LTP_ORDER, Rr, b_ptr, b_ptr_offset ); - - /* Calculate residual energy */ - nrg[ k ] = Silk_residual_energy_FLP.SKP_Silk_residual_energy_covar_FLP( b_ptr, b_ptr_offset, - WLTP_ptr, WLTP_ptr_offset, Rr, rr[ k ], Silk_define.LTP_ORDER ); - - temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); - Silk_scale_vector_FLP.SKP_Silk_scale_vector_FLP( WLTP_ptr, WLTP_ptr_offset, temp, Silk_define.LTP_ORDER * Silk_define.LTP_ORDER ); -// w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER / 2, LTP_ORDER / 2, LTP_ORDER ); - w[k] = WLTP_ptr[WLTP_ptr_offset + ((Silk_define.LTP_ORDER/2) * Silk_define.LTP_ORDER + Silk_define.LTP_ORDER/2)]; - - r_ptr_offset += subfr_length; - b_ptr_offset += Silk_define.LTP_ORDER; - WLTP_ptr_offset += Silk_define.LTP_ORDER * Silk_define.LTP_ORDER; - } - - /* Compute LTP coding gain */ - if( LTPredCodGain != null ) { - LPC_LTP_res_nrg = 1e-6f; - LPC_res_nrg = 0.0f; - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - LPC_res_nrg += rr[ k ] * Wght[ k ]; - LPC_LTP_res_nrg += nrg[ k ] * Wght[ k ]; - } - - assert( LPC_LTP_res_nrg > 0 ); - LTPredCodGain[0] = 3.0f * Silk_main_FLP.SKP_Silk_log2( LPC_res_nrg / LPC_LTP_res_nrg ); - } - - /* Smoothing */ - /* d = sum( B, 1 ); */ - b_ptr = b; - b_ptr_offset = 0; - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - d[ k ] = 0; - for( i = 0; i < Silk_define.LTP_ORDER; i++ ) { - d[ k ] += b_ptr[ b_ptr_offset + i ]; - } - b_ptr_offset += Silk_define.LTP_ORDER; - } - /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */ - temp = 1e-3f; - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - temp += w[ k ]; - } - m = 0; - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - m += d[ k ] * w[ k ]; - } - m = m / temp; - - b_ptr = b; - b_ptr_offset = 0; - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - g = Silk_define_FLP.LTP_SMOOTHING / ( Silk_define_FLP.LTP_SMOOTHING + w[ k ] ) * ( m - d[ k ] ); - temp = 0; - for( i = 0; i < Silk_define.LTP_ORDER; i++ ) { - delta_b[ i ] = Math.max( b_ptr[ i ], 0.1f ); - temp += delta_b[ i ]; - } - temp = g / temp; - for( i = 0; i < Silk_define.LTP_ORDER; i++ ) { - b_ptr[ i ] = b_ptr[ i ] + delta_b[ i ] * temp; - } - b_ptr_offset += Silk_define.LTP_ORDER; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_find_pitch_lags_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_find_pitch_lags_FLP.java deleted file mode 100644 index 8bdd4f2c0..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_find_pitch_lags_FLP.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_find_pitch_lags_FLP -{ - /** - * - * @param psEnc Encoder state FLP. - * @param psEncCtrl Encoder control FLP. - * @param res Residual. - * @param x Speech signal. - * @param x_offset offset of valid data. - */ - static void SKP_Silk_find_pitch_lags_FLP( - SKP_Silk_encoder_state_FLP psEnc, /* I/O Encoder state FLP */ - SKP_Silk_encoder_control_FLP psEncCtrl, /* I/O Encoder control FLP */ - float res[], /* O Residual */ - float x[], /* I Speech signal */ - int x_offset - ) - { - SKP_Silk_predict_state_FLP psPredSt = psEnc.sPred; -// const SKP_float *x_buf_ptr, *x_buf; - float[] x_buf_ptr, x_buf; - int x_buf_ptr_offset, x_buf_offset; - float[] auto_corr = new float[ Silk_define.FIND_PITCH_LPC_ORDER_MAX + 1 ]; - float[] A = new float[ Silk_define.FIND_PITCH_LPC_ORDER_MAX ]; - float[] refl_coef = new float[ Silk_define.FIND_PITCH_LPC_ORDER_MAX ]; - float[] Wsig = new float[ Silk_define.FIND_PITCH_LPC_WIN_MAX ]; - float thrhld; - float[] Wsig_ptr; - int Wsig_ptr_offset; - int buf_len; - - /******************************************/ - /* Setup buffer lengths etc based of Fs */ - /******************************************/ - buf_len = 2 * psEnc.sCmn.frame_length + psEnc.sCmn.la_pitch; - - /* Safty check */ - assert( buf_len >= psPredSt.pitch_LPC_win_length ); - -// x_buf = x - psEnc->sCmn.frame_length; - x_buf = x; - x_buf_offset = x_offset - psEnc.sCmn.frame_length; - - /*************************************/ - /* Estimate LPC AR coeficients */ - /*************************************/ - - /* Calculate windowed signal */ - - /* First LA_LTP samples */ -// x_buf_ptr = x_buf + buf_len - psPredSt->pitch_LPC_win_length; - x_buf_ptr = x_buf; - x_buf_ptr_offset = x_buf_offset + buf_len - psPredSt.pitch_LPC_win_length; - Wsig_ptr = Wsig; - Wsig_ptr_offset=0; - Silk_apply_sine_window_FLP.SKP_Silk_apply_sine_window_FLP( Wsig_ptr,Wsig_ptr_offset, x_buf_ptr,x_buf_ptr_offset, 1, psEnc.sCmn.la_pitch ); - - /* Middle non-windowed samples */ - Wsig_ptr_offset += psEnc.sCmn.la_pitch; - x_buf_ptr_offset += psEnc.sCmn.la_pitch; -// SKP_memcpy( Wsig_ptr, x_buf_ptr, ( psPredSt->pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ) ) * sizeof( SKP_float ) ); - for(int i_djinn=0; i_djinn< psPredSt.pitch_LPC_win_length - ( psEnc.sCmn.la_pitch << 1 ); i_djinn++) - Wsig_ptr[Wsig_ptr_offset + i_djinn] = x_buf_ptr[x_buf_ptr_offset+i_djinn]; - - /* Last LA_LTP samples */ - Wsig_ptr_offset += psPredSt.pitch_LPC_win_length - ( psEnc.sCmn.la_pitch << 1 ); - x_buf_ptr_offset += psPredSt.pitch_LPC_win_length - ( psEnc.sCmn.la_pitch << 1 ); - Silk_apply_sine_window_FLP.SKP_Silk_apply_sine_window_FLP( Wsig_ptr,Wsig_ptr_offset, x_buf_ptr,x_buf_ptr_offset, 2, psEnc.sCmn.la_pitch ); - - /* Calculate autocorrelation sequence */ - Silk_autocorrelation_FLP.SKP_Silk_autocorrelation_FLP( auto_corr,0, Wsig,0, psPredSt.pitch_LPC_win_length, psEnc.sCmn.pitchEstimationLPCOrder + 1 ); - - /* Add white noise, as a fraction of the energy */ - auto_corr[ 0 ] += auto_corr[ 0 ] * Silk_define_FLP.FIND_PITCH_WHITE_NOISE_FRACTION; - - /* Calculate the reflection coefficients using Schur */ - Silk_schur_FLP.SKP_Silk_schur_FLP( refl_coef,0, auto_corr,0, psEnc.sCmn.pitchEstimationLPCOrder ); - - /* Convert reflection coefficients to prediction coefficients */ - Silk_k2a_FLP.SKP_Silk_k2a_FLP( A, refl_coef, psEnc.sCmn.pitchEstimationLPCOrder ); - - /* Bandwidth expansion */ - Silk_bwexpander_FLP.SKP_Silk_bwexpander_FLP( A,0, psEnc.sCmn.pitchEstimationLPCOrder, Silk_define_FLP.FIND_PITCH_BANDWITH_EXPANSION ); - - /*****************************************/ - /* LPC analysis filtering */ - /*****************************************/ - Silk_LPC_analysis_filter_FLP.SKP_Silk_LPC_analysis_filter_FLP( res, A, x_buf, x_buf_offset, buf_len, psEnc.sCmn.pitchEstimationLPCOrder ); -// SKP_memset( res, 0, psEnc->sCmn.pitchEstimationLPCOrder * sizeof( SKP_float ) ); - for(int i_djinn=0; i_djinn 0.0f ); - invGains[ i ] = 1.0f / psEncCtrl.Gains[ i ]; - Wght[ i ] = invGains[ i ] * invGains[ i ]; - } - - if( psEncCtrl.sCmn.sigtype == Silk_define.SIG_TYPE_VOICED ) - { - /**********/ - /* VOICED */ - /**********/ - assert( psEnc.sCmn.frame_length - psEnc.sCmn.predictLPCOrder >= psEncCtrl.sCmn.pitchL[ 0 ] + Silk_define.LTP_ORDER / 2 ); - - /* LTP analysis */ - float[] LTPredCodGain_ptr = new float[1]; - LTPredCodGain_ptr[0] = psEncCtrl.LTPredCodGain; - Silk_find_LTP_FLP.SKP_Silk_find_LTP_FLP( psEncCtrl.LTPCoef, WLTP, LTPredCodGain_ptr, res_pitch, - res_pitch,( psEnc.sCmn.frame_length >> 1 ), psEncCtrl.sCmn.pitchL, Wght, - psEnc.sCmn.subfr_length, psEnc.sCmn.frame_length ); - psEncCtrl.LTPredCodGain = LTPredCodGain_ptr[0]; - - - /* Quantize LTP gain parameters */ - int[] PERIndex_ptr = new int[1]; - PERIndex_ptr[0] = psEncCtrl.sCmn.PERIndex; - Silk_quant_LTP_gains_FLP.SKP_Silk_quant_LTP_gains_FLP( psEncCtrl.LTPCoef, psEncCtrl.sCmn.LTPIndex, PERIndex_ptr, - WLTP, psEnc.mu_LTP, psEnc.sCmn.LTPQuantLowComplexity ); - psEncCtrl.sCmn.PERIndex = PERIndex_ptr[0]; - - /* Control LTP scaling */ - Silk_LTP_scale_ctrl_FLP.SKP_Silk_LTP_scale_ctrl_FLP( psEnc, psEncCtrl ); - - /* Create LTP residual */ - Silk_LTP_analysis_filter_FLP.SKP_Silk_LTP_analysis_filter_FLP( LPC_in_pre, psEnc.x_buf, psEnc.sCmn.frame_length - psEnc.sCmn.predictLPCOrder, - psEncCtrl.LTPCoef, psEncCtrl.sCmn.pitchL, invGains, psEnc.sCmn.subfr_length, psEnc.sCmn.predictLPCOrder ); - - } else { - /************/ - /* UNVOICED */ - /************/ - /* Create signal with prepended subframes, scaled by inverse gains */ - x_ptr = psEnc.x_buf; - x_ptr_offset = psEnc.sCmn.frame_length - psEnc.sCmn.predictLPCOrder; - - x_pre_ptr = LPC_in_pre; - x_pre_ptr_offset = 0; - for( i = 0; i < Silk_define.NB_SUBFR; i++ ) { - Silk_scale_copy_vector_FLP.SKP_Silk_scale_copy_vector_FLP( x_pre_ptr, x_pre_ptr_offset, x_ptr, x_ptr_offset, invGains[ i ], - psEnc.sCmn.subfr_length + psEnc.sCmn.predictLPCOrder ); - x_pre_ptr_offset += psEnc.sCmn.subfr_length + psEnc.sCmn.predictLPCOrder; - x_ptr_offset += psEnc.sCmn.subfr_length; - } - - Arrays.fill(psEncCtrl.LTPCoef, 0, Silk_define.NB_SUBFR * Silk_define.LTP_ORDER, 0.0f); - psEncCtrl.LTPredCodGain = 0.0f; - } - - /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */ - int[] NLSFInterpCoef_Q2_ptr = new int[1]; - NLSFInterpCoef_Q2_ptr[0] = psEncCtrl.sCmn.NLSFInterpCoef_Q2; - Silk_find_LPC_FLP.SKP_Silk_find_LPC_FLP( NLSF, NLSFInterpCoef_Q2_ptr, psEnc.sPred.prev_NLSFq, - psEnc.sCmn.useInterpolatedNLSFs * ( 1 - psEnc.sCmn.first_frame_after_reset ), psEnc.sCmn.predictLPCOrder, - LPC_in_pre, psEnc.sCmn.subfr_length + psEnc.sCmn.predictLPCOrder ); - psEncCtrl.sCmn.NLSFInterpCoef_Q2 = NLSFInterpCoef_Q2_ptr[0]; - - - /* Quantize LSFs */ -/*TEST************************************************************************/ -// /** -// * Test for NLSF -// */ -// float[] nlsf = new float[ Silk_define.MAX_LPC_ORDER ]; -// String nlsf_filename = "D:/gsoc/nlsf/nlsf"; -// nlsf_filename += frame_cnt; -// DataInputStream nlsf_datain = null; -// try -// { -// nlsf_datain = new DataInputStream( -// new FileInputStream( -// new File(nlsf_filename))); -// byte[] buffer = new byte[4]; -// for(int ii = 0; ii < NLSF.length; ii++ ) -// { -// try -// { -// -// int res = nlsf_datain.read(buffer); -// if(res != 4) -// { -// throw new IOException("Unexpected End of Stream"); -// } -// nlsf[ii] = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).getFloat(); -// NLSF[ii] = nlsf[ii]; -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// catch (FileNotFoundException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// finally -// { -// if(nlsf_datain != null) -// { -// try -// { -// nlsf_datain.close(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// } -// frame_cnt++; -/*TEST END********************************************************************/ - Silk_process_NLSFs_FLP.SKP_Silk_process_NLSFs_FLP( psEnc, psEncCtrl, NLSF ); - - /* Calculate residual energy using quantized LPC coefficients */ - Silk_residual_energy_FLP.SKP_Silk_residual_energy_FLP( psEncCtrl.ResNrg, LPC_in_pre, psEncCtrl.PredCoef, psEncCtrl.Gains, - psEnc.sCmn.subfr_length, psEnc.sCmn.predictLPCOrder ); - - /* Copy to prediction struct for use in next frame for fluctuation reduction */ - System.arraycopy(NLSF, 0, psEnc.sPred.prev_NLSFq, 0, psEnc.sCmn.predictLPCOrder); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_gain_quant.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_gain_quant.java deleted file mode 100644 index 04682a9a4..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_gain_quant.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_gain_quant -{ - - static final int OFFSET = ( ( Silk_define.MIN_QGAIN_DB * 128 ) / 6 + 16 * 128 ); - static final int SCALE_Q16 = ( ( 65536 * ( Silk_define.N_LEVELS_QGAIN - 1 ) ) / ( ( ( Silk_define.MAX_QGAIN_DB - Silk_define.MIN_QGAIN_DB ) * 128 ) / 6 ) ); - static final int INV_SCALE_Q16 = ( ( 65536 * ( ( ( Silk_define.MAX_QGAIN_DB - Silk_define.MIN_QGAIN_DB ) * 128 ) / 6 ) ) / ( Silk_define.N_LEVELS_QGAIN - 1 ) ); - - /** - * Gain scalar quantization with hysteresis, uniform on log scale. - * @param ind gain indices - * @param gain_Q16 gains (quantized out) - * @param prev_ind last index in previous frame - * @param conditional first gain is delta coded if 1 - */ - static void SKP_Silk_gains_quant( - int ind[], /* O gain indices */ - int gain_Q16[], /* I/O gains (quantized out) */ - int []prev_ind, /* I/O last index in previous frame */ - final int conditional /* I first gain is delta coded if 1 */ - ) - { - int k; - - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - /* Add half of previous quantization error, convert to log scale, scale, floor() */ - ind[ k ] = Silk_macros.SKP_SMULWB( SCALE_Q16, Silk_lin2log.SKP_Silk_lin2log( gain_Q16[ k ] ) - OFFSET ); - - /* Round towards previous quantized gain (hysteresis) */ - if( ind[ k ] < prev_ind[0] ) { - ind[ k ]++; - } - - /* Compute delta indices and limit */ - if( k == 0 && conditional == 0 ) { - /* Full index */ - ind[ k ] = Silk_SigProc_FIX.SKP_LIMIT_int( ind[ k ], 0, Silk_define.N_LEVELS_QGAIN - 1 ); - ind[ k ] = Math.max( ind[ k ], prev_ind[0] + Silk_define.MIN_DELTA_GAIN_QUANT ); - prev_ind[0] = ind[ k ]; - } else { - /* Delta index */ - ind[ k ] = Silk_SigProc_FIX.SKP_LIMIT_int( ind[ k ] - prev_ind[0], Silk_define.MIN_DELTA_GAIN_QUANT, Silk_define.MAX_DELTA_GAIN_QUANT ); - /* Accumulate deltas */ - prev_ind[0] += ind[ k ]; - /* Shift to make non-negative */ - ind[ k ] -= Silk_define.MIN_DELTA_GAIN_QUANT; - } - - /* Convert to linear scale and scale */ - gain_Q16[ k ] = Silk_log2lin.SKP_Silk_log2lin( Math.min( Silk_macros.SKP_SMULWB( INV_SCALE_Q16, prev_ind[0] ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */ - } - } - - /** - * Gains scalar dequantization, uniform on log scale. - * @param gain_Q16 quantized gains. - * @param ind gain indices. - * @param prev_ind last index in previous frame. - * @param conditional first gain is delta coded if 1. - */ - static void SKP_Silk_gains_dequant( - int gain_Q16[ ], /* O quantized gains */ - int ind[ ], /* I gain indices */ - int []prev_ind, /* I/O last index in previous frame */ - final int conditional /* I first gain is delta coded if 1 */ - ) - { - int k; - - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - if( k == 0 && conditional == 0 ) { - prev_ind[0] = ind[ k ]; - } else { - /* Delta index */ - prev_ind[0] += ind[ k ] + Silk_define.MIN_DELTA_GAIN_QUANT; - } - - /* Convert to linear scale and scale */ - gain_Q16[ k ] = Silk_log2lin.SKP_Silk_log2lin( Math.min( Silk_macros.SKP_SMULWB( INV_SCALE_Q16, prev_ind[0] ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */ - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_init_encoder_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_init_encoder_FLP.java deleted file mode 100644 index 5710bf319..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_init_encoder_FLP.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Initialize Silk Encoder state. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_init_encoder_FLP -{ - /** - * Initialize Silk Encoder state. - * @param psEnc - * @return - */ - static int SKP_Silk_init_encoder_FLP( - SKP_Silk_encoder_state_FLP psEnc /* I/O Encoder state FLP */ - ) - { - int ret = 0; - - /* Clear the entire encoder state */ -//TODO: psEnc = new SKP_Silk_encoder_state_FLP(); -// SKP_memset( psEnc, 0, sizeof( SKP_Silk_encoder_state_FLP ) ); - - /* Initialize to 24 kHz API sampling, 24 kHz max internal sampling, 20 ms packets, 25 kbps, 0% packet loss, and init non-zero values */ - ret = Silk_control_codec_FLP.SKP_Silk_control_encoder_FLP( psEnc, 24000, 24, 20, 25, 0, 0, 0, 10, 0 ); - - if(Silk_define.HIGH_PASS_INPUT!=0) - { - psEnc.variable_HP_smth1 = Silk_main_FLP.SKP_Silk_log2( 70.0 ); - psEnc.variable_HP_smth2 = Silk_main_FLP.SKP_Silk_log2( 70.0 ); - } - - /* Used to deactivate e.g. LSF interpolation and fluctuation reduction */ - psEnc.sCmn.first_frame_after_reset = 1; - psEnc.sCmn.fs_kHz_changed = 0; - psEnc.sCmn.LBRR_enabled = 0; - - /* Initialize Silk VAD */ - ret += Silk_VAD.SKP_Silk_VAD_Init( psEnc.sCmn.sVAD ); - - /* Initialize NSQ */ - psEnc.sNSQ.prev_inv_gain_Q16 = 65536; - psEnc.sNSQ_LBRR.prev_inv_gain_Q16 = 65536; - - return( ret ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_inner_product_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_inner_product_FLP.java deleted file mode 100644 index 2c6b553df..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_inner_product_FLP.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * inner product of two SKP_float arrays, with result as double. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_inner_product_FLP -{ - /** - * inner product of two SKP_float arrays, with result as double. - * @param data1 vector1. - * @param data1_offset offset of valid data. - * @param data2 vector2. - * @param data2_offset offset of valid data. - * @param dataSize length of vectors. - * @return result. - */ - static double SKP_Silk_inner_product_FLP( /* O result */ - float[] data1, /* I vector 1 */ - int data1_offset, - float[] data2, /* I vector 2 */ - int data2_offset, - int dataSize /* I length of vectors */ - ) - { - int i, dataSize4; - double result; - - /* 4x unrolled loop */ - result = 0.0f; - dataSize4 = dataSize & 0xFFFC; - for( i = 0; i < dataSize4; i += 4 ) - { - result += data1[ data1_offset + i + 0 ] * data2[ data2_offset + i + 0 ] + - data1[ data1_offset + i + 1 ] * data2[ data2_offset + i + 1 ] + - data1[ data1_offset + i + 2 ] * data2[ data2_offset + i + 2 ] + - data1[ data1_offset + i + 3 ] * data2[ data2_offset + i + 3 ]; - } - - /* add any remaining products */ - for( ; i < dataSize; i++ ) - { - result += data1[ data1_offset+i ] * data2[ data2_offset+i ]; - } - - return result; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_interpolate.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_interpolate.java deleted file mode 100644 index f4d3b3672..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_interpolate.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Interpolate two vectors. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_interpolate -{ - /** - * Interpolate two vectors. - * - * @param xi interpolated vector. - * @param x0 first vector. - * @param x1 second vector. - * @param ifact_Q2 interp. factor, weight on 2nd vector. - * @param d number of parameters. - */ - static void SKP_Silk_interpolate( - int[] xi, /* O interpolated vector */ - int[] x0, /* I first vector */ - int[] x1, /* I second vector */ - final int ifact_Q2, /* I interp. factor, weight on 2nd vector */ - final int d /* I number of parameters */ - ) - { - int i; - - assert( ifact_Q2 >= 0 ); - assert( ifact_Q2 <= ( 1 << 2 ) ); - - for( i = 0; i < d; i++ ) - { - xi[ i ] = ( x0[ i ] + ( ( x1[ i ] - x0[ i ] ) * ifact_Q2 >> 2 ) ); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_k2a_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_k2a_FLP.java deleted file mode 100644 index 4d3bc631b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_k2a_FLP.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * step up function, converts reflection coefficients to - * prediction coefficients. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_k2a_FLP -{ - /** - * step up function, converts reflection coefficients to prediction coefficients. - * - * @param A prediction coefficients [order]. - * @param rc reflection coefficients [order]. - * @param order prediction order. - */ - static void SKP_Silk_k2a_FLP( - float[] A, /* O: prediction coefficients [order] */ - float[] rc, /* I: reflection coefficients [order] */ - int order /* I: prediction order */ - ) - { - int k, n; - float[] Atmp = new float[Silk_SigProc_FIX.SKP_Silk_MAX_ORDER_LPC]; - - for( k = 0; k < order; k++ ) - { - for( n = 0; n < k; n++ ) - { - Atmp[ n ] = A[ n ]; - } - for( n = 0; n < k; n++ ) - { - A[ n ] += Atmp[ k - n - 1 ] * rc[ k ]; - } - A[ k ] = -rc[ k ]; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_levinsondurbin_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_levinsondurbin_FLP.java deleted file mode 100644 index 97875292e..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_levinsondurbin_FLP.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_levinsondurbin_FLP -{ - /** - * Solve the normal equations using the Levinson-Durbin recursion. - * - * @param A prediction coefficients [order]. - * @param A_offset offset of valid data. - * @param corr input auto-correlations [order + 1]. - * @param order prediction order. - * @return prediction error energy. - */ - static float SKP_Silk_levinsondurbin_FLP( /* O prediction error energy */ - float A[], /* O prediction coefficients [order] */ - int A_offset, - float corr[], /* I input auto-correlations [order + 1] */ - final int order /* I prediction order */ - ) - { - int i, mHalf, m; - float min_nrg, nrg, t, km, Atmp1, Atmp2; - - min_nrg = 1e-12f * corr[ 0 ] + 1e-9f; - nrg = corr[ 0 ]; - nrg = Math.max(min_nrg, nrg); - A[ A_offset ] = corr[ 1 ] / nrg; - nrg -= A[ A_offset ] * corr[ 1 ]; - nrg = Math.max(min_nrg, nrg); - - for( m = 1; m < order; m++ ) - { - t = corr[ m + 1 ]; - for( i = 0; i < m; i++ ) - { - t -= A[ A_offset+i ] * corr[ m - i ]; - } - - /* reflection coefficient */ - km = t / nrg; - - /* residual energy */ - nrg -= km * t; - nrg = Math.max(min_nrg, nrg); - - mHalf = m >> 1; - for( i = 0; i < mHalf; i++ ) - { - Atmp1 = A[ A_offset+i ]; - Atmp2 = A[ A_offset + m - i - 1 ]; - A[ A_offset + m - i - 1 ] -= km * Atmp1; - A[ A_offset+i ] -= km * Atmp2; - } - if( (m & 1) != 0) - { - A[ A_offset+mHalf ] -= km * A[ A_offset+mHalf ]; - } - A[ A_offset+m ] = km; - } - - /* return the residual energy */ - return nrg; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_lin2log.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_lin2log.java deleted file mode 100644 index f909803ba..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_lin2log.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Convert input to a log scale - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_lin2log -{ - /** - * Approximation of 128 * log2() (very close inverse of approx 2^() below) - * Convert input to a log scale. - * - * @param inLin Input in linear scale - * @return - */ - static int SKP_Silk_lin2log( final int inLin ) /* I: Input in linear scale */ - { - int lz, frac_Q7; - - int[] lz_ptr = new int[1]; - int[] frac_Q7_ptr = new int[1]; - - Silk_Inlines.SKP_Silk_CLZ_FRAC( inLin, lz_ptr, frac_Q7_ptr ); - lz = lz_ptr[0]; - frac_Q7 = frac_Q7_ptr[0]; - - /* Piece-wise parabolic approximation */ - return( Silk_SigProc_FIX.SKP_LSHIFT( 31 - lz, 7 ) + Silk_macros.SKP_SMLAWB( frac_Q7, Silk_SigProc_FIX.SKP_MUL( frac_Q7, 128 - frac_Q7 ), 179 ) ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_log2lin.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_log2lin.java deleted file mode 100644 index 7e76fa01d..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_log2lin.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Convert input to a linear scale. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_log2lin -{ - /** - * Approximation of 2^() (very close inverse of Silk_lin2log.SKP_Silk_lin2log()) - * Convert input to a linear scale. - * - * @param inLog_Q7 Input on log scale - * @return - */ - static int SKP_Silk_log2lin( final int inLog_Q7 ) /* I: Input on log scale */ - { - int out, frac_Q7; - - if( inLog_Q7 < 0 ) { - return 0; - } - - out = ( 1 << ( inLog_Q7 >> 7 ) ); - - frac_Q7 = inLog_Q7 & 0x7F; - if( inLog_Q7 < 2048 ) { - /* Piece-wise parabolic approximation */ - out = Silk_SigProc_FIX.SKP_ADD_RSHIFT( out, Silk_SigProc_FIX.SKP_MUL( out, Silk_macros.SKP_SMLAWB( frac_Q7, Silk_SigProc_FIX.SKP_MUL( frac_Q7, 128 - frac_Q7 ), -174 ) ), 7 ); - } else { - /* Piece-wise parabolic approximation */ - out = Silk_SigProc_FIX.SKP_MLA( out, Silk_SigProc_FIX.SKP_RSHIFT( out, 7 ), Silk_macros.SKP_SMLAWB( frac_Q7, Silk_SigProc_FIX.SKP_MUL( frac_Q7, 128 - frac_Q7 ), -174 ) ); - } - return out; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_lowpass_int.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_lowpass_int.java deleted file mode 100644 index a1f8c776b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_lowpass_int.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * First order low-pass filter, with input as SKP_int32, running at - * 48 kHz - * - * @author Dingxin Xu - */ -public class Silk_lowpass_int -{ - /** - * First order low-pass filter, with input as SKP_int32, running at 48 kHz - * @param in Q25 48 kHz signal; length = len - * @param in_offset offset of valid data. - * @param S Q25 state; length = 1 - * @param S_offset offset of valid data. - * @param out Q25 48 kHz signal; length = len - * @param out_offset offset of valid data. - * @param len Number of samples - */ - static void SKP_Silk_lowpass_int( - final int []in, /* I: Q25 48 kHz signal; length = len */ - int in_offset, - int []S, /* I/O: Q25 state; length = 1 */ - int S_offset, - int []out, /* O: Q25 48 kHz signal; length = len */ - int out_offset, - final int len /* I: Number of samples */ - ) - { - int k; - int in_tmp, out_tmp, state; - - state = S[ S_offset + 0 ]; - for( k = len; k > 0; k-- ) { - in_tmp = in[in_offset++]; - in_tmp -= ( in_tmp >> 2 ); /* multiply by 0.75 */ - out_tmp = state + in_tmp; /* zero at nyquist */ - state = in_tmp - ( out_tmp >> 1 ); /* pole */ - out[out_offset++] = out_tmp; - } - S[ S_offset + 0 ] = state; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_lowpass_short.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_lowpass_short.java deleted file mode 100644 index 8b0022564..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_lowpass_short.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * First order low-pass filter, with input as SKP_int16, running at - * 48 kHz - * - * @author Dingxin Xu - */ -public class Silk_lowpass_short -{ - /** - * First order low-pass filter, with input as SKP_int16, running at 48 kHz. - * @param in Q15 48 kHz signal; [len] - * @param in_offset offset of valid data. - * @param S Q25 state; length = 1 - * @param S_offset offset of valid data. - * @param out Q25 48 kHz signal; [len] - * @param out_offset offset of valid data. - * @param len Signal length - */ - static void SKP_Silk_lowpass_short( - final short []in, /* I: Q15 48 kHz signal; [len] */ - int in_offset, - int []S, /* I/O: Q25 state; length = 1 */ - int S_offset, - int []out, /* O: Q25 48 kHz signal; [len] */ - int out_offset, - final int len /* O: Signal length */ - ) - { - int k; - int in_tmp, out_tmp, state; - - state = S[ S_offset + 0 ]; - for( k = 0; k < len; k++ ) { - in_tmp = ( 768 * in[in_offset + k] ); /* multiply by 0.75, going from Q15 to Q25 */ - out_tmp = state + in_tmp; /* zero at nyquist */ - state = in_tmp - ( out_tmp >> 1 ); /* pole */ - out[ out_offset + k ] = out_tmp; - } - S[ S_offset + 0 ] = state; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_macros.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_macros.java deleted file mode 100644 index 0e990aeed..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_macros.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Translated from what is an inline header file for general platform. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_macros -{ - // (a32 * (SKP_int32)((SKP_int16)(b32))) >> 16 output have to be 32bit int - static int SKP_SMULWB(int a32, int b32) - { - return ((((a32) >> 16) * ((short)(b32))) + ((((a32) & 0x0000FFFF) * ((short)(b32))) >> 16)); - } - - // a32 + (b32 * (SKP_int32)((SKP_int16)(c32))) >> 16 output have to be 32bit int - static int SKP_SMLAWB(int a32, int b32, int c32) - { - return ((a32) + ((((b32) >> 16) * ((short)(c32))) + ((((b32) & 0x0000FFFF) * ((short)(c32))) >> 16))); - } - - // (a32 * (b32 >> 16)) >> 16 - static int SKP_SMULWT(int a32, int b32) - { - return (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16)); - } - - // a32 + (b32 * (c32 >> 16)) >> 16 - static int SKP_SMLAWT(int a32, int b32, int c32) - { - return ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16)); - } - - // (SKP_int32)((SKP_int16)(a3))) * (SKP_int32)((SKP_int16)(b32)) output have to be 32bit int - static int SKP_SMULBB(int a32, int b32) - { - return (((short)(a32)) * ((short)(b32))); - } - - // a32 + (SKP_int32)((SKP_int16)(b32)) * (SKP_int32)((SKP_int16)(c32)) output have to be 32bit int - static int SKP_SMLABB(int a32, int b32, int c32) - { - return ((a32) + (((short)(b32))) * ((short)(c32))); - } - - // (SKP_int32)((SKP_int16)(a32)) * (b32 >> 16) - static int SKP_SMULBT(int a32, int b32) - { - return (((short)(a32)) * ((b32) >> 16)); - } - - // a32 + (SKP_int32)((SKP_int16)(b32)) * (c32 >> 16) - static int SKP_SMLABT(int a32, int b32, int c32) - { - return ((a32) + (((short)(b32))) * ((c32) >> 16)); - } - - // a64 + (b32 * c32) - static long SKP_SMLAL(long a64, int b32, int c32) - { - return a64 + (long)b32 * (long)c32; - } - - // (a32 * b32) >> 16 - static int SKP_SMULWW(int a32, int b32) - { - return SKP_SMULWB(a32, b32) + a32 * Silk_SigProc_FIX.SKP_RSHIFT_ROUND(b32, 16); - } - - // a32 + ((b32 * c32) >> 16) - static int SKP_SMLAWW(int a32, int b32, int c32) - { - return SKP_SMLAWB(a32, b32, c32) + b32 * Silk_SigProc_FIX.SKP_RSHIFT_ROUND(c32, 16); - } - - /* add/subtract with output saturated */ - static int SKP_ADD_SAT32(int a, int b) - { - if( ((a + b) & 0x80000000) == 0 ) - return ((a & b) & 0x80000000) != 0 ? Integer.MIN_VALUE : a+b; - else - return ((a | b) & 0x80000000) == 0 ? Integer.MAX_VALUE : a+b; - } - - static int SKP_SUB_SAT32(int a, int b) - { - if( ((a - b) & 0x80000000) == 0 ) - return ( a & (b^0x80000000) & 0x80000000) != 0 ? Integer.MIN_VALUE : a-b; - else - return ( (a^0x80000000) & b & 0x80000000) != 0 ? Integer.MAX_VALUE : a-b; - } - - static int SKP_Silk_CLZ16(short in16) - { - return Integer.numberOfLeadingZeros(in16 & 0x0000FFFF) - 16; - } - - static int SKP_Silk_CLZ32(int in32) - { - return Integer.numberOfLeadingZeros(in32); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_main_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_main_FLP.java deleted file mode 100644 index e6b1c4e07..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_main_FLP.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_main_FLP -{ - /** - * using log2() helps the fixed-point conversion. - * @param x - * @return - */ - static float SKP_Silk_log2( double x ) - { - return ( float )( 3.32192809488736 * Math.log10( x ) ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_noise_shape_analysis_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_noise_shape_analysis_FLP.java deleted file mode 100644 index 09e20c8f8..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_noise_shape_analysis_FLP.java +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_noise_shape_analysis_FLP -{ - /** - * Compute noise shaping coefficients and initial gain values. - * @param psEnc Encoder state FLP - * @param psEncCtrl Encoder control FLP - * @param pitch_res LPC residual from pitch analysis - * @param pitch_res_offset offset of valid data. - * @param x Input signal [frame_length + la_shape] - * @param x_offset offset of valid data. - */ - static void SKP_Silk_noise_shape_analysis_FLP - ( - SKP_Silk_encoder_state_FLP psEnc, /* I/O Encoder state FLP */ - SKP_Silk_encoder_control_FLP psEncCtrl, /* I/O Encoder control FLP */ - float[] pitch_res, /* I LPC residual from pitch analysis */ - int pitch_res_offset, - float[] x, /* I Input signal [frame_length + la_shape] */ - int x_offset - ) - { - SKP_Silk_shape_state_FLP psShapeSt = psEnc.sShape; - int k, nSamples; - float SNR_adj_dB, HarmBoost, HarmShapeGain, Tilt; - float nrg, pre_nrg=0, log_energy, log_energy_prev, energy_variation; - float delta, BWExp1, BWExp2, gain_mult, gain_add, strength, b; - float[] x_windowed = new float[ Silk_define.SHAPE_LPC_WIN_MAX ]; - float[] auto_corr = new float[ Silk_define.SHAPE_LPC_ORDER_MAX + 1 ]; - float[] x_ptr, pitch_res_ptr; - int x_ptr_offset, pitch_res_ptr_offset=0; - - /* Point to start of first LPC analysis block */ - x_ptr = x; - x_ptr_offset = x_offset + psEnc.sCmn.la_shape - Silk_define.SHAPE_LPC_WIN_MS * psEnc.sCmn.fs_kHz + psEnc.sCmn.subfr_length; - - /****************/ - /* CONTROL SNR */ - /****************/ - /* Reduce SNR_dB values if recent bitstream has exceeded TargetRate */ - psEncCtrl.current_SNR_dB = psEnc.SNR_dB - 0.05f * psEnc.BufferedInChannel_ms; - - /* Reduce SNR_dB if inband FEC used */ - if( psEnc.speech_activity > Silk_define_FLP.LBRR_SPEECH_ACTIVITY_THRES ) - { - psEncCtrl.current_SNR_dB -= psEnc.inBandFEC_SNR_comp; - } - - /****************/ - /* GAIN CONTROL */ - /****************/ - /* Input quality is the average of the quality in the lowest two VAD bands */ - psEncCtrl.input_quality = 0.5f * ( psEncCtrl.input_quality_bands[ 0 ] + psEncCtrl.input_quality_bands[ 1 ] ); - - /* Coding quality level, between 0.0 and 1.0 */ - psEncCtrl.coding_quality = Silk_SigProc_FLP.SKP_sigmoid( 0.25f * ( psEncCtrl.current_SNR_dB - 18.0f ) ); - - /* Reduce coding SNR during low speech activity */ - b = 1.0f - psEnc.speech_activity; - SNR_adj_dB = psEncCtrl.current_SNR_dB - - Silk_perceptual_parameters_FLP.BG_SNR_DECR_dB * psEncCtrl.coding_quality * ( 0.5f + 0.5f * psEncCtrl.input_quality ) * b * b; - - if( psEncCtrl.sCmn.sigtype == Silk_define.SIG_TYPE_VOICED ) - { - /* Reduce gains for periodic signals */ - SNR_adj_dB += Silk_perceptual_parameters_FLP.HARM_SNR_INCR_dB * psEnc.LTPCorr; - } - else - { - /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ - SNR_adj_dB += ( -0.4f * psEncCtrl.current_SNR_dB + 6.0f ) * ( 1.0f - psEncCtrl.input_quality ); - } - - /*************************/ - /* SPARSENESS PROCESSING */ - /*************************/ - /* Set quantizer offset */ - if( psEncCtrl.sCmn.sigtype == Silk_define.SIG_TYPE_VOICED ) - { - /* Initally set to 0; may be overruled in process_gains(..) */ - psEncCtrl.sCmn.QuantOffsetType = 0; - psEncCtrl.sparseness = 0.0f; - } - else - { - /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ - nSamples = 2 * psEnc.sCmn.fs_kHz; - energy_variation = 0.0f; - log_energy_prev = 0.0f; - pitch_res_ptr = pitch_res; - pitch_res_ptr_offset = pitch_res_offset; - for( k = 0; k < Silk_define.FRAME_LENGTH_MS / 2; k++ ) - { - nrg = nSamples + ( float )Silk_energy_FLP.SKP_Silk_energy_FLP( pitch_res_ptr,pitch_res_ptr_offset, nSamples ); - log_energy = Silk_main_FLP.SKP_Silk_log2( nrg ); - if( k > 0 ) - { - energy_variation += Math.abs( log_energy - log_energy_prev ); - } - log_energy_prev = log_energy; - pitch_res_ptr_offset += nSamples; - } - psEncCtrl.sparseness = Silk_SigProc_FLP.SKP_sigmoid( 0.4f * ( energy_variation - 5.0f ) ); - - /* Set quantization offset depending on sparseness measure */ - if( psEncCtrl.sparseness > Silk_perceptual_parameters_FLP.SPARSENESS_THRESHOLD_QNT_OFFSET ) - { - psEncCtrl.sCmn.QuantOffsetType = 0; - } - else - { - psEncCtrl.sCmn.QuantOffsetType = 1; - } - - /* Increase coding SNR for sparse signals */ - SNR_adj_dB += Silk_perceptual_parameters_FLP.SPARSE_SNR_INCR_dB * ( psEncCtrl.sparseness - 0.5f ); - } - - /*******************************/ - /* Control bandwidth expansion */ - /*******************************/ - delta = Silk_perceptual_parameters_FLP.LOW_RATE_BANDWIDTH_EXPANSION_DELTA * ( 1.0f - 0.75f * psEncCtrl.coding_quality ); - BWExp1 = Silk_perceptual_parameters_FLP.BANDWIDTH_EXPANSION - delta; - BWExp2 = Silk_perceptual_parameters_FLP.BANDWIDTH_EXPANSION + delta; - if( psEnc.sCmn.fs_kHz == 24 ) - { - /* Less bandwidth expansion for super wideband */ - BWExp1 = 1.0f - ( 1.0f - BWExp1 ) * Silk_perceptual_parameters_FLP.SWB_BANDWIDTH_EXPANSION_REDUCTION; - BWExp2 = 1.0f - ( 1.0f - BWExp2 ) * Silk_perceptual_parameters_FLP.SWB_BANDWIDTH_EXPANSION_REDUCTION; - } - /* BWExp1 will be applied after BWExp2, so make it relative */ - BWExp1 /= BWExp2; - - /********************************************/ - /* Compute noise shaping AR coefs and gains */ - /********************************************/ - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) - { - /* Apply window */ - Silk_apply_sine_window_FLP.SKP_Silk_apply_sine_window_FLP( x_windowed,0, x_ptr,x_ptr_offset, 0, Silk_define.SHAPE_LPC_WIN_MS * psEnc.sCmn.fs_kHz ); - - /* Update pointer: next LPC analysis block */ - x_ptr_offset += psEnc.sCmn.subfr_length; - - /* Calculate auto correlation */ - Silk_autocorrelation_FLP.SKP_Silk_autocorrelation_FLP(auto_corr,0, x_windowed,0, Silk_define.SHAPE_LPC_WIN_MS * psEnc.sCmn.fs_kHz, psEnc.sCmn.shapingLPCOrder + 1); - - /* Add white noise, as a fraction of energy */ - auto_corr[ 0 ] += auto_corr[ 0 ] * Silk_perceptual_parameters_FLP.SHAPE_WHITE_NOISE_FRACTION; - - /* Convert correlations to prediction coefficients, and compute residual energy */ - nrg = Silk_levinsondurbin_FLP.SKP_Silk_levinsondurbin_FLP( psEncCtrl.AR2,k * Silk_define.SHAPE_LPC_ORDER_MAX, auto_corr, psEnc.sCmn.shapingLPCOrder ); - - /* Bandwidth expansion for synthesis filter shaping */ - Silk_bwexpander_FLP.SKP_Silk_bwexpander_FLP( psEncCtrl.AR2,k * Silk_define.SHAPE_LPC_ORDER_MAX, psEnc.sCmn.shapingLPCOrder, BWExp2 ); - - /* Make sure to fit in Q13 SKP_int16 */ - LPC_fit_int16( psEncCtrl.AR2,k * Silk_define.SHAPE_LPC_ORDER_MAX, 1.0f, psEnc.sCmn.shapingLPCOrder, 3.999f ); - - /* Compute noise shaping filter coefficients */ -// SKP_memcpy( -// &psEncCtrl->AR1[ k * SHAPE_LPC_ORDER_MAX ], -// &psEncCtrl->AR2[ k * SHAPE_LPC_ORDER_MAX ], -// psEnc->sCmn.shapingLPCOrder * sizeof( SKP_float ) ); - for(int i_djinn=0; i_djinnGainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ); - } - - /*****************/ - /* Gain tweaking */ - /*****************/ - /* Increase gains during low speech activity and put lower limit on gains */ - gain_mult = ( float )Math.pow( 2.0f, -0.16f * SNR_adj_dB ); - gain_add = ( float )Math.pow( 2.0f, 0.16f * Silk_perceptual_parameters_FLP.NOISE_FLOOR_dB ) + - ( float )Math.pow( 2.0f, 0.16f * Silk_perceptual_parameters_FLP.RELATIVE_MIN_GAIN_dB ) * psEnc.avgGain; - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) - { - psEncCtrl.Gains[ k ] *= gain_mult; - psEncCtrl.Gains[ k ] += gain_add; - psEnc.avgGain += psEnc.speech_activity * Silk_perceptual_parameters_FLP.GAIN_SMOOTHING_COEF * ( psEncCtrl.Gains[ k ] - psEnc.avgGain ); - } - - /************************************************/ - /* Decrease level during fricatives (de-essing) */ - /************************************************/ - gain_mult = 1.0f + Silk_perceptual_parameters_FLP.INPUT_TILT + psEncCtrl.coding_quality * Silk_perceptual_parameters_FLP.HIGH_RATE_INPUT_TILT; - if( psEncCtrl.input_tilt <= 0.0f && psEncCtrl.sCmn.sigtype == Silk_define.SIG_TYPE_UNVOICED ) - { - float essStrength = -psEncCtrl.input_tilt * psEnc.speech_activity * ( 1.0f - psEncCtrl.sparseness ); - if( psEnc.sCmn.fs_kHz == 24 ) - { - gain_mult *= ( float )Math.pow( 2.0f, -0.16f * Silk_perceptual_parameters_FLP.DE_ESSER_COEF_SWB_dB * essStrength ); - } - else if( psEnc.sCmn.fs_kHz == 16 ) - { - gain_mult *= (float)Math.pow( 2.0f, -0.16f * Silk_perceptual_parameters_FLP.DE_ESSER_COEF_WB_dB * essStrength ); - } - else - { - assert( psEnc.sCmn.fs_kHz == 12 || psEnc.sCmn.fs_kHz == 8 ); - } - } - - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) - { - psEncCtrl.GainsPre[ k ] *= gain_mult; - } - - /************************************************/ - /* Control low-frequency shaping and noise tilt */ - /************************************************/ - /* Less low frequency shaping for noisy inputs */ - strength = Silk_perceptual_parameters_FLP.LOW_FREQ_SHAPING * ( 1.0f + Silk_perceptual_parameters_FLP.LOW_QUALITY_LOW_FREQ_SHAPING_DECR * ( psEncCtrl.input_quality_bands[ 0 ] - 1.0f ) ); - if( psEncCtrl.sCmn.sigtype == Silk_define.SIG_TYPE_VOICED ) - { - /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ - /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) - { - b = 0.2f / psEnc.sCmn.fs_kHz + 3.0f / psEncCtrl.sCmn.pitchL[ k ]; - psEncCtrl.LF_MA_shp[ k ] = -1.0f + b; - psEncCtrl.LF_AR_shp[ k ] = 1.0f - b - b * strength; - } - Tilt = - Silk_perceptual_parameters_FLP.HP_NOISE_COEF - - (1 - Silk_perceptual_parameters_FLP.HP_NOISE_COEF) * Silk_perceptual_parameters_FLP.HARM_HP_NOISE_COEF * psEnc.speech_activity; - } - else - { - b = 1.3f / psEnc.sCmn.fs_kHz; - psEncCtrl.LF_MA_shp[ 0 ] = -1.0f + b; - psEncCtrl.LF_AR_shp[ 0 ] = 1.0f - b - b * strength * 0.6f; - for( k = 1; k < Silk_define.NB_SUBFR; k++ ) - { - psEncCtrl.LF_MA_shp[ k ] = psEncCtrl.LF_MA_shp[ k - 1 ]; - psEncCtrl.LF_AR_shp[ k ] = psEncCtrl.LF_AR_shp[ k - 1 ]; - } - Tilt = -Silk_perceptual_parameters_FLP.HP_NOISE_COEF; - } - - /****************************/ - /* HARMONIC SHAPING CONTROL */ - /****************************/ - /* Control boosting of harmonic frequencies */ - HarmBoost = Silk_perceptual_parameters_FLP.LOW_RATE_HARMONIC_BOOST * ( 1.0f - psEncCtrl.coding_quality ) * psEnc.LTPCorr; - - /* More harmonic boost for noisy input signals */ - HarmBoost += Silk_perceptual_parameters_FLP.LOW_INPUT_QUALITY_HARMONIC_BOOST * ( 1.0f - psEncCtrl.input_quality ); - - if( Silk_define.USE_HARM_SHAPING!=0 && psEncCtrl.sCmn.sigtype == Silk_define.SIG_TYPE_VOICED ) - { - /* Harmonic noise shaping */ - HarmShapeGain = Silk_perceptual_parameters_FLP.HARMONIC_SHAPING; - - /* More harmonic noise shaping for high bitrates or noisy input */ - HarmShapeGain += Silk_perceptual_parameters_FLP.HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING * - ( 1.0f - ( 1.0f - psEncCtrl.coding_quality ) * psEncCtrl.input_quality ); - - /* Less harmonic noise shaping for less periodic signals */ - HarmShapeGain *= ( float )Math.sqrt( psEnc.LTPCorr ); - } - else - { - HarmShapeGain = 0.0f; - } - - /*************************/ - /* Smooth over subframes */ - /*************************/ - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) - { - psShapeSt.HarmBoost_smth += Silk_perceptual_parameters_FLP.SUBFR_SMTH_COEF * ( HarmBoost - psShapeSt.HarmBoost_smth ); - psEncCtrl.HarmBoost[ k ] = psShapeSt.HarmBoost_smth; - psShapeSt.HarmShapeGain_smth += Silk_perceptual_parameters_FLP.SUBFR_SMTH_COEF * ( HarmShapeGain - psShapeSt.HarmShapeGain_smth ); - psEncCtrl.HarmShapeGain[ k ] = psShapeSt.HarmShapeGain_smth; - psShapeSt.Tilt_smth += Silk_perceptual_parameters_FLP.SUBFR_SMTH_COEF * ( Tilt - psShapeSt.Tilt_smth ); - psEncCtrl.Tilt[ k ] = psShapeSt.Tilt_smth; - } - } - - /** - * - * @param a Unstable/stabilized LPC vector [L]. - * @param a_offset offset of valid data. - * @param bwe Bandwidth expansion factor. - * @param L Number of LPC parameters in the input vector. - * @param maxVal Maximum value allowed. - */ - static void LPC_fit_int16( - float[] a, /* I/O: Unstable/stabilized LPC vector [L] */ - int a_offset, - final float bwe, /* I: Bandwidth expansion factor */ - final int L, /* I: Number of LPC parameters in the input vector */ - float maxVal /* I Maximum value allowed */ - ) - { - float maxabs, absval, sc; - int k, i, idx = 0; - float[] invGain = new float[1]; - - Silk_bwexpander_FLP.SKP_Silk_bwexpander_FLP( a,a_offset, L, bwe ); - - /***************************/ - /* Limit range of the LPCs */ - /***************************/ - /* Limit the maximum absolute value of the prediction coefficients */ - for( k = 0; k < 1000; k++ ) - { - /* Find maximum absolute value and its index */ - maxabs = -1.0f; - for( i = 0; i < L; i++ ) - { - absval = Math.abs( a[ a_offset+i ] ); - if( absval > maxabs ) { - maxabs = absval; - idx = i; - } - } - - if( maxabs >= maxVal ) - { - /* Reduce magnitude of prediction coefficients */ - sc = 0.995f * ( 1.0f - ( 1.0f - maxVal / maxabs ) / ( idx + 1 ) ); - Silk_bwexpander_FLP.SKP_Silk_bwexpander_FLP( a,a_offset, L, sc ); - } - else - { - break; - } - } - /* Reached the last iteration */ - if( k == 1000 ) - { - assert( false ); - } - - /**********************/ - /* Ensure stable LPCs */ - /**********************/ - for( k = 0; k < 1000; k++ ) - { - if( Silk_LPC_inv_pred_gain_FLP.SKP_Silk_LPC_inverse_pred_gain_FLP( invGain, a,a_offset, L ) == 1 ) - { - Silk_bwexpander_FLP.SKP_Silk_bwexpander_FLP( a,a_offset, L, 0.997f ); - } - else - { - break; - } - } - - /* Reached the last iteration */ - if( k == 1000 ) - { - assert( false ); - for( i = 0; i < L; i++ ) - { - a[ i ] = 0.0f; - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_perceptual_parameters_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_perceptual_parameters_FLP.java deleted file mode 100644 index 1327b2b85..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_perceptual_parameters_FLP.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Perceptual parameters. - * - * @author Jing Dai - * @author Dingxin Xu - */ -//TODO: float or double??? -public class Silk_perceptual_parameters_FLP -{ - /* reduction in coding SNR during low speech activity */ - static final float BG_SNR_DECR_dB = 3.0f; - - /* factor for reducing quantization noise during voiced speech */ - static final float HARM_SNR_INCR_dB = 2.0f; - - /* factor for reducing quantization noise for unvoiced sparse signals */ - static final float SPARSE_SNR_INCR_dB = 2.0f; - - /* threshold for sparseness measure above which to use lower quantization offset during unvoiced */ - static final float SPARSENESS_THRESHOLD_QNT_OFFSET = 0.75f; - - - /* noise shaping filter chirp factor */ - static final float BANDWIDTH_EXPANSION = 0.94f; - - /* difference between chirp factors for analysis and synthesis noise shaping filters at low bitrates */ - static final float LOW_RATE_BANDWIDTH_EXPANSION_DELTA = 0.01f; - - /* factor to reduce all bandwdith expansion coefficients for super wideband, relative to wideband */ - static final float SWB_BANDWIDTH_EXPANSION_REDUCTION = 1.0f; - - /* gain reduction for fricatives */ - static final float DE_ESSER_COEF_SWB_dB = 2.0f; - static final float DE_ESSER_COEF_WB_dB = 1.0f; - - - /* extra harmonic boosting (signal shaping) at low bitrates */ - static final float LOW_RATE_HARMONIC_BOOST = 0.1f; - - /* extra harmonic boosting (signal shaping) for noisy input signals */ - static final float LOW_INPUT_QUALITY_HARMONIC_BOOST = 0.1f; - - /* harmonic noise shaping */ - static final float HARMONIC_SHAPING = 0.3f; - - /* extra harmonic noise shaping for high bitrates or noisy input */ - static final float HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING = 0.2f; - - - /* parameter for shaping noise towards higher frequencies */ - static final float HP_NOISE_COEF = 0.3f; - - /* parameter for shaping noise extra towards higher frequencies during voiced speech */ - static final float HARM_HP_NOISE_COEF = 0.45f; - - /* parameter for applying a high-pass tilt to the input signal */ - static final float INPUT_TILT = 0.04f; - - /* parameter for extra high-pass tilt to the input signal at high rates */ - static final float HIGH_RATE_INPUT_TILT = 0.06f; - - /* parameter for reducing noise at the very low frequencies */ - static final float LOW_FREQ_SHAPING = 3.0f; - - /* less reduction of noise at the very low frequencies for signals with low SNR at low frequencies */ - static final float LOW_QUALITY_LOW_FREQ_SHAPING_DECR = 0.5f; - - /* fraction added to first autocorrelation value */ - static final float SHAPE_WHITE_NOISE_FRACTION = 4.7684e-5f; - - /* fraction of first autocorrelation value added to residual energy value; limits prediction gain */ - static final float SHAPE_MIN_ENERGY_RATIO = 1.526e-5f; // 1.526e-5 = 1/65536 - - /* noise floor to put a low limit on the quantization step size */ - static final float NOISE_FLOOR_dB = 4.0f; - - /* noise floor relative to active speech gain level */ - static final float RELATIVE_MIN_GAIN_dB = -50.0f; - - /* subframe smoothing coefficient for determining active speech gain level (lower -> more smoothing) */ - static final float GAIN_SMOOTHING_COEF = 1e-3f; - - /* subframe smoothing coefficient for HarmBoost, HarmShapeGain, Tilt (lower -> more smoothing) */ - static final float SUBFR_SMTH_COEF = 0.4f; - - /* Amount of noise added in prefilter, to simulate quantization noise */ - static final float NOISE_GAIN_VL = 0.12f; - static final float NOISE_GAIN_VH = 0.12f; - static final float NOISE_GAIN_UVL = 0.1f; - static final float NOISE_GAIN_UVH = 0.15f; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_pitch_analysis_core_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_pitch_analysis_core_FLP.java deleted file mode 100644 index dc7c28e74..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_pitch_analysis_core_FLP.java +++ /dev/null @@ -1,712 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Pitch analysis. - * - * @author Jing Dai - * @author Dingxin Xu - */ -//TODO: float or dobule ??? -public class Silk_pitch_analysis_core_FLP -{ - static final int SCRATCH_SIZE = 22; - - static final float eps = 1.192092896e-07f; - - /* using log2() helps the fixed-point conversion */ - static float SKP_P_log2(double x) - { - return (float)(3.32192809488736 * Math.log10(x)); - } - - /** - * CORE PITCH ANALYSIS FUNCTION. - * @param signal signal of length PITCH_EST_FRAME_LENGTH_MS*Fs_kHz - * @param pitch_out 4 pitch lag values - * @param lagIndex lag Index - * @param contourIndex pitch contour Index - * @param LTPCorr normalized correlation; input: value from previous frame - * @param prevLag last lag of previous frame; set to zero is unvoiced - * @param search_thres1 first stage threshold for lag candidates 0 - 1 - * @param search_thres2 final threshold for lag candidates 0 - 1 - * @param Fs_kHz sample frequency (kHz) - * @param complexity Complexity setting, 0-2, where 2 is highest - * @return voicing estimate: 0 voiced, 1 unvoiced - */ - static int SKP_Silk_pitch_analysis_core_FLP( /* O voicing estimate: 0 voiced, 1 unvoiced */ - float[] signal, /* I signal of length PITCH_EST_FRAME_LENGTH_MS*Fs_kHz */ - int[] pitch_out, /* O 4 pitch lag values */ - int[] lagIndex, /* O lag Index */ - int[] contourIndex, /* O pitch contour Index */ - float[] LTPCorr, /* I/O normalized correlation; input: value from previous frame */ - int prevLag, /* I last lag of previous frame; set to zero is unvoiced */ - final float search_thres1, /* I first stage threshold for lag candidates 0 - 1 */ - final float search_thres2, /* I final threshold for lag candidates 0 - 1 */ - final int Fs_kHz, /* I sample frequency (kHz) */ - final int complexity /* I Complexity setting, 0-2, where 2 is highest */ - ) - { - float[] signal_8kHz = new float[ Silk_common_pitch_est_defines.PITCH_EST_FRAME_LENGTH_MS * 8 ]; - float[] signal_4kHz = new float[ Silk_common_pitch_est_defines.PITCH_EST_FRAME_LENGTH_MS * 4 ]; - float[] scratch_mem = new float[ Silk_common_pitch_est_defines.PITCH_EST_MAX_FRAME_LENGTH * 3 ]; - float[] filt_state = new float[ Silk_common_pitch_est_defines.PITCH_EST_MAX_DECIMATE_STATE_LENGTH ]; - int i, k, d, j; - float threshold, contour_bias; - float[][] C = new float[Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR][(Silk_common_pitch_est_defines.PITCH_EST_MAX_LAG >> 1) + 5]; /* use to be +2 but then valgrind reported errors for SWB */ - float[] CC = new float[Silk_common_pitch_est_defines.PITCH_EST_NB_CBKS_STAGE2_EXT]; - float[] target_ptr, basis_ptr; - int target_ptr_offset, basis_ptr_offset; - double cross_corr, normalizer, energy, energy_tmp; - int[] d_srch = new int[Silk_common_pitch_est_defines.PITCH_EST_D_SRCH_LENGTH]; - short[] d_comp = new short[(Silk_common_pitch_est_defines.PITCH_EST_MAX_LAG >> 1) + 5]; - int length_d_srch, length_d_comp; - float Cmax, CCmax, CCmax_b, CCmax_new_b, CCmax_new; - int CBimax, CBimax_new, lag, start_lag, end_lag, lag_new; - int cbk_offset, cbk_size; - float lag_log2, prevLag_log2, delta_lag_log2_sqr; - float[][][] energies_st3 = new float[ Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR ][ Silk_common_pitch_est_defines.PITCH_EST_NB_CBKS_STAGE3_MAX ][ Silk_common_pitch_est_defines.PITCH_EST_NB_STAGE3_LAGS ]; - float[][][] cross_corr_st3 = new float[ Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR ][ Silk_common_pitch_est_defines.PITCH_EST_NB_CBKS_STAGE3_MAX ][ Silk_common_pitch_est_defines.PITCH_EST_NB_STAGE3_LAGS ]; - - int diff, lag_counter; - int frame_length, frame_length_8kHz, frame_length_4kHz; - int sf_length, sf_length_8kHz, sf_length_4kHz; - int min_lag, min_lag_8kHz, min_lag_4kHz; - int max_lag, max_lag_8kHz, max_lag_4kHz; - - int nb_cbks_stage2; - - /* Check for valid sampling frequency */ - assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 || Fs_kHz == 24 ); - - /* Check for valid complexity setting */ - assert( complexity >= Silk_SigProc_FIX.SKP_Silk_PITCH_EST_MIN_COMPLEX ); - assert( complexity <= Silk_SigProc_FIX.SKP_Silk_PITCH_EST_MAX_COMPLEX ); - - assert( search_thres1 >= 0.0f && search_thres1 <= 1.0f ); - assert( search_thres2 >= 0.0f && search_thres2 <= 1.0f ); - - /* Setup frame lengths max / min lag for the sampling frequency */ - frame_length = Silk_common_pitch_est_defines.PITCH_EST_FRAME_LENGTH_MS * Fs_kHz; - frame_length_4kHz = Silk_common_pitch_est_defines.PITCH_EST_FRAME_LENGTH_MS * 4; - frame_length_8kHz = Silk_common_pitch_est_defines.PITCH_EST_FRAME_LENGTH_MS * 8; - sf_length = frame_length >> 3; - sf_length_4kHz = frame_length_4kHz >> 3; - sf_length_8kHz = frame_length_8kHz >> 3; - min_lag = Silk_common_pitch_est_defines.PITCH_EST_MIN_LAG_MS * Fs_kHz; - min_lag_4kHz = Silk_common_pitch_est_defines.PITCH_EST_MIN_LAG_MS * 4; - min_lag_8kHz = Silk_common_pitch_est_defines.PITCH_EST_MIN_LAG_MS * 8; - max_lag = Silk_common_pitch_est_defines.PITCH_EST_MAX_LAG_MS * Fs_kHz; - max_lag_4kHz = Silk_common_pitch_est_defines.PITCH_EST_MAX_LAG_MS * 4; - max_lag_8kHz = Silk_common_pitch_est_defines.PITCH_EST_MAX_LAG_MS * 8; - - for(int i_djinn=0; i_djinn< Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR; i_djinn++) - for(int j_djinn=0; j_djinn< (Silk_common_pitch_est_defines.PITCH_EST_MAX_LAG >> 1) + 5; j_djinn++) - C[i_djinn][j_djinn] = 0; - - /* Resample from input sampled at Fs_kHz to 8 kHz */ - if( Fs_kHz == 12 ) - { - short[] signal_12 = new short[ 12 * Silk_common_pitch_est_defines.PITCH_EST_FRAME_LENGTH_MS ]; - short[] signal_8 = new short[ 8 * Silk_common_pitch_est_defines.PITCH_EST_FRAME_LENGTH_MS ]; - int[] R23 = new int[ 6 ]; - - /* Resample to 12 -> 8 khz */ - for(int i_djinn=0; i_djinn<6; i_djinn++) - R23[i_djinn] = 0; - Silk_SigProc_FLP.SKP_float2short_array( signal_12,0, signal,0, Silk_common_pitch_est_defines.PITCH_EST_FRAME_LENGTH_MS * 12); - Silk_resampler_down2_3.SKP_Silk_resampler_down2_3( R23,0, signal_8,0, signal_12,0, Silk_common_pitch_est_defines.PITCH_EST_FRAME_LENGTH_MS * 12 ); - Silk_SigProc_FLP.SKP_short2float_array( signal_8kHz,0, signal_8,0, frame_length_8kHz ); - } - else if( Fs_kHz == 16 ) - { - if( complexity == Silk_SigProc_FIX.SKP_Silk_PITCH_EST_MAX_COMPLEX ) - { - assert( 4 <= Silk_common_pitch_est_defines.PITCH_EST_MAX_DECIMATE_STATE_LENGTH ); - for(int i_djinn=0; i_djinn<4; i_djinn++) - filt_state[i_djinn] = 0; - - Silk_decimate2_coarse_FLP.SKP_Silk_decimate2_coarse_FLP( signal,0, filt_state,0, signal_8kHz,0, - scratch_mem,0, frame_length_8kHz ); - } - else - { - assert( 2 <= Silk_common_pitch_est_defines.PITCH_EST_MAX_DECIMATE_STATE_LENGTH ); - for(int i_djinn=0; i_djinn<2; i_djinn++) - filt_state[i_djinn] = 0; - - Silk_decimate2_coarsest_FLP.SKP_Silk_decimate2_coarsest_FLP( signal,0, filt_state,0, signal_8kHz,0, - scratch_mem,0, frame_length_8kHz ); - } - } - else if( Fs_kHz == 24 ) - { - short[] signal_24 = new short[ Silk_common_pitch_est_defines.PITCH_EST_MAX_FRAME_LENGTH ]; - short[] signal_8 = new short[ 8 * Silk_common_pitch_est_defines.PITCH_EST_FRAME_LENGTH_MS ]; - int[] filt_state_fix = new int[ 8 ]; - - /* Resample to 24 -> 8 khz */ - Silk_SigProc_FLP.SKP_float2short_array( signal_24,0, signal,0, 24 * Silk_common_pitch_est_defines.PITCH_EST_FRAME_LENGTH_MS ); - for(int i_djinn=0; i_djinn<8; i_djinn++) - filt_state_fix[i_djinn] = 0; - Silk_resampler_down3.SKP_Silk_resampler_down3( filt_state_fix,0, signal_8,0, signal_24,0, 24 * Silk_common_pitch_est_defines.PITCH_EST_FRAME_LENGTH_MS ); - Silk_SigProc_FLP.SKP_short2float_array( signal_8kHz,0, signal_8,0, frame_length_8kHz ); - } - else - { - assert( Fs_kHz == 8 ); - for(int i_djinn=0; i_djinn 0; i-- ) { - signal_4kHz[ i ] += signal_4kHz[ i - 1 ]; - } - - /****************************************************************************** - * FIRST STAGE, operating in 4 khz - ******************************************************************************/ - target_ptr = signal_4kHz; - target_ptr_offset = frame_length_4kHz >> 1; - for( k = 0; k < 2; k++ ) - { - /* Check that we are within range of the array */ - assert( target_ptr_offset >= 0 ); - assert( target_ptr_offset + sf_length_8kHz <= frame_length_4kHz ); - - basis_ptr = target_ptr; - basis_ptr_offset = target_ptr_offset - min_lag_4kHz; - - /* Check that we are within range of the array */ - assert( basis_ptr_offset >= 0 ); - assert( basis_ptr_offset + sf_length_8kHz <= frame_length_4kHz ); - - /* Calculate first vector products before loop */ - cross_corr = Silk_inner_product_FLP.SKP_Silk_inner_product_FLP( target_ptr,target_ptr_offset, basis_ptr,basis_ptr_offset, sf_length_8kHz ); - normalizer = Silk_energy_FLP.SKP_Silk_energy_FLP( basis_ptr,basis_ptr_offset, sf_length_8kHz ) + 1000.0f; - - C[ 0 ][ min_lag_4kHz ] += (float)(cross_corr / Math.sqrt(normalizer)); - - /* From now on normalizer is computed recursively */ - for(d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++) - { - basis_ptr_offset--; - - /* Check that we are within range of the array */ - assert( basis_ptr_offset >= 0 ); - assert( basis_ptr_offset + sf_length_8kHz <= frame_length_4kHz ); - - cross_corr = Silk_inner_product_FLP.SKP_Silk_inner_product_FLP(target_ptr,target_ptr_offset, basis_ptr,basis_ptr_offset, sf_length_8kHz); - - /* Add contribution of new sample and remove contribution from oldest sample */ -// normalizer += -// basis_ptr[ 0 ] * basis_ptr[ 0 ] - -// basis_ptr[ sf_length_8kHz ] * basis_ptr[ sf_length_8kHz ]; - normalizer += - basis_ptr[ basis_ptr_offset + 0 ] * basis_ptr[ basis_ptr_offset + 0 ] - - basis_ptr[ basis_ptr_offset + sf_length_8kHz ] * basis_ptr[ basis_ptr_offset + sf_length_8kHz ]; - C[ 0 ][ d ] += (float)(cross_corr / Math.sqrt( normalizer )); - } - /* Update target pointer */ - target_ptr_offset += sf_length_8kHz; - } - - /* Apply short-lag bias */ - for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) - { - C[ 0 ][ i ] -= C[ 0 ][ i ] * i / 4096.0f; - } - - /* Sort */ - length_d_srch = 5 + complexity; - assert( length_d_srch <= Silk_common_pitch_est_defines.PITCH_EST_D_SRCH_LENGTH ); - Silk_sort_FLP.SKP_Silk_insertion_sort_decreasing_FLP( C[ 0 ],min_lag_4kHz, d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch ); - - /* Escape if correlation is very low already here */ - Cmax = C[ 0 ][ min_lag_4kHz ]; - target_ptr = signal_4kHz; - target_ptr_offset = frame_length_4kHz >> 1; - energy = 1000.0f; - for( i = 0; i < frame_length_4kHz >> 1; i++ ) - { - energy += target_ptr[target_ptr_offset+i] * target_ptr[target_ptr_offset+i]; - } - threshold = Cmax * Cmax; - if( energy / 16.0f > threshold ) - { - for(int i_djinn=0; i_djinn threshold ) - { - d_srch[ i ] = ( d_srch[ i ] + min_lag_4kHz ) << 1; - } - else - { - length_d_srch = i; - break; - } - } - assert( length_d_srch > 0 ); - - for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) { - d_comp[ i ] = 0; - } - for( i = 0; i < length_d_srch; i++ ) { - d_comp[ d_srch[ i ] ] = 1; - } - - /* Convolution */ - for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) { - d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ]; - } - - length_d_srch = 0; - for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) { - if( d_comp[ i + 1 ] > 0 ) { - d_srch[ length_d_srch ] = i; - length_d_srch++; - } - } - - /* Convolution */ - for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) { - d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ]; - } - - length_d_comp = 0; - for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) - { - if( d_comp[ i ] > 0 ) { - d_comp[ length_d_comp ] = (short)(i - 2); - length_d_comp++; - } - } - - /********************************************************************************** - ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation - *************************************************************************************/ - /********************************************************************************* - * Find energy of each subframe projected onto its history, for a range of delays - *********************************************************************************/ - for(int i_djinn=0; i_djinn< Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR; i_djinn++) - for(int j_djinn=0; j_djinn< ((Silk_common_pitch_est_defines.PITCH_EST_MAX_LAG >> 1) + 5); j_djinn++) - C[i_djinn][j_djinn] = 0; - - target_ptr = signal_8kHz; /* point to middle of frame */ - target_ptr_offset = frame_length_4kHz; - for( k = 0; k < Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR; k++ ) - { - /* Check that we are within range of the array */ - assert( target_ptr_offset >= 0 ); - assert( target_ptr_offset + sf_length_8kHz <= frame_length_8kHz ); - - energy_tmp = Silk_energy_FLP.SKP_Silk_energy_FLP( target_ptr,target_ptr_offset, sf_length_8kHz ); - for( j = 0; j < length_d_comp; j++ ) - { - d = d_comp[ j ]; - basis_ptr = target_ptr; - basis_ptr_offset = target_ptr_offset - d; - - /* Check that we are within range of the array */ - assert( basis_ptr_offset >= 0 ); - assert( basis_ptr_offset + sf_length_8kHz <= frame_length_8kHz ); - - cross_corr = Silk_inner_product_FLP.SKP_Silk_inner_product_FLP( basis_ptr,basis_ptr_offset, target_ptr,target_ptr_offset, sf_length_8kHz ); - energy = Silk_energy_FLP.SKP_Silk_energy_FLP( basis_ptr,basis_ptr_offset, sf_length_8kHz ); - if (cross_corr > 0.0f) - { - C[ k ][ d ] = (float)(cross_corr * cross_corr / (energy * energy_tmp + eps)); - } - else - { - C[ k ][ d ] = 0.0f; - } - } - target_ptr_offset += sf_length_8kHz; - } - - /* search over lag range and lags codebook */ - /* scale factor for lag codebook, as a function of center lag */ - - CCmax = 0.0f; /* This value doesn't matter */ - CCmax_b = -1000.0f; - - CBimax = 0; /* To avoid returning undefined lag values */ - lag = -1; /* To check if lag with strong enough correlation has been found */ - - if( prevLag > 0 ) { - if( Fs_kHz == 12 ) - { - prevLag = ( prevLag<<1 ) / 3; - } - else if( Fs_kHz == 16 ) - { - prevLag = prevLag>>1; - } - else if( Fs_kHz == 24 ) - { - prevLag = prevLag / 3; - } - prevLag_log2 = SKP_P_log2(prevLag); - } - else - { - prevLag_log2 = 0; - } - - /* If input is 8 khz use a larger codebook here because it is last stage */ - if( Fs_kHz == 8 && complexity > Silk_SigProc_FIX.SKP_Silk_PITCH_EST_MIN_COMPLEX ) - { - nb_cbks_stage2 = Silk_common_pitch_est_defines.PITCH_EST_NB_CBKS_STAGE2_EXT; - } - else - { - nb_cbks_stage2 = Silk_common_pitch_est_defines.PITCH_EST_NB_CBKS_STAGE2; - } - - for( k = 0; k < length_d_srch; k++ ) - { - d = d_srch[ k ]; - for( j = 0; j < nb_cbks_stage2; j++ ) - { - CC[j] = 0.0f; - for( i = 0; i < Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR; i++ ) { - /* Try all codebooks */ - CC[ j ] += C[ i ][ d + Silk_pitch_est_tables.SKP_Silk_CB_lags_stage2[ i ][ j ] ]; - } - } - /* Find best codebook */ - CCmax_new = -1000.0f; - CBimax_new = 0; - for( i = 0; i < nb_cbks_stage2; i++ ) - { - if( CC[ i ] > CCmax_new ) - { - CCmax_new = CC[ i ]; - CBimax_new = i; - } - } - CCmax_new = Math.max(CCmax_new, 0.0f); /* To avoid taking square root of negative number later */ - CCmax_new_b = CCmax_new; - - /* Bias towards shorter lags */ - lag_log2 = SKP_P_log2(d); - CCmax_new_b -= Silk_pitch_est_defines_FLP.PITCH_EST_FLP_SHORTLAG_BIAS * Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR * lag_log2; - - /* Bias towards previous lag */ - if ( prevLag > 0 ) - { - delta_lag_log2_sqr = lag_log2 - prevLag_log2; - delta_lag_log2_sqr *= delta_lag_log2_sqr; - CCmax_new_b -= Silk_pitch_est_defines_FLP.PITCH_EST_FLP_PREVLAG_BIAS * Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR * LTPCorr[0] * delta_lag_log2_sqr / (delta_lag_log2_sqr + 0.5f); - } - - if ( CCmax_new_b > CCmax_b && CCmax_new > Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR * search_thres2 * search_thres2 ) - { - CCmax_b = CCmax_new_b; - CCmax = CCmax_new; - lag = d; - CBimax = CBimax_new; - } - } - - if( lag == -1 ) - { - /* No suitable candidate found */ - for(int i_djinn=0; i_djinn 8 ) { - /* Search in original signal */ - - /* Compensate for decimation */ - assert( lag == Silk_SigProc_FIX.SKP_SAT16( lag ) ); - if( Fs_kHz == 12 ) - { - lag = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( Silk_macros.SKP_SMULBB( lag, 3 ), 1 ); - } - else if( Fs_kHz == 16 ) - { - lag = lag<<1; - } - else - { - lag = Silk_macros.SKP_SMULBB( lag, 3 ); - } - - lag = Silk_SigProc_FIX.SKP_LIMIT_int( lag, min_lag, max_lag ); - start_lag = Math.max( lag - 2, min_lag ); - end_lag = Math.min( lag + 2, max_lag ); - lag_new = lag; /* to avoid undefined lag */ - CBimax = 0; /* to avoid undefined lag */ - assert( CCmax >= 0.0f ); - LTPCorr[0] = (float)Math.sqrt( CCmax / Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR ); // Output normalized correlation - - CCmax = -1000.0f; - - /* Calculate the correlations and energies needed in stage 3 */ - SKP_P_Ana_calc_corr_st3( cross_corr_st3, signal,0, start_lag, sf_length, complexity ); - SKP_P_Ana_calc_energy_st3( energies_st3, signal,0, start_lag, sf_length, complexity ); - - lag_counter = 0; - assert( lag == Silk_SigProc_FIX.SKP_SAT16( lag ) ); - contour_bias = Silk_pitch_est_defines_FLP.PITCH_EST_FLP_FLATCONTOUR_BIAS / lag; - - /* Setup cbk parameters acording to complexity setting */ - cbk_size = Silk_pitch_est_tables.SKP_Silk_cbk_sizes_stage3[ complexity ]; - cbk_offset = Silk_pitch_est_tables.SKP_Silk_cbk_offsets_stage3[ complexity ]; - - for( d = start_lag; d <= end_lag; d++ ) - { - for( j = cbk_offset; j < ( cbk_offset + cbk_size ); j++ ) - { - cross_corr = 0.0; - energy = eps; - for( k = 0; k < Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR; k++ ) - { - energy += energies_st3[ k ][ j ][ lag_counter ]; - cross_corr += cross_corr_st3[ k ][ j ][ lag_counter ]; - } - if( cross_corr > 0.0 ) - { - CCmax_new = (float)(cross_corr * cross_corr / energy); - /* Reduce depending on flatness of contour */ - diff = j - ( Silk_common_pitch_est_defines.PITCH_EST_NB_CBKS_STAGE3_MAX >> 1 ); - CCmax_new *= ( 1.0f - contour_bias * diff * diff ); - } - else - { - CCmax_new = 0.0f; - } - - if( CCmax_new > CCmax ) - { - CCmax = CCmax_new; - lag_new = d; - CBimax = j; - } - } - lag_counter++; - } - - for( k = 0; k < Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR; k++ ) - { - pitch_out[k] = lag_new + Silk_pitch_est_tables.SKP_Silk_CB_lags_stage3[ k ][ CBimax ]; - } - lagIndex[0] = lag_new - min_lag; - contourIndex[0] = CBimax; - } - else - { - /* Save Lags and correlation */ - assert( CCmax >= 0.0f ); - LTPCorr[0] = (float)Math.sqrt(CCmax / Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR); /* Output normalized correlation */ - for( k = 0; k < Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR; k++ ) - { - pitch_out[ k ] = lag + Silk_pitch_est_tables.SKP_Silk_CB_lags_stage2[ k ][ CBimax ]; - } - lagIndex[0] = lag - min_lag; - contourIndex[0] = CBimax; - } - assert( lagIndex[0] >= 0 ); - /* return as voiced */ - return 0; - } - - /** - * Internally used functions. - * - * @param cross_corr_st3 3 DIM correlation array. - * @param signal vector to correlate. - * @param signal_offset offset of valid data. - * @param start_lag start lag. - * @param sf_length sub frame length. - * @param complexity Complexity setting. - */ - static void SKP_P_Ana_calc_corr_st3 - ( - float[][][] cross_corr_st3, - float signal[], /* I vector to correlate */ - int signal_offset, - int start_lag, /* I start lag */ - int sf_length, /* I sub frame length */ - int complexity /* I Complexity setting */ - ) - /*********************************************************************** - Calculates the correlations used in stage 3 search. In order to cover - the whole lag codebook for all the searched offset lags (lag +- 2), - the following correlations are needed in each sub frame: - - sf1: lag range [-8,...,7] total 16 correlations - sf2: lag range [-4,...,4] total 9 correlations - sf3: lag range [-3,....4] total 8 correltions - sf4: lag range [-6,....8] total 15 correlations - - In total 48 correlations. The direct implementation computed in worst case - 4*12*5 = 240 correlations, but more likely around 120. - **********************************************************************/ - { - float[] target_ptr, basis_ptr; - int target_ptr_offset, basis_ptr_offset; - int i, j, k, lag_counter; - int cbk_offset, cbk_size, delta, idx; - float[] scratch_mem = new float[ SCRATCH_SIZE ]; - - assert( complexity >= Silk_SigProc_FIX.SKP_Silk_PITCH_EST_MIN_COMPLEX ); - assert( complexity <= Silk_SigProc_FIX.SKP_Silk_PITCH_EST_MAX_COMPLEX ); - - cbk_offset = Silk_pitch_est_tables.SKP_Silk_cbk_offsets_stage3[ complexity ]; - cbk_size = Silk_pitch_est_tables.SKP_Silk_cbk_sizes_stage3[ complexity ]; - - target_ptr = signal;/* Pointer to middle of frame */ - target_ptr_offset = signal_offset+( sf_length << 2 ); - for( k = 0; k < Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR; k++ ) - { - lag_counter = 0; - - /* Calculate the correlations for each subframe */ - for( j = Silk_pitch_est_tables.SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ]; j <= Silk_pitch_est_tables.SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 1 ]; j++ ) - { - basis_ptr = target_ptr; - basis_ptr_offset = target_ptr_offset - ( start_lag + j ); - assert( lag_counter < SCRATCH_SIZE ); - scratch_mem[ lag_counter ] = (float)Silk_inner_product_FLP.SKP_Silk_inner_product_FLP( target_ptr,target_ptr_offset, basis_ptr,basis_ptr_offset, sf_length ); - lag_counter++; - } - - delta = Silk_pitch_est_tables.SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ]; - for( i = cbk_offset; i < ( cbk_offset + cbk_size ); i++ ) - { - /* Fill out the 3 dim array that stores the correlations for */ - /* each code_book vector for each start lag */ - idx = Silk_pitch_est_tables.SKP_Silk_CB_lags_stage3[ k ][ i ] - delta; - for( j = 0; j < Silk_common_pitch_est_defines.PITCH_EST_NB_STAGE3_LAGS; j++ ) - { - assert( idx + j < SCRATCH_SIZE ); - assert( idx + j < lag_counter ); - cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ]; - } - } - target_ptr_offset += sf_length; - } - } - - /** - * @param energies_st3 3 DIM correlation array. - * @param signal vector to correlate. - * @param signal_offset offset of valid data. - * @param start_lag start lag. - * @param sf_length sub frame length. - * @param complexity Complexity setting. - */ - static void SKP_P_Ana_calc_energy_st3 - ( - float[][][] energies_st3, - float signal[], /* I vector to correlate */ - int signal_offset, - int start_lag, /* I start lag */ - int sf_length, /* I sub frame length */ - int complexity /* I Complexity setting */ - ) - /**************************************************************** - Calculate the energies for first two subframes. The energies are - calculated recursively. - ****************************************************************/ - { - float[] target_ptr, basis_ptr; - int target_ptr_offset, basis_ptr_offset; - double energy; - int k, i, j, lag_counter; - int cbk_offset, cbk_size, delta, idx; - float[] scratch_mem = new float[ SCRATCH_SIZE ]; - - assert( complexity >= Silk_SigProc_FIX.SKP_Silk_PITCH_EST_MIN_COMPLEX ); - assert( complexity <= Silk_SigProc_FIX.SKP_Silk_PITCH_EST_MAX_COMPLEX ); - - cbk_offset = Silk_pitch_est_tables.SKP_Silk_cbk_offsets_stage3[ complexity ]; - cbk_size = Silk_pitch_est_tables.SKP_Silk_cbk_sizes_stage3[ complexity ]; - - target_ptr = signal; - target_ptr_offset = signal_offset+( sf_length << 2 ); - for( k = 0; k < Silk_common_pitch_est_defines.PITCH_EST_NB_SUBFR; k++ ) - { - lag_counter = 0; - - /* Calculate the energy for first lag */ - basis_ptr = target_ptr; - basis_ptr_offset = target_ptr_offset - ( start_lag + Silk_pitch_est_tables.SKP_Silk_Lag_range_stage3[complexity ][ k ][ 0 ]); - energy = Silk_energy_FLP.SKP_Silk_energy_FLP( basis_ptr,basis_ptr_offset, sf_length ) + 1e-3; - assert( energy >= 0.0 ); - scratch_mem[lag_counter] = (float)energy; - lag_counter++; - - for( i = 1; i < ( Silk_pitch_est_tables.SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 1 ] - Silk_pitch_est_tables.SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ] + 1 ); i++ ) - { - /* remove part outside new window */ - energy -= basis_ptr[basis_ptr_offset + sf_length - i] * basis_ptr[basis_ptr_offset + sf_length - i]; - assert( energy >= 0.0 ); - - /* add part that comes into window */ - energy += basis_ptr[ basis_ptr_offset -i ] * basis_ptr[ basis_ptr_offset-i ]; - assert( energy >= 0.0 ); - assert( lag_counter < SCRATCH_SIZE ); - scratch_mem[lag_counter] = (float)energy; - lag_counter++; - } - - delta = Silk_pitch_est_tables.SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ]; - for( i = cbk_offset; i < ( cbk_offset + cbk_size ); i++ ) - { - /* Fill out the 3 dim array that stores the correlations for */ - /* each code_book vector for each start lag */ - idx = Silk_pitch_est_tables.SKP_Silk_CB_lags_stage3[ k ][ i ] - delta; - for(j = 0; j < Silk_common_pitch_est_defines.PITCH_EST_NB_STAGE3_LAGS; j++) - { - assert( idx + j < SCRATCH_SIZE ); - assert( idx + j < lag_counter ); - energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ]; - assert( energies_st3[ k ][ i ][ j ] >= 0.0f ); - } - } - target_ptr_offset += sf_length; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_pitch_est_defines.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_pitch_est_defines.java deleted file mode 100644 index 5502b9654..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_pitch_est_defines.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Definitions For Fix pitch estimator - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_pitch_est_defines -{ - static final int PITCH_EST_SHORTLAG_BIAS_Q15 = 6554; /* 0.2f. for logarithmic weighting */ - static final int PITCH_EST_PREVLAG_BIAS_Q15 = 6554; /* Prev lag bias */ - static final int PITCH_EST_FLATCONTOUR_BIAS_Q20 = 52429; /* 0.05f */ -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_pitch_est_defines_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_pitch_est_defines_FLP.java deleted file mode 100644 index f11e8bb18..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_pitch_est_defines_FLP.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Definitions For FLP pitch estimator. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_pitch_est_defines_FLP -{ - static final float PITCH_EST_FLP_SHORTLAG_BIAS = 0.2f; /* for logarithmic weighting */ - static final float PITCH_EST_FLP_PREVLAG_BIAS = 0.2f; /* for logarithmic weighting */ - static final float PITCH_EST_FLP_FLATCONTOUR_BIAS = 0.05f; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_pitch_est_tables.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_pitch_est_tables.java deleted file mode 100644 index 6ab10f27b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_pitch_est_tables.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Auto Generated File from generate_pitch_est_tables.m - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_pitch_est_tables -{ - static short[][] SKP_Silk_CB_lags_stage2 = - { - {0, 2,-1,-1,-1, 0, 0, 1, 1, 0, 1}, - {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0}, - {0,-1, 2, 1, 0, 1, 1, 0, 0,-1,-1} - }; - - static short[][] SKP_Silk_CB_lags_stage3 = - { - {-9,-7,-6,-5,-5,-4,-4,-3,-3,-2,-2,-2,-1,-1,-1, 0, 0, 0, 1, 1, 0, 1, 2, 2, 2, 3, 3, 4, 4, 5, 6, 5, 6, 8}, - {-3,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0,-1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 2, 1, 2, 2, 2, 2, 3}, - { 3, 3, 2, 2, 2, 2, 1, 2, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,-1, 0, 0,-1,-1,-1,-1,-1,-2,-2,-2}, - { 9, 8, 6, 5, 6, 5, 4, 4, 3, 3, 2, 2, 2, 1, 0, 1, 1, 0, 0, 0,-1,-1,-1,-2,-2,-2,-3,-3,-4,-4,-5,-5,-6,-7} - }; - - static short[][][] SKP_Silk_Lag_range_stage3 = - { - /* Lags to search for low number of stage3 cbks */ - { - {-2,6}, - {-1,5}, - {-1,5}, - {-2,7} - }, - /* Lags to search for middle number of stage3 cbks */ - { - {-4,8}, - {-1,6}, - {-1,6}, - {-4,9} - }, - /* Lags to search for max number of stage3 cbks */ - { - {-9,12}, - {-3,7}, - {-2,7}, - {-7,13} - } - }; - - static short[] SKP_Silk_cbk_sizes_stage3 = - { - Silk_common_pitch_est_defines.PITCH_EST_NB_CBKS_STAGE3_MIN, - Silk_common_pitch_est_defines.PITCH_EST_NB_CBKS_STAGE3_MID, - Silk_common_pitch_est_defines.PITCH_EST_NB_CBKS_STAGE3_MAX - }; - - static short[] SKP_Silk_cbk_offsets_stage3 = - { - ((Silk_common_pitch_est_defines.PITCH_EST_NB_CBKS_STAGE3_MAX - Silk_common_pitch_est_defines.PITCH_EST_NB_CBKS_STAGE3_MIN) >> 1), - ((Silk_common_pitch_est_defines.PITCH_EST_NB_CBKS_STAGE3_MAX - Silk_common_pitch_est_defines.PITCH_EST_NB_CBKS_STAGE3_MID) >> 1), - 0 - }; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_prefilter_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_prefilter_FLP.java deleted file mode 100644 index 1169acf02..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_prefilter_FLP.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -import java.util.*; - -/** - * - * @author Dingxin Xu - */ -public class Silk_prefilter_FLP -{ - /** - * SKP_Silk_prefilter. Main Prefilter Function. - * @param psEnc Encoder state FLP. - * @param psEncCtrl Encoder control FLP. - * @param xw Weighted signal. - * @param x Speech signal. - * @param x_offset offset of valid data. - */ - static void SKP_Silk_prefilter_FLP( - SKP_Silk_encoder_state_FLP psEnc, /* I/O Encoder state FLP */ - SKP_Silk_encoder_control_FLP psEncCtrl, /* I Encoder control FLP */ - float xw[], /* O Weighted signal */ - float x[], /* I Speech signal */ - int x_offset - ) - { - SKP_Silk_prefilter_state_FLP P = psEnc.sPrefilt; - int j, k, lag; - float HarmShapeGain, Tilt, LF_MA_shp, LF_AR_shp; - float[] B = new float[ 2 ]; - float[] AR1_shp = new float[ Silk_define.NB_SUBFR * Silk_define.SHAPE_LPC_ORDER_MAX ]; - float[] px; - int px_offset; - float[] pxw, pst_res; - int pxw_offset; - int pst_res_offset; - float[] HarmShapeFIR = new float[ 3 ]; - float[] st_res = new float[ Silk_define.MAX_FRAME_LENGTH / Silk_define.NB_SUBFR + Silk_define.MAX_LPC_ORDER ]; - - /* Setup pointers */ - px = x; - px_offset = x_offset; - pxw = xw; - pxw_offset = 0; - lag = P.lagPrev; - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) - { - /* Update Variables that change per sub frame */ - if( psEncCtrl.sCmn.sigtype == Silk_define.SIG_TYPE_VOICED ) - { - lag = psEncCtrl.sCmn.pitchL[ k ]; - } - - /* Noise shape parameters */ - HarmShapeGain = psEncCtrl.HarmShapeGain[ k ] * ( 1.0f - psEncCtrl.HarmBoost[ k ] ); - HarmShapeFIR[ 0 ] = Silk_tables_other_FLP.SKP_Silk_HarmShapeFIR_FLP[ 0 ] * HarmShapeGain; - HarmShapeFIR[ 1 ] = Silk_tables_other_FLP.SKP_Silk_HarmShapeFIR_FLP[ 1 ] * HarmShapeGain; - HarmShapeFIR[ 2 ] = Silk_tables_other_FLP.SKP_Silk_HarmShapeFIR_FLP[ 2 ] * HarmShapeGain; - Tilt = psEncCtrl.Tilt[ k ]; - LF_MA_shp = psEncCtrl.LF_MA_shp[ k ]; - LF_AR_shp = psEncCtrl.LF_AR_shp[ k ]; -//TODO: copy the psEncCtrl.AR1 to a local buffer or use a reference(pointer) to the struct??? -// AR1_shp = psEncCtrl.AR1; -// AR1_shp_offset = k * Silk_define.SHAPE_LPC_ORDER_MAX; - Arrays.fill(AR1_shp, 0); - System.arraycopy(psEncCtrl.AR1, k * Silk_define.SHAPE_LPC_ORDER_MAX, - AR1_shp, 0, psEncCtrl.AR1.length-k * Silk_define.SHAPE_LPC_ORDER_MAX); - - /* Short term FIR filtering*/ - Silk_LPC_analysis_filter_FLP.SKP_Silk_LPC_analysis_filter_FLP( st_res, AR1_shp, - px, px_offset - psEnc.sCmn.shapingLPCOrder, - psEnc.sCmn.subfr_length + psEnc.sCmn.shapingLPCOrder, psEnc.sCmn.shapingLPCOrder ); - - pst_res = st_res; - pst_res_offset = psEnc.sCmn.shapingLPCOrder; // Point to first sample - - /* reduce (mainly) low frequencies during harmonic emphasis */ - B[ 0 ] = psEncCtrl.GainsPre[ k ]; - B[ 1 ] = -psEncCtrl.GainsPre[ k ] * - ( psEncCtrl.HarmBoost[ k ] * HarmShapeGain + Silk_perceptual_parameters_FLP.INPUT_TILT + - psEncCtrl.coding_quality * Silk_perceptual_parameters_FLP.HIGH_RATE_INPUT_TILT ); - pxw[ pxw_offset + 0 ] = B[ 0 ] * pst_res[ pst_res_offset + 0 ] + B[ 1 ] * P.sHarmHP; - for( j = 1; j < psEnc.sCmn.subfr_length; j++ ) { - pxw[ pxw_offset + j ] = B[ 0 ] * pst_res[ pst_res_offset + j ] + B[ 1 ] * pst_res[ pst_res_offset + j - 1 ]; - } - P.sHarmHP = pst_res[ pst_res_offset + psEnc.sCmn.subfr_length - 1 ]; - - SKP_Silk_prefilt_FLP( P, pxw, pxw_offset, pxw, pxw_offset, HarmShapeFIR, Tilt, LF_MA_shp, LF_AR_shp, lag, psEnc.sCmn.subfr_length ); - - px_offset += psEnc.sCmn.subfr_length; - pxw_offset += psEnc.sCmn.subfr_length; - } - P.lagPrev = psEncCtrl.sCmn.pitchL[ Silk_define.NB_SUBFR - 1 ]; - } - - /** - * SKP_Silk_prefilter_part1. Prefilter for finding Quantizer input signal. - * @param P - * @param st_res - * @param st_res_offset - * @param xw - * @param xw_offset - * @param HarmShapeFIR - * @param Tilt - * @param LF_MA_shp - * @param LF_AR_shp - * @param lag - * @param length - */ - static void SKP_Silk_prefilt_FLP( - SKP_Silk_prefilter_state_FLP P,/* (I/O) state */ - float st_res[], /* (I) */ - int st_res_offset, - float xw[], /* (O) */ - int xw_offset, - float []HarmShapeFIR, /* (I) */ - float Tilt, /* (I) */ - float LF_MA_shp, /* (I) */ - float LF_AR_shp, /* (I) */ - int lag, /* (I) */ - int length /* (I) */ - ) - { - int i; - int idx, LTP_shp_buf_idx; - float n_Tilt, n_LF, n_LTP; - float sLF_AR_shp, sLF_MA_shp; - float []LTP_shp_buf; - - /* To speed up use temp variables instead of using the struct */ - LTP_shp_buf = P.sLTP_shp1; - LTP_shp_buf_idx = P.sLTP_shp_buf_idx1; - sLF_AR_shp = P.sLF_AR_shp1; - sLF_MA_shp = P.sLF_MA_shp1; - - for( i = 0; i < length; i++ ) { - if( lag > 0 ) { - assert( Silk_define.HARM_SHAPE_FIR_TAPS == 3 ); - idx = lag + LTP_shp_buf_idx; - n_LTP = LTP_shp_buf[ ( idx - Silk_define.HARM_SHAPE_FIR_TAPS / 2 - 1) & Silk_define.LTP_MASK ] * HarmShapeFIR[ 0 ]; - n_LTP += LTP_shp_buf[ ( idx - Silk_define.HARM_SHAPE_FIR_TAPS / 2 ) & Silk_define.LTP_MASK ] * HarmShapeFIR[ 1 ]; - n_LTP += LTP_shp_buf[ ( idx - Silk_define.HARM_SHAPE_FIR_TAPS / 2 + 1) & Silk_define.LTP_MASK ] * HarmShapeFIR[ 2 ]; - } else { - n_LTP = 0; - } - - n_Tilt = sLF_AR_shp * Tilt; - n_LF = sLF_AR_shp * LF_AR_shp + sLF_MA_shp * LF_MA_shp; - - sLF_AR_shp = st_res[ st_res_offset + i ] - n_Tilt; - sLF_MA_shp = sLF_AR_shp - n_LF; - - LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & Silk_define.LTP_MASK; - LTP_shp_buf[ LTP_shp_buf_idx ] = sLF_MA_shp; - xw[ xw_offset + i ] = sLF_MA_shp - n_LTP; - } - /* Copy temp variable back to state */ - P.sLF_AR_shp1 = sLF_AR_shp; - P.sLF_MA_shp1 = sLF_MA_shp; - P.sLTP_shp_buf_idx1 = LTP_shp_buf_idx; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_process_NLSFs_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_process_NLSFs_FLP.java deleted file mode 100644 index 7990b75b9..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_process_NLSFs_FLP.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Limit, stabilize, convert and quantize NLSFs. - * - * @author Dingxin Xu - */ -public class Silk_process_NLSFs_FLP -{ - /** - * Limit, stabilize, convert and quantize NLSFs. - * @param psEnc Encoder state FLP - * @param psEncCtrl Encoder control FLP - * @param pNLSF NLSFs (quantized output) - */ - static void SKP_Silk_process_NLSFs_FLP( - SKP_Silk_encoder_state_FLP psEnc, /* I/O Encoder state FLP */ - SKP_Silk_encoder_control_FLP psEncCtrl, /* I/O Encoder control FLP */ - float []pNLSF /* I/O NLSFs (quantized output) */ - ) - { - boolean doInterpolate; - float pNLSFW[] = new float[ Silk_define.MAX_LPC_ORDER ]; - float NLSF_mu, NLSF_mu_fluc_red, i_sqr, NLSF_interpolation_factor = 0.0f; - final SKP_Silk_NLSF_CB_FLP psNLSF_CB_FLP; - - - /* Used only for NLSF interpolation */ - float pNLSF0_temp[] = new float[ Silk_define.MAX_LPC_ORDER ]; - float pNLSFW0_temp[] = new float[ Silk_define.MAX_LPC_ORDER ]; - int i; - - assert( psEncCtrl.sCmn.sigtype == Silk_define.SIG_TYPE_VOICED || psEncCtrl.sCmn.sigtype == Silk_define.SIG_TYPE_UNVOICED ); - - /***********************/ - /* Calculate mu values */ - /***********************/ - if( psEncCtrl.sCmn.sigtype == Silk_define.SIG_TYPE_VOICED ) { - NLSF_mu = 0.002f - 0.001f * psEnc.speech_activity; - NLSF_mu_fluc_red = 0.1f - 0.05f * psEnc.speech_activity; - } else { - NLSF_mu = 0.005f - 0.004f * psEnc.speech_activity; - NLSF_mu_fluc_red = 0.2f - 0.1f * ( psEnc.speech_activity + psEncCtrl.sparseness ); - } - - /* Calculate NLSF weights */ - Silk_NLSF_VQ_weights_laroia_FLP.SKP_Silk_NLSF_VQ_weights_laroia_FLP( pNLSFW, pNLSF, psEnc.sCmn.predictLPCOrder ); - - /* Update NLSF weights for interpolated NLSFs */ - doInterpolate = ( psEnc.sCmn.useInterpolatedNLSFs == 1 ) && ( psEncCtrl.sCmn.NLSFInterpCoef_Q2 < ( 1 << 2 ) ); - if( doInterpolate ) { - - /* Calculate the interpolated NLSF vector for the first half */ - NLSF_interpolation_factor = 0.25f * psEncCtrl.sCmn.NLSFInterpCoef_Q2; - Silk_wrappers_FLP.SKP_Silk_interpolate_wrapper_FLP( pNLSF0_temp, psEnc.sPred.prev_NLSFq, pNLSF, - NLSF_interpolation_factor, psEnc.sCmn.predictLPCOrder ); - - /* Calculate first half NLSF weights for the interpolated NLSFs */ - Silk_NLSF_VQ_weights_laroia_FLP.SKP_Silk_NLSF_VQ_weights_laroia_FLP( pNLSFW0_temp, pNLSF0_temp, psEnc.sCmn.predictLPCOrder ); - - /* Update NLSF weights with contribution from first half */ - i_sqr = NLSF_interpolation_factor * NLSF_interpolation_factor; - for( i = 0; i < psEnc.sCmn.predictLPCOrder; i++ ) { - pNLSFW[ i ] = 0.5f * ( pNLSFW[ i ] + i_sqr * pNLSFW0_temp[ i ] ); - } - } - - /* Set pointer to the NLSF codebook for the current signal type and LPC order */ - psNLSF_CB_FLP = psEnc.psNLSF_CB_FLP[ psEncCtrl.sCmn.sigtype ]; - - /* Quantize NLSF parameters given the trained NLSF codebooks */ - Silk_NLSF_MSVQ_encode_FLP.SKP_Silk_NLSF_MSVQ_encode_FLP( psEncCtrl.sCmn.NLSFIndices, pNLSF, psNLSF_CB_FLP, psEnc.sPred.prev_NLSFq, - pNLSFW, NLSF_mu, NLSF_mu_fluc_red, psEnc.sCmn.NLSF_MSVQ_Survivors, - psEnc.sCmn.predictLPCOrder, psEnc.sCmn.first_frame_after_reset ); - - /* Convert quantized NLSFs back to LPC coefficients */ - Silk_wrappers_FLP.SKP_Silk_NLSF2A_stable_FLP( psEncCtrl.PredCoef[ 1 ], pNLSF, psEnc.sCmn.predictLPCOrder ); - - if( doInterpolate ) { - /* Calculate the interpolated, quantized NLSF vector for the first half */ - Silk_wrappers_FLP.SKP_Silk_interpolate_wrapper_FLP( pNLSF0_temp, psEnc.sPred.prev_NLSFq, pNLSF, - NLSF_interpolation_factor, psEnc.sCmn.predictLPCOrder ); - - /* Convert back to LPC coefficients */ - Silk_wrappers_FLP.SKP_Silk_NLSF2A_stable_FLP( psEncCtrl.PredCoef[ 0 ], pNLSF0_temp, psEnc.sCmn.predictLPCOrder ); - - } else { - /* Copy LPC coefficients for first half from second half */ - System.arraycopy(psEncCtrl.PredCoef[1], 0, psEncCtrl.PredCoef[0], 0, psEnc.sCmn.predictLPCOrder); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_process_gains_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_process_gains_FLP.java deleted file mode 100644 index d452679ef..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_process_gains_FLP.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * processing of gains. - * - * @author Dingxin Xu - */ -public class Silk_process_gains_FLP -{ - /** - * Processing of gains. - * @param psEnc Encoder state FLP - * @param psEncCtrl Encoder control FLP - */ - static void SKP_Silk_process_gains_FLP( - SKP_Silk_encoder_state_FLP psEnc, /* I/O Encoder state FLP */ - SKP_Silk_encoder_control_FLP psEncCtrl /* I/O Encoder control FLP */ - ) - { - SKP_Silk_shape_state_FLP psShapeSt = psEnc.sShape; - int k; - int pGains_Q16[] = new int[ Silk_define.NB_SUBFR ]; - float s, InvMaxSqrVal, gain; - - /* Gain reduction when LTP coding gain is high */ - if( psEncCtrl.sCmn.sigtype == Silk_define.SIG_TYPE_VOICED ) { - s = 1.0f - 0.5f * Silk_SigProc_FLP.SKP_sigmoid( 0.25f * ( psEncCtrl.LTPredCodGain - 12.0f ) ); - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - psEncCtrl.Gains[ k ] *= s; - } - } - - /* Limit the quantized signal */ - InvMaxSqrVal = ( float )( Math.pow( 2.0f, 0.33f * ( 21.0f - psEncCtrl.current_SNR_dB ) ) / psEnc.sCmn.subfr_length ); - - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - /* Soft limit on ratio residual energy and squared gains */ - gain = psEncCtrl.Gains[ k ]; - gain = ( float )Math.sqrt( gain * gain + psEncCtrl.ResNrg[ k ] * InvMaxSqrVal ); - psEncCtrl.Gains[ k ] = ( gain < 32767.0f ? gain : 32767.0f ); - } - - /* Prepare gains for noise shaping quantization */ - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - pGains_Q16[ k ] = ( int ) ( psEncCtrl.Gains[ k ] * 65536.0f ); - } - - /* Noise shaping quantization */ - int[] LastGainIndex_ptr = new int[1]; - LastGainIndex_ptr[0] = psShapeSt.LastGainIndex; - Silk_gain_quant.SKP_Silk_gains_quant( psEncCtrl.sCmn.GainsIndices, pGains_Q16, - LastGainIndex_ptr, psEnc.sCmn.nFramesInPayloadBuf ); - psShapeSt.LastGainIndex = LastGainIndex_ptr[0]; - /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ - for( k = 0; k < Silk_define.NB_SUBFR; k++ ) { - psEncCtrl.Gains[ k ] = pGains_Q16[ k ] / 65536.0f; - } - - /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */ - if( psEncCtrl.sCmn.sigtype == Silk_define.SIG_TYPE_VOICED ) { - if( psEncCtrl.LTPredCodGain + psEncCtrl.input_tilt > 1.0f ) { - psEncCtrl.sCmn.QuantOffsetType = 0; - } else { - psEncCtrl.sCmn.QuantOffsetType = 1; - } - } - - /* Quantizer boundary adjustment */ - if( psEncCtrl.sCmn.sigtype == Silk_define.SIG_TYPE_VOICED ) { - psEncCtrl.Lambda = 1.2f - 0.4f * psEnc.speech_activity - - 0.3f * psEncCtrl.input_quality - + 0.2f * psEncCtrl.sCmn.QuantOffsetType - - 0.1f * psEncCtrl.coding_quality; - } else { - psEncCtrl.Lambda = 1.2f - 0.4f * psEnc.speech_activity - - 0.4f * psEncCtrl.input_quality - + 0.4f * psEncCtrl.sCmn.QuantOffsetType - - 0.1f * psEncCtrl.coding_quality; - } - - assert( psEncCtrl.Lambda >= 0.0f ); - assert( psEncCtrl.Lambda < 2.0f ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_quant_LTP_gains_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_quant_LTP_gains_FLP.java deleted file mode 100644 index 2c8f3798d..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_quant_LTP_gains_FLP.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Dingxin Xu - */ -public class Silk_quant_LTP_gains_FLP -{ - - /** - * - * @param B (Un-)quantized LTP gains - * @param cbk_index Codebook index - * @param periodicity_index Periodicity index - * @param W Error weights - * @param mu Mu value (R/D tradeoff) - * @param lowComplexity Flag for low complexity - */ - static void SKP_Silk_quant_LTP_gains_FLP( - float B[], /* I/O (Un-)quantized LTP gains */ - int cbk_index[], /* O Codebook index */ - int []periodicity_index, /* O Periodicity index */ - final float W[], /* I Error weights */ - final float mu, /* I Mu value (R/D tradeoff) */ - final int lowComplexity /* I Flag for low complexity */ - ) - { -// SKP_int j, k, temp_idx[ NB_SUBFR ], cbk_size; -// const SKP_uint16 *cdf_ptr; -// const SKP_int16 *cl_ptr; -// const SKP_int16 *cbk_ptr_Q14; -// const SKP_float *b_ptr, *W_ptr; -// SKP_float rate_dist_subfr, rate_dist, min_rate_dist; - int j,k,cbk_size; - int[] temp_idx = new int[Silk_define.NB_SUBFR]; - int[] cdf_ptr; int cdf_ptr_offset; - short[] cl_ptr; int cl_ptr_offset; - short[] cbk_ptr_Q14; int cbk_ptr_Q14_offset; - float b_ptr[]; - float W_ptr[]; int b_ptr_offset,W_ptr_offset; - float rate_dist_subfr = 0, rate_dist, min_rate_dist; - - - - /***************************************************/ - /* Iterate over different codebooks with different */ - /* rates/distortions, and choose best */ - /***************************************************/ -// min_rate_dist = SKP_float_MAX; - min_rate_dist = Float.MAX_VALUE; - for( k = 0; k < 3; k++ ) { - cdf_ptr = Silk_tables_LTP.SKP_Silk_LTP_gain_CDF_ptrs[ k ]; - cl_ptr = Silk_tables_LTP.SKP_Silk_LTP_gain_BITS_Q6_ptrs[ k ]; - cbk_ptr_Q14 = Silk_tables_LTP.SKP_Silk_LTP_vq_ptrs_Q14[ k ]; - cbk_size = Silk_tables_LTP.SKP_Silk_LTP_vq_sizes[ k ]; - - - /* Setup pointer to first subframe */ - W_ptr = W; - W_ptr_offset = 0; - b_ptr = B; - b_ptr_offset = 0; - - rate_dist = 0.0f; - for( j = 0; j < Silk_define.NB_SUBFR; j++ ) { - - float [] rate_dist_subfr_ptr = new float[1]; - rate_dist_subfr_ptr[0] = rate_dist_subfr; - - Silk_VQ_nearest_neighbor_FLP.SKP_Silk_VQ_WMat_EC_FLP( - temp_idx, /* O index of best codebook vector */ - j, - rate_dist_subfr_ptr, /* O best weighted quantization error + mu * rate */ - b_ptr, /* I input vector to be quantized */ - b_ptr_offset, - W_ptr, /* I weighting matrix */ - W_ptr_offset, - cbk_ptr_Q14, /* I codebook */ - cl_ptr, /* I code length for each codebook vector */ - mu, /* I tradeoff between weighted error and rate */ - cbk_size /* I number of vectors in codebook */ - ); - rate_dist_subfr = rate_dist_subfr_ptr[0]; -// Silk_VQ_nearest_neighbor_FLP.SKP_Silk_VQ_WMat_EC_FLP( -// &temp_idx[ j ], /* O index of best codebook vector */ -// &rate_dist_subfr, /* O best weighted quantization error + mu * rate */ -// b_ptr, /* I input vector to be quantized */ -// W_ptr, /* I weighting matrix */ -// cbk_ptr_Q14, /* I codebook */ -// cl_ptr, /* I code length for each codebook vector */ -// mu, /* I tradeoff between weighted error and rate */ -// cbk_size /* I number of vectors in codebook */ -// ); - - - rate_dist += rate_dist_subfr; - -// b_ptr += LTP_ORDER; -// W_ptr += LTP_ORDER * LTP_ORDER; - b_ptr_offset += Silk_define.LTP_ORDER; - W_ptr_offset += Silk_define.LTP_ORDER * Silk_define.LTP_ORDER; - } - - if( rate_dist < min_rate_dist ) { - min_rate_dist = rate_dist; -// SKP_memcpy( cbk_index, temp_idx, NB_SUBFR * sizeof( SKP_int ) ); -// *periodicity_index = k; - System.arraycopy(temp_idx, 0, cbk_index, 0, Silk_define.NB_SUBFR); - periodicity_index[0] = k; - } - - /* Break early in low-complexity mode if rate distortion is below threshold */ - if( lowComplexity != 0 && ( rate_dist * 16384.0f < Silk_tables_LTP.SKP_Silk_LTP_gain_middle_avg_RD_Q14 ) ) { - break; - } - } - -// cbk_ptr_Q14 = SKP_Silk_LTP_vq_ptrs_Q14[ *periodicity_index ]; - cbk_ptr_Q14 = Silk_tables_LTP.SKP_Silk_LTP_vq_ptrs_Q14[periodicity_index[0]]; - - for( j = 0; j < Silk_define.NB_SUBFR; j++ ) { -// SKP_short2float_array( &B[ j * LTP_ORDER ], -// &cbk_ptr_Q14[ cbk_index[ j ] * LTP_ORDER ], -// LTP_ORDER ); - Silk_SigProc_FLP.SKP_short2float_array(B, j*Silk_define.LTP_ORDER, - cbk_ptr_Q14, cbk_index[ j ] * Silk_define.LTP_ORDER, - Silk_define.LTP_ORDER); - } - - for( j = 0; j < Silk_define.NB_SUBFR * Silk_define.LTP_ORDER; j++ ) { - B[ j ] *= Silk_define_FLP.Q14_CONVERSION_FAC; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_range_coder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_range_coder.java deleted file mode 100644 index 034304133..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_range_coder.java +++ /dev/null @@ -1,471 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Range coder - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_range_coder -{ - /** - * Range encoder for one symbol. - * @param psRC compressor data structure. - * @param data uncompressed data. - * @param prob cumulative density functions. - * @param prob_offset offset of valid data. - */ - static void SKP_Silk_range_encoder( - SKP_Silk_range_coder_state psRC, /* I/O compressor data structure */ - final int data, /* I uncompressed data */ - int prob[], /* I cumulative density functions */ - int prob_offset - ) - { - long low_Q16, high_Q16; - long base_tmp, range_Q32; - - /* Copy structure data */ - long base_Q32 = psRC.base_Q32; - long range_Q16 = psRC.range_Q16; - int bufferIx = psRC.bufferIx; - byte[] buffer = psRC.buffer; - - if( psRC.error!=0 ) - { - return; - } - - /* Update interval */ - low_Q16 = prob[ prob_offset + data ]; - high_Q16 = prob[ prob_offset + data + 1 ]; - base_tmp = base_Q32; /* save current base, to test for carry */ - -//TODO: base_Q32 should be 32-bit -// base_Q32 += ( range_Q16 * low_Q16 ) & 0xFFFFFFFFL; - base_Q32 += ( range_Q16 * low_Q16 ) & 0xFFFFFFFFL; - base_Q32 = base_Q32 & 0xFFFFFFFFL; - - range_Q32 = ( range_Q16 * (high_Q16 - low_Q16) )& 0xFFFFFFFFL; - - /* Check for carry */ - if( base_Q32 < base_tmp ) - { - /* Propagate carry in buffer */ - int bufferIx_tmp = bufferIx; - while( ( ++buffer[ --bufferIx_tmp ] ) == 0 ); - } - - /* Check normalization */ - if( (range_Q32 & 0xFF000000L)!=0 ) -// if( (range_Q32 & 0xFF000000)!=0 ) - { - /* No normalization */ -// range_Q16 = ( range_Q32 >> 16 ); - range_Q16 = ( range_Q32 >>> 16 ); - - } - else - { - if( (range_Q32 & 0xFFFF0000L)!=0 ) -// if( (range_Q32 & 0xFFFF0000)!=0 ) - { - /* Normalization of 8 bits shift */ -// range_Q16 = ( range_Q32 >> 8 ); - range_Q16 = ( range_Q32 >>> 8 ); - } - else - { - /* Normalization of 16 bits shift */ - range_Q16 = range_Q32; - /* Make sure not to write beyond buffer */ - if( bufferIx >= psRC.bufferLength ) - { - psRC.error = Silk_define.RANGE_CODER_WRITE_BEYOND_BUFFER; - return; - } - /* Write one byte to buffer */ - buffer[ bufferIx++ ] = (byte)( base_Q32 >>> 24 ); -// base_Q32 = base_Q32 << 8; - base_Q32 = (base_Q32 << 8)&0xFFFFFFFFL; - - } - /* Make sure not to write beyond buffer */ - if( bufferIx >= psRC.bufferLength ) - { - psRC.error = Silk_define.RANGE_CODER_WRITE_BEYOND_BUFFER; - return; - } - /* Write one byte to buffer */ - buffer[ bufferIx++ ] = (byte)( base_Q32 >>> 24 ); -// base_Q32 = base_Q32 << 8; - base_Q32 = (base_Q32 << 8)&0xFFFFFFFFL; - } - - /* Copy structure data back */ - psRC.base_Q32 = base_Q32; - psRC.range_Q16 = range_Q16; - psRC.bufferIx = bufferIx; - } - - /** - * Range encoder for multiple symbols. - * @param psRC compressor data structure. - * @param data uncompressed data [nSymbols]. - * @param prob cumulative density functions. - * @param nSymbols number of data symbols. - */ - static void SKP_Silk_range_encoder_multi( - SKP_Silk_range_coder_state psRC, /* I/O compressor data structure */ - int[] data, /* I uncompressed data [nSymbols] */ - int[][] prob, /* I cumulative density functions */ - final int nSymbols /* I number of data symbols */ - ) - { - int k; - for( k = 0; k < nSymbols; k++ ) - { - SKP_Silk_range_encoder( psRC, data[ k ], prob[ k ], 0 ); - } - } - - /** - * Range decoder for one symbol. - * @param data uncompressed data. - * @param data_offset offset of valid data. - * @param psRC compressor data structure. - * @param prob cumulative density function. - * @param prob_offset offset of valid data. - * @param probIx initial (middle) entry of cdf. - */ - static void SKP_Silk_range_decoder( - int data[], /* O uncompressed data */ - int data_offset, - SKP_Silk_range_coder_state psRC, /* I/O compressor data structure */ - final int prob[], /* I cumulative density function */ - int prob_offset, - int probIx /* I initial (middle) entry of cdf */ - ) - { - long low_Q16, high_Q16; - long base_tmp, range_Q32; - - /* Copy structure data */ - long base_Q32 = psRC.base_Q32; - long range_Q16 = psRC.range_Q16; - int bufferIx = psRC.bufferIx; - byte[] buffer = psRC.buffer; - int buffer_offset = 4; - - if( psRC.error != 0) { - /* Set output to zero */ - data[data_offset + 0] = 0; - return; - } - - high_Q16 = prob[prob_offset + probIx]; - -//TODO base_tmp = Silk_SigProc_FIX.SKP_MUL_uint( range_Q16, high_Q16 ); - base_tmp = ( range_Q16 * high_Q16 ) & 0xFFFFFFFFL; - - if( base_tmp > base_Q32 ) { - while( true ) { - low_Q16 = prob[ --probIx + prob_offset ]; -// base_tmp = Silk_SigProc_FIX.SKP_MUL_uint( range_Q16, low_Q16 ); - base_tmp = (range_Q16 * low_Q16 ) & 0xFFFFFFFFL; - if( base_tmp <= base_Q32 ) { - break; - } - high_Q16 = low_Q16; - /* Test for out of range */ - if( high_Q16 == 0 ) { - psRC.error = Silk_define.RANGE_CODER_CDF_OUT_OF_RANGE; - /* Set output to zero */ - data[data_offset + 0] = 0; - return; - } - } - } else { - while( true ) { - low_Q16 = high_Q16; - high_Q16 = prob[ ++probIx + prob_offset ]; -// base_tmp = Silk_SigProc_FIX.SKP_MUL_uint( range_Q16, high_Q16 ); - base_tmp = (range_Q16 * high_Q16) & 0xFFFFFFFFL; - if( base_tmp > base_Q32 ) { - probIx--; - break; - } - /* Test for out of range */ - if( high_Q16 == 0xFFFF ) { - psRC.error = Silk_define.RANGE_CODER_CDF_OUT_OF_RANGE; - /* Set output to zero */ - data[data_offset + 0] = 0; - return; - } - } - } - data[data_offset + 0] = probIx; - -// base_Q32 -= Silk_SigProc_FIX.SKP_MUL_uint( range_Q16, low_Q16 ); - base_Q32 -= (range_Q16 * low_Q16) & 0xFFFFFFFFL; - base_Q32 = base_Q32 & 0xFFFFFFFFL; -// range_Q32 = Silk_SigProc_FIX.SKP_MUL_uint( range_Q16, high_Q16 - low_Q16 ); - range_Q32 = (range_Q16 * (high_Q16 - low_Q16)) & 0xFFFFFFFFL; - range_Q32 = range_Q32 & 0xFFFFFFFFL; - - /* Check normalization */ -//TODO:or if( (range_Q32 & 0xFF000000) != 0 ) { - if( (range_Q32 & 0xFF000000L) != 0 ) { - /* No normalization */ - range_Q16 = range_Q32>>>16; - } else { -//TODO:or if( (range_Q32 & 0xFFFF0000) != 0 ) { - if( (range_Q32 & 0xFFFF0000L) != 0 ) { - /* Normalization of 8 bits shift */ - range_Q16 = ( range_Q32 >>> 8 ); - /* Check for errors */ - if( ( base_Q32 >>> 24 ) != 0) { - psRC.error = Silk_define.RANGE_CODER_NORMALIZATION_FAILED; - /* Set output to zero */ - data[data_offset + 0] = 0; - return; - } - } else { - /* Normalization of 16 bits shift */ - range_Q16 = range_Q32; - /* Check for errors */ -//TODO: if( ( base_Q32 >> 16 ) != 0 ) { - if((base_Q32 >>>16) != 0) { - psRC.error = Silk_define.RANGE_CODER_NORMALIZATION_FAILED; - /* Set output to zero */ - data[data_offset + 0] = 0; - return; - } - /* Update base */ - base_Q32 = ( base_Q32 << 8 ); - base_Q32 = base_Q32 & 0xFFFFFFFFL; - /* Make sure not to read beyond buffer */ - if( bufferIx < psRC.bufferLength ) { - /* Read one byte from buffer */ - base_Q32 |= (buffer[buffer_offset + bufferIx++ ])&0xFF; - } - } - /* Update base */ - base_Q32 = ( base_Q32 << 8 ); - base_Q32 = base_Q32 & 0xFFFFFFFFL; - /* Make sure not to read beyond buffer */ - if( bufferIx < psRC.bufferLength ) { - /* Read one byte from buffer */ - base_Q32 |= (buffer[ buffer_offset + bufferIx++ ])&0xFF; - } - } - - /* Check for zero interval length */ - if( range_Q16 == 0 ) { - psRC.error = Silk_define.RANGE_CODER_ZERO_INTERVAL_WIDTH; - /* Set output to zero */ - data[data_offset + 0] = 0; - return; - } - - /* Copy structure data back */ - psRC.base_Q32 = base_Q32; - psRC.range_Q16 = range_Q16; - psRC.bufferIx = bufferIx; - } - - /** - * Range decoder for multiple symbols. - * @param data uncompressed data [nSymbols]. - * @param psRC compressor data structure. - * @param prob cumulative density functions. - * @param probStartIx initial (middle) entries of cdfs [nSymbols]. - * @param nSymbols number of data symbols. - */ - static void SKP_Silk_range_decoder_multi( - int data[], /* O uncompressed data [nSymbols] */ - SKP_Silk_range_coder_state psRC, /* I/O compressor data structure */ - int[][] prob, /* I cumulative density functions */ - int probStartIx[], /* I initial (middle) entries of cdfs [nSymbols] */ - final int nSymbols /* I number of data symbols */ - ) - { - int k; - for( k = 0; k < nSymbols; k++ ) { - SKP_Silk_range_decoder( data, k, psRC, prob[ k ], 0, probStartIx[ k ] ); - } - } - - /** - * Initialize range encoder. - * @param psRC compressor data structure. - */ - static void SKP_Silk_range_enc_init( - SKP_Silk_range_coder_state psRC /* O compressor data structure */ - ) - { - /* Initialize structure */ - psRC.bufferLength = Silk_define.MAX_ARITHM_BYTES; - psRC.range_Q16 = 0x0000FFFF; - psRC.bufferIx = 0; - psRC.base_Q32 = 0; - psRC.error = 0; - } - - /** - * Initialize range decoder. - * @param psRC compressor data structure. - * @param buffer buffer for compressed data [bufferLength]. - * @param buffer_offset offset of valid data. - * @param bufferLength buffer length (in bytes). - */ - static void SKP_Silk_range_dec_init( - SKP_Silk_range_coder_state psRC, /* O compressor data structure */ - byte buffer[], /* I buffer for compressed data [bufferLength] */ - int buffer_offset, - final int bufferLength /* I buffer length (in bytes) */ - ) - { - /* check input */ - if( bufferLength > Silk_define.MAX_ARITHM_BYTES ) { - psRC.error = Silk_define.RANGE_CODER_DEC_PAYLOAD_TOO_LONG; - return; - } - /* Initialize structure */ - /* Copy to internal buffer */ - System.arraycopy(buffer, buffer_offset, psRC.buffer, 0, bufferLength); - - psRC.bufferLength = bufferLength; - psRC.bufferIx = 0; - psRC.base_Q32 = - ( - ( (buffer[ buffer_offset + 0 ] & 0xFF) << 24 ) | - ( (buffer[ buffer_offset + 1 ] & 0xFF) << 16 ) | - ( (buffer[ buffer_offset + 2 ] & 0xFF) << 8 ) | - (buffer[ buffer_offset + 3 ] & 0xFF) - )&0xFFFFFFFFL; - psRC.range_Q16 = 0x0000FFFF; - psRC.error = 0; - } - - /** - * Determine length of bitstream. - * @param psRC compressed data structure. - * @param nBytes number of BYTES in stream. - * @return returns number of BITS in stream. - */ - static int SKP_Silk_range_coder_get_length( /* O returns number of BITS in stream */ - SKP_Silk_range_coder_state psRC, /* I compressed data structure */ - int[] nBytes /* O number of BYTES in stream */ - ) - { - int nBits; - - /* Number of bits in stream */ - nBits = ( psRC.bufferIx << 3 ) + Silk_macros.SKP_Silk_CLZ32((int) (psRC.range_Q16 - 1) ) - 14; - - nBytes [0] = (( nBits + 7)>> 3 ); - /* Return number of bits in bitstream */ - return nBits; - } - - /** - * Write shortest uniquely decodable stream to buffer, and determine its length. - * @param psRC ompressed data structure. - */ - static void SKP_Silk_range_enc_wrap_up( - SKP_Silk_range_coder_state psRC /* I/O compressed data structure */ - ) - { - int bufferIx_tmp, bits_to_store, bits_in_stream, nBytes, mask; - long base_Q24; - - /* Lower limit of interval, shifted 8 bits to the right */ - base_Q24 = psRC.base_Q32 >>> 8; - - int[] nBytes_ptr = new int[1]; - bits_in_stream = SKP_Silk_range_coder_get_length( psRC, nBytes_ptr ); - nBytes = nBytes_ptr[0]; - - /* Number of additional bits (1..9) required to be stored to stream */ -//TODO: bits_to_store = bits_in_stream - psRC.bufferIx << 3 ; - bits_to_store = bits_in_stream - (psRC.bufferIx << 3) ; - - /* Round up to required resolution */ -//TODO:base_Q24 should be 32-bit long. -// base_Q24 += 0x00800000 >>> ( bits_to_store - 1 ); - base_Q24 += 0x00800000 >>> ( bits_to_store - 1 ); - base_Q24 = base_Q24 & 0xFFFFFFFFL; -// base_Q24 &= 0xFFFFFFFF << ( 24 - bits_to_store ); - base_Q24 &= 0xFFFFFFFF << ( 24 - bits_to_store ); - - - /* Check for carry */ - if( (base_Q24 & 0x01000000) != 0 ) - { - /* Propagate carry in buffer */ - bufferIx_tmp = psRC.bufferIx; - while( ( ++( psRC.buffer[ --bufferIx_tmp ] ) ) == 0 ); - } - - /* Store to stream, making sure not to write beyond buffer */ - if( psRC.bufferIx < psRC.bufferLength ) - { - psRC.buffer[ psRC.bufferIx++ ] = (byte) ( base_Q24>>> 16 ); - if( bits_to_store > 8 ) - { - if( psRC.bufferIx < psRC.bufferLength ) - { - psRC.buffer[ psRC.bufferIx++ ] = (byte) ( base_Q24 >>> 8 ); - } - } - } - - /* Fill up any remaining bits in the last byte with 1s */ - if( (bits_in_stream & 7) != 0 ) - { - mask = 0xFF >> ( bits_in_stream & 7 ); - if( nBytes - 1 < psRC.bufferLength ) - { - psRC.buffer[ nBytes - 1 ] |= mask; - } - } - } - - /** - * Check that any remaining bits in the last byte are set to 1. - * @param psRC compressed data structure. - */ - static void SKP_Silk_range_coder_check_after_decoding( - SKP_Silk_range_coder_state psRC /* I/O compressed data structure */ - ) - { - int bits_in_stream, nBytes, mask; - int nBytes_ptr[] = new int[1]; - - bits_in_stream = SKP_Silk_range_coder_get_length( psRC, nBytes_ptr ); - nBytes = nBytes_ptr[0]; - - /* Make sure not to read beyond buffer */ - if( nBytes - 1 >= psRC.bufferLength ) { - psRC.error = Silk_define.RANGE_CODER_DECODER_CHECK_FAILED; - return; - } - - /* Test any remaining bits in last byte */ - if( (bits_in_stream & 7) != 0 ) { - mask = ( 0xFF >>( bits_in_stream & 7) ); - - if( ( psRC.buffer[ nBytes - 1 ] & mask ) != mask ) { - psRC.error = Silk_define.RANGE_CODER_DECODER_CHECK_FAILED; - return; - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_regularize_correlations_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_regularize_correlations_FLP.java deleted file mode 100644 index 03b9a9c2c..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_regularize_correlations_FLP.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Dingxin Xu - */ -public class Silk_regularize_correlations_FLP -{ - /** - * - * @param XX Correlation matrices - * @param xx Correlation values - * @param xx_offset offset of valid data. - * @param noise Noise energy to add - * @param D Dimension of XX - */ - static void SKP_Silk_regularize_correlations_FLP( - float []XX, /* I/O Correlation matrices */ - int XX_offset, - float []xx, /* I/O Correlation values */ - int xx_offset, - float noise, /* I Noise energy to add */ - int D /* I Dimension of XX */ - ) - { - int i; - - for( i = 0; i < D; i++ ) { - XX[XX_offset + i*D+i] += noise; - } - xx[ xx_offset ] += noise; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler.java deleted file mode 100644 index a859c4418..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler.java +++ /dev/null @@ -1,513 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -import java.util.*; - -/** - * Interface to collection of resamplers. - * - * @author Jing Dai - * @author Dingxin Xu - */ -/* Matrix of resampling methods used: - * Fs_out (kHz) - * 8 12 16 24 32 44.1 48 - * - * 8 C UF U UF UF UF UF - * 12 AF C UF U UF UF UF - * 16 D AF C UF U UF UF - * Fs_in (kHz) 24 AIF D AF C UF UF U - * 32 UF AF D AF C UF UF - * 44.1 AMI AMI AMI AMI AMI C UF - * 48 DAF DAF AF D AF UF C - * - * default method: UF - * - * C -> Copy (no resampling) - * D -> Allpass-based 2x downsampling - * U -> Allpass-based 2x upsampling - * DAF -> Allpass-based 2x downsampling followed by AR2 filter followed by FIR interpolation - * UF -> Allpass-based 2x upsampling followed by FIR interpolation - * AMI -> ARMA4 filter followed by FIR interpolation - * AF -> AR2 filter followed by FIR interpolation - * - * Input signals sampled above 48 kHz are first downsampled to at most 48 kHz. - * Output signals sampled above 48 kHz are upsampled from at most 48 kHz. - */ -public class Silk_resampler -{ - /** - * Greatest common divisor. - * @param a - * @param b - */ - static int gcd(int a, int b) - { - int tmp; - while( b > 0 ) - { - tmp = a - b * (a/b); - a = b; - b = tmp; - } - return a; - } - - /** - * Initialize/reset the resampler state for a given pair of input/output sampling rates. - * @param S resampler state. - * @param Fs_Hz_in Input sampling rate (Hz). - * @param Fs_Hz_out Output sampling rate (Hz). - * @return - */ - static int SKP_Silk_resampler_init( - SKP_Silk_resampler_state_struct S, /* I/O: Resampler state */ - int Fs_Hz_in, /* I: Input sampling rate (Hz) */ - int Fs_Hz_out /* I: Output sampling rate (Hz) */ - ) - { - int cycleLen, cyclesPerBatch, up2 = 0, down2 = 0; - - /* Clear state */ -//TODO:how to set all fields of S to 0? - //S = new SKP_Silk_resampler_state_struct(); - S.memZero(); - - /* Input checking */ - if(Silk_resampler_structs.RESAMPLER_SUPPORT_ABOVE_48KHZ != 0) - { - if( Fs_Hz_in < 8000 || Fs_Hz_in > 192000 || Fs_Hz_out < 8000 || Fs_Hz_out > 192000 ) - { - assert( false ); - return -1; - } - } - else - { - if( Fs_Hz_in < 8000 || Fs_Hz_in > 48000 || Fs_Hz_out < 8000 || Fs_Hz_out > 48000 ) - { - assert( false ); - return -1; - } - } - - if(Silk_resampler_structs.RESAMPLER_SUPPORT_ABOVE_48KHZ != 0) - { - /* Determine pre downsampling and post upsampling */ - if( Fs_Hz_in > 96000 ) - { - S.nPreDownsamplers = 2; - S.down_pre_function = "SKP_Silk_resampler_private_down4"; - S.downPreCB = new DownPreImplDown4(); - } - else if( Fs_Hz_in > 48000 ) - { - S.nPreDownsamplers = 1; - S.down_pre_function = "SKP_Silk_resampler_down2"; - S.downPreCB = new DownPreImplDown2(); - } - else - { - S.nPreDownsamplers = 0; - S.down_pre_function = null; - S.downPreCB = null; - } - - if( Fs_Hz_out > 96000 ) - { - S.nPostUpsamplers = 2; - S.up_post_function = "SKP_Silk_resampler_private_up4"; - S.upPostCB = new UpPostImplUp4(); - } - else if( Fs_Hz_out > 48000 ) - { - S.nPostUpsamplers = 1; - S.up_post_function = "SKP_Silk_resampler_up2"; - S.upPostCB = new UpPostImplUp2(); - } - else - { - S.nPostUpsamplers = 0; - S.up_post_function = null; - S.upPostCB = null; - } - - if( S.nPreDownsamplers + S.nPostUpsamplers > 0 ) - { - /* Ratio of output/input samples */ - S.ratio_Q16 = ( ( Fs_Hz_out<<13 ) / Fs_Hz_in )<<3; - /* Make sure the ratio is rounded up */ - while( Silk_macros.SKP_SMULWW( S.ratio_Q16, Fs_Hz_in ) < Fs_Hz_out ) - S.ratio_Q16++; - - /* Batch size is 10 ms */ - S.batchSizePrePost = Fs_Hz_in/100 ; - - /* Convert sampling rate to those after pre-downsampling and before post-upsampling */ - Fs_Hz_in = Fs_Hz_in >> S.nPreDownsamplers ; - Fs_Hz_out = Fs_Hz_out >> S.nPostUpsamplers ; - } - } - - /* Number of samples processed per batch */ - /* First, try 10 ms frames */ - S.batchSize = Fs_Hz_in/100; - if( ( S.batchSize*100 != Fs_Hz_in ) || ( Fs_Hz_in % 100 != 0 ) ) - { - /* No integer number of input or output samples with 10 ms frames, use greatest common divisor */ - cycleLen = Fs_Hz_in / gcd( Fs_Hz_in, Fs_Hz_out ); - cyclesPerBatch = Silk_resampler_private.RESAMPLER_MAX_BATCH_SIZE_IN / cycleLen; - if( cyclesPerBatch == 0 ) - { - /* cycleLen too big, let's just use the maximum batch size. Some distortion will result. */ - S.batchSize = Silk_resampler_private.RESAMPLER_MAX_BATCH_SIZE_IN; - assert( false ); - } - else - { - S.batchSize = cyclesPerBatch * cycleLen; - } - } - - /* Find resampler with the right sampling ratio */ - if( Fs_Hz_out > Fs_Hz_in ) - { - /* Upsample */ - if( Fs_Hz_out == Fs_Hz_in * 2 ) - { /* Fs_out : Fs_in = 2 : 1 */ - /* Special case: directly use 2x upsampler */ - S.resampler_function = "SKP_Silk_resampler_private_up2_HQ_wrapper"; - S.resamplerCB = new ResamplerImplWrapper(); - } - else - { - /* Default resampler */ - S.resampler_function = "SKP_Silk_resampler_private_IIR_FIR"; - S.resamplerCB = new ResamplerImplIIRFIR(); - up2 = 1; - if( Fs_Hz_in > 24000 ) - { - /* Low-quality all-pass upsampler */ - S.up2_function = "SKP_Silk_resampler_up2"; - S.up2CB = new Up2ImplUp2(); - - } - else - { - /* High-quality all-pass upsampler */ - S.up2_function = "SKP_Silk_resampler_private_up2_HQ"; - S.up2CB = new Up2ImplHQ(); - - } - } - } - else if ( Fs_Hz_out < Fs_Hz_in ) - { - /* Downsample */ - if( Fs_Hz_out * 4 == Fs_Hz_in * 3 ) - { /* Fs_out : Fs_in = 3 : 4 */ - S.FIR_Fracs = 3; - S.Coefs = Silk_resampler_rom.SKP_Silk_Resampler_3_4_COEFS; - S.resampler_function = "SKP_Silk_resampler_private_down_FIR"; - S.resamplerCB = new ResamplerImplDownFIR(); - } - else if( Fs_Hz_out * 3 == Fs_Hz_in * 2 ) - { /* Fs_out : Fs_in = 2 : 3 */ - S.FIR_Fracs = 2; - S.Coefs = Silk_resampler_rom.SKP_Silk_Resampler_2_3_COEFS; - S.resampler_function = "SKP_Silk_resampler_private_down_FIR"; - S.resamplerCB = new ResamplerImplDownFIR(); - } - else if( Fs_Hz_out * 2 == Fs_Hz_in ) - { /* Fs_out : Fs_in = 1 : 2 */ - S.FIR_Fracs = 1; - S.Coefs = Silk_resampler_rom.SKP_Silk_Resampler_1_2_COEFS; - S.resampler_function = "SKP_Silk_resampler_private_down_FIR"; - S.resamplerCB = new ResamplerImplDownFIR(); - } - else if( Fs_Hz_out * 8 == Fs_Hz_in * 3 ) - { /* Fs_out : Fs_in = 3 : 8 */ - S.FIR_Fracs = 3; - S.Coefs = Silk_resampler_rom.SKP_Silk_Resampler_3_8_COEFS; - S.resampler_function = "SKP_Silk_resampler_private_down_FIR"; - S.resamplerCB = new ResamplerImplDownFIR(); - } - else if( Fs_Hz_out * 3 == Fs_Hz_in ) - { /* Fs_out : Fs_in = 1 : 3 */ - S.FIR_Fracs = 1; - S.Coefs = Silk_resampler_rom.SKP_Silk_Resampler_1_3_COEFS; - S.resampler_function = "SKP_Silk_resampler_private_down_FIR"; - S.resamplerCB = new ResamplerImplDownFIR(); - } - else if( Fs_Hz_out * 4 == Fs_Hz_in ) - { /* Fs_out : Fs_in = 1 : 4 */ - S.FIR_Fracs = 1; - down2 = 1; - S.Coefs = Silk_resampler_rom.SKP_Silk_Resampler_1_2_COEFS; - S.resampler_function = "SKP_Silk_resampler_private_down_FIR"; - S.resamplerCB = new ResamplerImplDownFIR(); - } - else if( Fs_Hz_out * 6 == Fs_Hz_in ) - { /* Fs_out : Fs_in = 1 : 6 */ - S.FIR_Fracs = 1; - down2 = 1; - S.Coefs = Silk_resampler_rom.SKP_Silk_Resampler_1_3_COEFS; - S.resampler_function = "SKP_Silk_resampler_private_down_FIR"; - S.resamplerCB = new ResamplerImplDownFIR(); - } - else if( Fs_Hz_out * 441 == Fs_Hz_in * 80 ) - { /* Fs_out : Fs_in = 80 : 441 */ - S.Coefs = Silk_resampler_rom.SKP_Silk_Resampler_80_441_ARMA4_COEFS; - S.resampler_function = "SKP_Silk_resampler_private_IIR_FIR"; - S.resamplerCB = new ResamplerImplIIRFIR(); - } - else if( Fs_Hz_out * 441 == Fs_Hz_in * 120 ) - { /* Fs_out : Fs_in = 120 : 441 */ - S.Coefs = Silk_resampler_rom.SKP_Silk_Resampler_120_441_ARMA4_COEFS; - S.resampler_function = "SKP_Silk_resampler_private_IIR_FIR"; - S.resamplerCB = new ResamplerImplIIRFIR(); - } - else if( Fs_Hz_out * 441 == Fs_Hz_in * 160 ) - { /* Fs_out : Fs_in = 160 : 441 */ - S.Coefs = Silk_resampler_rom.SKP_Silk_Resampler_160_441_ARMA4_COEFS; - S.resampler_function = "SKP_Silk_resampler_private_IIR_FIR"; - S.resamplerCB = new ResamplerImplIIRFIR(); - } - else if( Fs_Hz_out * 441 == Fs_Hz_in * 240 ) - { /* Fs_out : Fs_in = 240 : 441 */ - S.Coefs = Silk_resampler_rom.SKP_Silk_Resampler_240_441_ARMA4_COEFS; - S.resampler_function = "SKP_Silk_resampler_private_IIR_FIR"; - S.resamplerCB = new ResamplerImplIIRFIR(); - } - else if( Fs_Hz_out * 441 == Fs_Hz_in * 320 ) - { /* Fs_out : Fs_in = 320 : 441 */ - S.Coefs = Silk_resampler_rom.SKP_Silk_Resampler_320_441_ARMA4_COEFS; - S.resampler_function = "SKP_Silk_resampler_private_IIR_FIR"; - S.resamplerCB = new ResamplerImplIIRFIR(); - } - else - { - /* Default resampler */ - S.resampler_function = "SKP_Silk_resampler_private_IIR_FIR"; - S.resamplerCB = new ResamplerImplIIRFIR(); - up2 = 1; - if( Fs_Hz_in > 24000 ) - { - /* Low-quality all-pass upsampler */ - S.up2_function = "SKP_Silk_resampler_up2"; - S.up2CB = new Up2ImplUp2(); - } - else - { - /* High-quality all-pass upsampler */ - S.up2_function = "SKP_Silk_resampler_private_up2_HQ"; - S.up2CB = new Up2ImplHQ(); - } - } - } - else - { - /* Input and output sampling rates are equal: copy */ - S.resampler_function = "SKP_Silk_resampler_private_copy"; - S.resamplerCB = new ResamplerImplCopy(); - } - - S.input2x = up2 | down2; - - /* Ratio of input/output samples */ - S.invRatio_Q16 = ( ( Fs_Hz_in << 14 + up2 - down2 ) / Fs_Hz_out ) << 2 ; - /* Make sure the ratio is rounded up */ - while( Silk_macros.SKP_SMULWW( S.invRatio_Q16, Fs_Hz_out << down2 ) < ( Fs_Hz_in << up2 ) ) - { - S.invRatio_Q16++; - } - - S.magic_number = 123456789; - - return 0; - } - - /** - * Clear the states of all resampling filters, without resetting sampling rate ratio. - * @param S Resampler state. - * @return - */ - static int SKP_Silk_resampler_clear( - SKP_Silk_resampler_state_struct S /* I/O: Resampler state */ - ) - { - Arrays.fill(S.sDown2, 0); - Arrays.fill(S.sIIR, 0); - Arrays.fill(S.sFIR, 0); - if (Silk_resampler_structs.RESAMPLER_SUPPORT_ABOVE_48KHZ != 0) - { - Arrays.fill(S.sDownPre, 0); - Arrays.fill(S.sUpPost, 0); - } - return 0; - } - - /** - * Resampler: convert from one sampling rate to another. - * @param S Resampler state. - * @param out Output signal. - * @param out_offset offset of vaild data. - * @param in Input signal. - * @param in_offset offset of valid data. - * @param inLen Number of input samples - * @return - */ - static int SKP_Silk_resampler( - SKP_Silk_resampler_state_struct S, /* I/O: Resampler state */ - short[] out, /* O: Output signal */ - int out_offset, - short[] in, /* I: Input signal */ - int in_offset, - int inLen /* I: Number of input samples */ - ) - { - /* Verify that state was initialized and has not been corrupted */ - if( S.magic_number != 123456789 ) - { - assert( false ); - return -1; - } - - if (Silk_resampler_structs.RESAMPLER_SUPPORT_ABOVE_48KHZ != 0) - { - if( S.nPreDownsamplers + S.nPostUpsamplers > 0 ) { - /* The input and/or output sampling rate is above 48000 Hz */ - int nSamplesIn, nSamplesOut; - short[] in_buf = new short[ 480 ]; - short[] out_buf = new short[ 480 ]; - - while( inLen > 0 ) { - /* Number of input and output samples to process */ - nSamplesIn = Silk_SigProc_FIX.SKP_min( inLen, S.batchSizePrePost ); - nSamplesOut = Silk_macros.SKP_SMULWB( S.ratio_Q16, nSamplesIn ); - - Silk_typedef.SKP_assert( ( nSamplesIn >> S.nPreDownsamplers ) <= 480 ); - Silk_typedef.SKP_assert( ( nSamplesOut >> S.nPostUpsamplers ) <= 480 ); - - if( S.nPreDownsamplers > 0 ) { - S.down_pre_function(S.sDownPre, in_buf, 0, in, in_offset, nSamplesIn); - - if( S.nPostUpsamplers > 0 ) { - S.resampler_function(S, out_buf, 0, in_buf, 0, ( nSamplesIn >> S.nPreDownsamplers )); - S.up_post_function(S.sUpPost, out, out_offset, out_buf, 0, ( nSamplesOut >> S.nPostUpsamplers )); - } else { - S.resampler_function( S, out, out_offset, in_buf, 0, ( nSamplesIn >> S.nPreDownsamplers )); - } - } else { - S.resampler_function( S, out_buf, 0, in, in_offset, ( nSamplesIn >> S.nPreDownsamplers )); - S.up_post_function( S.sUpPost, out, out_offset, out_buf, 0, ( nSamplesOut >> S.nPostUpsamplers )); - } - - in_offset += nSamplesIn; - out_offset += nSamplesOut; - inLen -= nSamplesIn; - } - } else { - /* Input and output sampling rate are at most 48000 Hz */ - S.resampler_function( S, out, out_offset, in, in_offset, inLen); - } - } - else{ - /* Input and output sampling rate are at most 48000 Hz */ - S.resampler_function( S, out, out_offset, in, in_offset, inLen); - } - return 0; - } -} -/*************************************************************************************/ -class DownPreImplDown4 implements DownPreFP -{ - public void down_pre_function(int[] state, short[] out, int outOffset, - short[] in, int inOffset, int len) { - Silk_resampler_private_down4.SKP_Silk_resampler_private_down4(state, 0, - out, outOffset, in, inOffset, len); - } -} -class DownPreImplDown2 implements DownPreFP -{ - public void down_pre_function(int[] state, short[] out, int outOffset, - short[] in, int inOffset, int len) { - Silk_resampler_down2.SKP_Silk_resampler_down2(state, 0, - out, outOffset, in, inOffset, len); - } -} -/*----------------------------------------------------------------*/ -class UpPostImplUp4 implements UpPostFP -{ - public void up_post_function(int[] state, short[] out, int outOffset, - short[] in, int inOffset, int len) { - Silk_resampler_private_up4.SKP_Silk_resampler_private_up4(state, 0, - out, outOffset, in, inOffset, len); - } - -} -class UpPostImplUp2 implements UpPostFP -{ - public void up_post_function(int[] state, short[] out, int outOffset, - short[] in, int inOffset, int len) { - Silk_resampler_up2.SKP_Silk_resampler_up2(state, 0, - out, outOffset, in, inOffset, len); - } -} -/*----------------------------------------------------------------*/ -class ResamplerImplWrapper implements ResamplerFP -{ - public void resampler_function(Object state, short[] out, int outOffset, - short[] in, int inOffset, int len) { - Silk_resampler_private_up2_HQ.SKP_Silk_resampler_private_up2_HQ_wrapper(state, - out, outOffset, in, inOffset, len); - } -} -class ResamplerImplIIRFIR implements ResamplerFP -{ - public void resampler_function(Object state, short[] out, int outOffset, - short[] in, int inOffset, int len) { - Silk_resampler_private_IIR_FIR.SKP_Silk_resampler_private_IIR_FIR(state, - out, outOffset, in, inOffset, len); - } -} -class ResamplerImplDownFIR implements ResamplerFP -{ - public void resampler_function(Object state, short[] out, int outOffset, - short[] in, int inOffset, int len) { - Silk_resampler_private_down_FIR.SKP_Silk_resampler_private_down_FIR(state, - out, outOffset, in, inOffset, len); - } -} -class ResamplerImplCopy implements ResamplerFP -{ - public void resampler_function(Object state, short[] out, int outOffset, - short[] in, int inOffset, int len) { - Silk_resampler_private_copy.SKP_Silk_resampler_private_copy(state, out, outOffset, in, inOffset, len); - } - -} -/*----------------------------------------------------------------*/ -class Up2ImplUp2 implements Up2FP -{ - public void up2_function(int[] state, short[] out, int outOffset, - short[] in, int inOffset, int len) { - Silk_resampler_up2.SKP_Silk_resampler_up2(state, 0, - out, outOffset, in, inOffset, len); - } -} -class Up2ImplHQ implements Up2FP -{ - public void up2_function(int[] state, short[] out, int outOffset, - short[] in, int inOffset, int len) { - Silk_resampler_private_up2_HQ.SKP_Silk_resampler_private_up2_HQ(state, 0, - out, outOffset, in, inOffset, len); - } - -} -/*************************************************************************************/ diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_down2.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_down2.java deleted file mode 100644 index 05b33f535..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_down2.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Downsample by a factor 2, mediocre quality. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_resampler_down2 -{ - /** - * Downsample by a factor 2, mediocre quality. - * @param S State vector [ 2 ]. - * @param S_offset offset of valid data. - * @param out Output signal [ len ]. - * @param out_offset offset of valid data. - * @param in Input signal [ floor(len/2) ]. - * @param in_offset offset of valid data. - * @param inLen Number of input samples. - */ - static void SKP_Silk_resampler_down2( - int[] S, /* I/O: State vector [ 2 ] */ - int S_offset, - short[] out, /* O: Output signal [ len ] */ - int out_offset, - short[] in, /* I: Input signal [ floor(len/2) ] */ - int in_offset, - int inLen /* I: Number of input samples */ - ) - { - int k, len2 = inLen>>1; - int in32, out32, Y, X; - - assert( Silk_resampler_rom.SKP_Silk_resampler_down2_0 > 0 ); - assert( Silk_resampler_rom.SKP_Silk_resampler_down2_1 < 0 ); - - /* Internal variables and state are in Q10 format */ - for( k = 0; k < len2; k++ ) { - /* Convert to Q10 */ - in32 = in[ in_offset + 2 * k ] << 10; - - /* All-pass section for even input sample */ - Y = in32 - S[ S_offset ]; - X = Silk_macros.SKP_SMLAWB( Y, Y, Silk_resampler_rom.SKP_Silk_resampler_down2_1 ); - out32 = S[ S_offset ] + X; - S[ S_offset ] = in32 + X; - - /* Convert to Q10 */ - in32 = in[ in_offset + 2 * k + 1 ] << 10; - - /* All-pass section for odd input sample, and add to output of previous section */ - Y = in32 - S[ S_offset+1 ]; - X = Silk_macros.SKP_SMULWB( Y, Silk_resampler_rom.SKP_Silk_resampler_down2_0 ); - out32 = out32 + S[ S_offset+1 ]; - out32 = out32 + X; - S[ S_offset+1 ] = in32 + X; - - /* Add, convert back to int16 and store to output */ - out[ out_offset + k ] = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( out32, 11 ) ); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_down2_3.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_down2_3.java deleted file mode 100644 index 5caeaa464..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_down2_3.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Downsample by a factor 2/3, low quality. - * - * @author Jing Dai. - * @author Dingxin Xu - */ -public class Silk_resampler_down2_3 -{ - static final int ORDER_FIR = 4; - - /** - * Downsample by a factor 2/3, low quality. - * @param S State vector [ 6 ] - * @param S_offset offset of valid data. - * @param out Output signal [ floor(2*inLen/3) ] - * @param out_offset offset of valid data. - * @param in Input signal [ inLen ] - * @param in_offset offset of valid data. - * @param inLen Number of input samples - */ - static void SKP_Silk_resampler_down2_3( - int[] S, /* I/O: State vector [ 6 ] */ - int S_offset, - short[] out, /* O: Output signal [ floor(2*inLen/3) ] */ - int out_offset, - short[] in, /* I: Input signal [ inLen ] */ - int in_offset, - int inLen /* I: Number of input samples */ - ) - { - int nSamplesIn, counter, res_Q6; - int[] buf = new int[ Silk_resampler_private.RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR ]; - int buf_ptr; - - /* Copy buffered samples to start of buffer */ - for(int i_djinn=0; i_djinn 2 ) - { - /* Inner product */ - res_Q6 = Silk_macros.SKP_SMULWB( buf[ buf_ptr ], Silk_resampler_rom.SKP_Silk_Resampler_2_3_COEFS_LQ[ 2 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf[ buf_ptr+1 ], Silk_resampler_rom.SKP_Silk_Resampler_2_3_COEFS_LQ[ 3 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf[ buf_ptr+2 ], Silk_resampler_rom.SKP_Silk_Resampler_2_3_COEFS_LQ[ 5 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf[ buf_ptr+3 ], Silk_resampler_rom.SKP_Silk_Resampler_2_3_COEFS_LQ[ 4 ] ); - - /* Scale down, saturate and store in output array */ - out[out_offset++] = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( res_Q6, 6 ) ); - - res_Q6 = Silk_macros.SKP_SMULWB( buf[ buf_ptr+1 ], Silk_resampler_rom.SKP_Silk_Resampler_2_3_COEFS_LQ[ 4 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf[ buf_ptr+2 ], Silk_resampler_rom.SKP_Silk_Resampler_2_3_COEFS_LQ[ 5 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf[ buf_ptr+3 ], Silk_resampler_rom.SKP_Silk_Resampler_2_3_COEFS_LQ[ 3 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf[ buf_ptr+4 ], Silk_resampler_rom.SKP_Silk_Resampler_2_3_COEFS_LQ[ 2 ] ); - - /* Scale down, saturate and store in output array */ - out[out_offset++] = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( res_Q6, 6 ) ); - - buf_ptr += 3; - counter -= 3; - } - - in_offset += nSamplesIn; - inLen -= nSamplesIn; - - if( inLen > 0 ) - { - /* More iterations to do; copy last part of filtered signal to beginning of buffer */ - for(int i_djinn=0; i_djinn 2 ) - { - /* Inner product */ - res_Q6 = Silk_macros.SKP_SMULWB( buf[ buf_ptr ] + buf[ buf_ptr+5 ], Silk_resampler_rom.SKP_Silk_Resampler_1_3_COEFS_LQ[ 2 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf[ buf_ptr+1 ] + buf[ buf_ptr+4 ], Silk_resampler_rom.SKP_Silk_Resampler_1_3_COEFS_LQ[ 3 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf[ buf_ptr+2 ] + buf[ buf_ptr+3 ], Silk_resampler_rom.SKP_Silk_Resampler_1_3_COEFS_LQ[ 4 ] ); - - /* Scale down, saturate and store in output array */ - out[out_offset++] = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( res_Q6, 6 ) ); - - buf_ptr += 3; - counter -= 3; - } - - in_offset += nSamplesIn; - inLen -= nSamplesIn; - - if( inLen > 0 ) - { - /* More iterations to do; copy last part of filtered signal to beginning of buffer */ - for(int i_djinn=0; i_djinn> 2, out1_Q8, Coef[ Coef_offset+3 ] ); - S[ S_offset+3 ] = Silk_macros.SKP_SMLAWB( out1_Q8 >> 2 , out2_Q8, Coef[ Coef_offset+5 ] ); - - /* Apply gain and store to output. The coefficient is in Q16 */ - out[ out_offset+k ] = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_macros.SKP_SMLAWB( 128, out2_Q8, Coef[ Coef_offset+6 ] ) >> 8 ); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_IIR_FIR.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_IIR_FIR.java deleted file mode 100644 index 03ee46d73..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_IIR_FIR.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Upsample using a combination of allpass-based 2x upsampling and FIR interpolation. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_resampler_private_IIR_FIR -{ - /** - * Upsample using a combination of allpass-based 2x upsampling and FIR interpolation. - * @param SS Resampler state. - * @param out Output signal. - * @param out_offset offset of valid data. - * @param in Input signal. - * @param in_offset offset of valid data. - * @param inLen Number of input samples. - */ - static void SKP_Silk_resampler_private_IIR_FIR( - Object SS, /* I/O: Resampler state */ - short[] out, /* O: Output signal */ - int out_offset, - short[] in, /* I: Input signal */ - int in_offset, - int inLen /* I: Number of input samples */ - ) - { - SKP_Silk_resampler_state_struct S = (SKP_Silk_resampler_state_struct )SS; - - int nSamplesIn, table_index; - int max_index_Q16, index_Q16, index_increment_Q16, res_Q15; - short[] buf = new short[ 2 * Silk_resampler_private.RESAMPLER_MAX_BATCH_SIZE_IN + Silk_resampler_rom.RESAMPLER_ORDER_FIR_144 ]; - int buf_ptr; - - /* Copy buffered samples to start of buffer */ -//TODO:litter-endian or big-endian??? -// SKP_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_144 * sizeof( SKP_int32 ) ); - for(int i_djinn=0; i_djinn>>16); -// buf[2*i_djinn+1] = (short)(S.sFIR[i_djinn]&0x0000FFFF); -//littel-endian - buf[2*i_djinn] = (short)(S.sFIR[i_djinn]&0x0000FFFF); - buf[2*i_djinn+1] = (short)(S.sFIR[i_djinn]>>>16); - } - - /* Iterate over blocks of frameSizeIn input samples */ - index_increment_Q16 = S.invRatio_Q16; - while( true ) - { - nSamplesIn = Math.min( inLen, S.batchSize ); - - if( S.input2x == 1 ) - { - /* Upsample 2x */ - S.up2_function(S.sIIR, buf, Silk_resampler_rom.RESAMPLER_ORDER_FIR_144, in, in_offset, nSamplesIn); - } - else - { - /* Fourth-order ARMA filter */ - Silk_resampler_private_ARMA4.SKP_Silk_resampler_private_ARMA4( S.sIIR,0, buf,Silk_resampler_rom.RESAMPLER_ORDER_FIR_144, in,in_offset, S.Coefs,0, nSamplesIn ); - } - - max_index_Q16 = nSamplesIn << ( 16 + S.input2x ); /* +1 if 2x upsampling */ - - /* Interpolate upsampled signal and store in output array */ - for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) - { - table_index = Silk_macros.SKP_SMULWB( index_Q16 & 0xFFFF, 144 ); - buf_ptr = index_Q16 >> 16; - res_Q15 = Silk_macros.SKP_SMULBB( buf[ buf_ptr ], Silk_resampler_rom.SKP_Silk_resampler_frac_FIR_144[ table_index ][ 0 ] ); - res_Q15 = Silk_macros.SKP_SMLABB( res_Q15, buf[ buf_ptr+1 ], Silk_resampler_rom.SKP_Silk_resampler_frac_FIR_144[ table_index ][ 1 ] ); - res_Q15 = Silk_macros.SKP_SMLABB( res_Q15, buf[ buf_ptr+2 ], Silk_resampler_rom.SKP_Silk_resampler_frac_FIR_144[ table_index ][ 2 ] ); - res_Q15 = Silk_macros.SKP_SMLABB( res_Q15, buf[ buf_ptr+3 ], Silk_resampler_rom.SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 2 ] ); - res_Q15 = Silk_macros.SKP_SMLABB( res_Q15, buf[ buf_ptr+4 ], Silk_resampler_rom.SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 1 ] ); - res_Q15 = Silk_macros.SKP_SMLABB( res_Q15, buf[ buf_ptr+5 ], Silk_resampler_rom.SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 0 ] ); - out[out_offset++] = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( res_Q15, 15 ) ); - } - in_offset += nSamplesIn; - inLen -= nSamplesIn; - - if( inLen > 0 ) - { - /* More iterations to do; copy last part of filtered signal to beginning of buffer */ -//TODO:litter-endian or big-endian??? -// SKP_memcpy( buf, &buf[ nSamplesIn << S->input2x ], RESAMPLER_ORDER_FIR_144 * sizeof( SKP_int32 ) ); - for(int i_djinn=0; i_djinnsFIR, &buf[nSamplesIn << S->input2x ], RESAMPLER_ORDER_FIR_144 * sizeof( SKP_int32 ) ); - for(int i_djinn=0; i_djinn>8)&0xFF)<<8)&0x0000FF00; - S.sFIR[i_djinn] |= (((buf[(nSamplesIn << S.input2x) + 2*i_djinn + 1]>>0)&0xFF)<<16)&0x00FF0000; - S.sFIR[i_djinn] |= (((buf[(nSamplesIn << S.input2x) + 2*i_djinn + 1 ]>>8)&0xFF)<<24)&0xFF000000; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_copy.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_copy.java deleted file mode 100644 index ee723e3ce..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_copy.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Simple opy. - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_resampler_private_copy -{ - /** - * Simple copy. - * @param SS Resampler state (unused). - * @param out Output signal - * @param out_offset offset of valid data. - * @param in Input signal - * @param in_offset offset of valid data. - * @param inLen Number of input samples - */ - static void SKP_Silk_resampler_private_copy( - Object SS, /* I/O: Resampler state (unused) */ - short[] out, /* O: Output signal */ - int out_offset, - short[] in, /* I: Input signal */ - int in_offset, - int inLen /* I: Number of input samples */ - ) - { - for(int k=0; k> 2; - int in32, out32, Y, X; - - assert( Silk_resampler_rom.SKP_Silk_resampler_down2_0 > 0 ); - assert( Silk_resampler_rom.SKP_Silk_resampler_down2_1 < 0 ); - - /* Internal variables and state are in Q10 format */ - for( k = 0; k < len4; k++ ) - { - /* Add two input samples and convert to Q10 */ - in32 = ( in[ in_offset + 4 * k ] + in[ in_offset + 4 * k + 1 ] ) << 9 ; - - /* All-pass section for even input sample */ - Y = in32 - S[ S_offset ]; - X = Silk_macros.SKP_SMLAWB( Y, Y, Silk_resampler_rom.SKP_Silk_resampler_down2_1 ); - out32 = S[ S_offset ] + X; - S[ S_offset ] = in32 + X; - - /* Add two input samples and convert to Q10 */ - in32 = ( in[ in_offset + 4 * k + 2 ] + in[ in_offset + 4 * k + 3 ] ) << 9; - - /* All-pass section for odd input sample */ - Y = in32 - S[ S_offset+1 ]; - X = Silk_macros.SKP_SMULWB( Y, Silk_resampler_rom.SKP_Silk_resampler_down2_0 ); - out32 = out32 + S[ S_offset+1 ]; - out32 = out32 + X; - S[ S_offset+1 ] = in32 + X; - - /* Add, convert back to int16 and store to output */ - out[ out_offset+k ] = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( out32, 11 ) ); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_down_FIR.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_down_FIR.java deleted file mode 100644 index 50b7713ea..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_down_FIR.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Resample with a 2x downsampler (optional), a 2nd order AR filter followed by FIR interpolation. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_resampler_private_down_FIR -{ - /** - * Resample with a 2x downsampler (optional), - * a 2nd order AR filter followed by FIR interpolation. - * @param SS Resampler state. - * @param out Output signal. - * @param out_offset offset of valid data. - * @param in Input signal. - * @param in_offset offset of valid data. - * @param inLen Number of input samples. - */ - static void SKP_Silk_resampler_private_down_FIR( - Object SS, /* I/O: Resampler state */ - short[] out, /* O: Output signal */ - int out_offset, - short[] in, /* I: Input signal */ - int in_offset, - int inLen /* I: Number of input samples */ - ) - { - SKP_Silk_resampler_state_struct S = (SKP_Silk_resampler_state_struct)SS; - int nSamplesIn, interpol_ind; - int max_index_Q16, index_Q16, index_increment_Q16, res_Q6; - short[] buf1 = new short[ Silk_resampler_private.RESAMPLER_MAX_BATCH_SIZE_IN / 2 ]; - int[] buf2 = new int[ Silk_resampler_private.RESAMPLER_MAX_BATCH_SIZE_IN + Silk_resampler_rom.RESAMPLER_DOWN_ORDER_FIR ]; - int[] buf_ptr; - int buf_ptr_offset; - short[] interpol_ptr, FIR_Coefs; - int interpol_ptr_offset, FIR_Coefs_offset; - - /* Copy buffered samples to start of buffer */ -//TODO: arrayCopy(); -// SKP_memcpy( buf2, S->sFIR, RESAMPLER_DOWN_ORDER_FIR * sizeof( SKP_int32 ) ); - for(int i_djinn=0; i_djinn> 1; - - /* Second-order AR filter (output in Q8) */ - Silk_resampler_private_AR2.SKP_Silk_resampler_private_AR2( S.sIIR,0, buf2,Silk_resampler_rom.RESAMPLER_DOWN_ORDER_FIR, buf1,0, S.Coefs,0, nSamplesIn ); - } - else - { - /* Second-order AR filter (output in Q8) */ - Silk_resampler_private_AR2.SKP_Silk_resampler_private_AR2( S.sIIR,0, buf2,Silk_resampler_rom.RESAMPLER_DOWN_ORDER_FIR, in,in_offset, S.Coefs,0, nSamplesIn ); - } - - max_index_Q16 = nSamplesIn << 16; - - /* Interpolate filtered signal */ - if( S.FIR_Fracs == 1 ) - { - for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) - { - /* Integer part gives pointer to buffered input */ - buf_ptr = buf2; - buf_ptr_offset = index_Q16 >> 16; - - /* Inner product */ - res_Q6 = Silk_macros.SKP_SMULWB( buf_ptr[ buf_ptr_offset ]+buf_ptr[ buf_ptr_offset+11 ], FIR_Coefs[ FIR_Coefs_offset ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf_ptr[ buf_ptr_offset+1 ]+buf_ptr[ buf_ptr_offset+10 ], FIR_Coefs[ FIR_Coefs_offset+1 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf_ptr[ buf_ptr_offset+2 ]+buf_ptr[ buf_ptr_offset+9 ], FIR_Coefs[ FIR_Coefs_offset+2 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf_ptr[ buf_ptr_offset+3 ]+buf_ptr[ buf_ptr_offset+8 ], FIR_Coefs[ FIR_Coefs_offset+3 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf_ptr[ buf_ptr_offset+4 ]+buf_ptr[ buf_ptr_offset+7 ], FIR_Coefs[ FIR_Coefs_offset+4 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf_ptr[ buf_ptr_offset+5 ]+buf_ptr[ buf_ptr_offset+6 ], FIR_Coefs[ FIR_Coefs_offset+5 ] ); - - /* Scale down, saturate and store in output array */ - out[out_offset++] = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( res_Q6, 6 ) ); - } - } - else - { - for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) - { - /* Integer part gives pointer to buffered input */ - buf_ptr = buf2; - buf_ptr_offset = index_Q16 >> 16; - - /* Fractional part gives interpolation coefficients */ - interpol_ind = Silk_macros.SKP_SMULWB( index_Q16 & 0xFFFF, S.FIR_Fracs ); - - /* Inner product */ - interpol_ptr = FIR_Coefs; -//BugFix interpol_ptr_offset = Silk_resampler_rom.RESAMPLER_DOWN_ORDER_FIR / 2 * interpol_ind; - interpol_ptr_offset = FIR_Coefs_offset + Silk_resampler_rom.RESAMPLER_DOWN_ORDER_FIR / 2 * interpol_ind; - res_Q6 = Silk_macros.SKP_SMULWB( buf_ptr[ buf_ptr_offset ], interpol_ptr[ interpol_ptr_offset ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf_ptr[ buf_ptr_offset+1 ], interpol_ptr[ interpol_ptr_offset+1 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf_ptr[ buf_ptr_offset+2 ], interpol_ptr[ interpol_ptr_offset+2 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf_ptr[ buf_ptr_offset+3 ], interpol_ptr[ interpol_ptr_offset+3 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf_ptr[ buf_ptr_offset+4 ], interpol_ptr[ interpol_ptr_offset+4 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf_ptr[ buf_ptr_offset+5 ], interpol_ptr[ interpol_ptr_offset+5 ] ); - interpol_ptr = FIR_Coefs; -//BugFix interpol_ptr_offset = Silk_resampler_rom.RESAMPLER_DOWN_ORDER_FIR / 2 * ( S.FIR_Fracs - 1 - interpol_ind ); - interpol_ptr_offset = FIR_Coefs_offset + Silk_resampler_rom.RESAMPLER_DOWN_ORDER_FIR / 2 * ( S.FIR_Fracs - 1 - interpol_ind ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf_ptr[ buf_ptr_offset+11 ], interpol_ptr[ interpol_ptr_offset ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf_ptr[ buf_ptr_offset+10 ], interpol_ptr[ interpol_ptr_offset+1 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf_ptr[ buf_ptr_offset+9 ], interpol_ptr[ interpol_ptr_offset+2 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf_ptr[ buf_ptr_offset+8 ], interpol_ptr[ interpol_ptr_offset+3 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf_ptr[ buf_ptr_offset+7 ], interpol_ptr[ interpol_ptr_offset+4 ] ); - res_Q6 = Silk_macros.SKP_SMLAWB( res_Q6, buf_ptr[ buf_ptr_offset+6 ], interpol_ptr[ interpol_ptr_offset+5 ] ); - - /* Scale down, saturate and store in output array */ - out[out_offset++] = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( res_Q6, 6 ) ); - } - } - - in_offset += nSamplesIn << S.input2x; - inLen -= nSamplesIn << S.input2x; - - if( inLen > S.input2x ) - { - /* More iterations to do; copy last part of filtered signal to beginning of buffer */ -//TODO: arrayCopy(); -// SKP_memcpy( buf2, &buf2[ nSamplesIn ], RESAMPLER_DOWN_ORDER_FIR * sizeof( SKP_int32 ) ); - for(int i_djinn=0; i_djinnsFIR, &buf2[ nSamplesIn ], RESAMPLER_DOWN_ORDER_FIR * sizeof( SKP_int32 ) ); - for(int i_djinn=0; i_djinn 0 ); - assert( Silk_resampler_rom.SKP_Silk_resampler_up2_hq_0[ 1 ] < 0 ); - assert( Silk_resampler_rom.SKP_Silk_resampler_up2_hq_1[ 0 ] > 0 ); - assert( Silk_resampler_rom.SKP_Silk_resampler_up2_hq_1[ 1 ] < 0 ); - - /* Internal variables and state are in Q10 format */ - for( k = 0; k < len; k++ ) - { - /* Convert to Q10 */ - in32 = in[ in_offset+k ] << 10; - - /* First all-pass section for even output sample */ - Y = in32 - S[ S_offset ]; - X = Silk_macros.SKP_SMULWB( Y, Silk_resampler_rom.SKP_Silk_resampler_up2_hq_0[ 0 ] ); - out32_1 = S[ S_offset ] + X; - S[ S_offset ] = in32 + X; - - /* Second all-pass section for even output sample */ - Y = out32_1 - S[ S_offset+1 ]; - X = Silk_macros.SKP_SMLAWB( Y, Y, Silk_resampler_rom.SKP_Silk_resampler_up2_hq_0[ 1 ] ); - out32_2 = S[ S_offset+1 ] + X; - S[ S_offset+1 ] = out32_1 + X; - - /* Biquad notch filter */ - out32_2 = Silk_macros.SKP_SMLAWB( out32_2, S[ S_offset+5 ], Silk_resampler_rom.SKP_Silk_resampler_up2_hq_notch[ 2 ] ); - out32_2 = Silk_macros.SKP_SMLAWB( out32_2, S[ S_offset+4 ], Silk_resampler_rom.SKP_Silk_resampler_up2_hq_notch[ 1 ] ); - out32_1 = Silk_macros.SKP_SMLAWB( out32_2, S[ S_offset+4 ], Silk_resampler_rom.SKP_Silk_resampler_up2_hq_notch[ 0 ] ); - S[ S_offset+5 ] = out32_2 - S[ S_offset+5 ]; - - /* Apply gain in Q15, convert back to int16 and store to output */ - out[ out_offset + 2 * k ] = (short)Silk_SigProc_FIX.SKP_SAT16( - Silk_macros.SKP_SMLAWB( 256, out32_1, Silk_resampler_rom.SKP_Silk_resampler_up2_hq_notch[ 3 ] ) >> 9 ); - - /* First all-pass section for odd output sample */ - Y = in32 - S[ S_offset+2 ]; - X = Silk_macros.SKP_SMULWB( Y, Silk_resampler_rom.SKP_Silk_resampler_up2_hq_1[ 0 ] ); - out32_1 = S[ S_offset+2 ] + X; - S[ S_offset+2 ] = in32 + X; - - /* Second all-pass section for odd output sample */ - Y = out32_1 - S[ S_offset+3 ]; - X = Silk_macros.SKP_SMLAWB( Y, Y, Silk_resampler_rom.SKP_Silk_resampler_up2_hq_1[ 1 ] ); - out32_2 = S[ S_offset+3 ] + X; - S[ S_offset+3 ] = out32_1 + X; - - /* Biquad notch filter */ - out32_2 = Silk_macros.SKP_SMLAWB( out32_2, S[ S_offset+4 ], Silk_resampler_rom.SKP_Silk_resampler_up2_hq_notch[ 2 ] ); - out32_2 = Silk_macros.SKP_SMLAWB( out32_2, S[ S_offset+5 ], Silk_resampler_rom.SKP_Silk_resampler_up2_hq_notch[ 1 ] ); - out32_1 = Silk_macros.SKP_SMLAWB( out32_2, S[ S_offset+5 ], Silk_resampler_rom.SKP_Silk_resampler_up2_hq_notch[ 0 ] ); - S[ S_offset+4 ] = out32_2 - S[ S_offset+4 ]; - - /* Apply gain in Q15, convert back to int16 and store to output */ - out[ out_offset + 2 * k + 1 ] = (short)Silk_SigProc_FIX.SKP_SAT16( - Silk_macros.SKP_SMLAWB( 256, out32_1, Silk_resampler_rom.SKP_Silk_resampler_up2_hq_notch[ 3 ] ) >> 9 ); - } - } - - /** - * the wrapper method. - * @param SS Resampler state (unused). - * @param out Output signal [ 2 * len ]. - * @param out_offset offset of valid data. - * @param in Input signal [ len ]. - * @param in_offset offset of valid data. - * @param len Number of input samples. - */ - static void SKP_Silk_resampler_private_up2_HQ_wrapper( - Object SS, /* I/O: Resampler state (unused) */ - short[] out, /* O: Output signal [ 2 * len ] */ - int out_offset, - short[] in, /* I: Input signal [ len ] */ - int in_offset, - int len /* I: Number of input samples */ - ) - { - SKP_Silk_resampler_state_struct S = (SKP_Silk_resampler_state_struct )SS; - SKP_Silk_resampler_private_up2_HQ( S.sIIR,0, out,out_offset, in,in_offset, len ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_up4.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_up4.java deleted file mode 100644 index f4a41d11b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_private_up4.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Upsample by a factor 4. - * Note: very low quality, only use with output sampling rates above 96 kHz. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_resampler_private_up4 -{ - /** - * Upsample by a factor 4. - * Note: very low quality, only use with output sampling rates above 96 kHz. - * @param S State vector [ 2 ]. - * @param S_offset offset of valid data. - * @param out Output signal [ 4 * len ]. - * @param out_offset offset of valid data. - * @param in Input signal [ len ]. - * @param in_offset offset of valid data. - * @param len Number of INPUT samples. - */ - static void SKP_Silk_resampler_private_up4( - int[] S, /* I/O: State vector [ 2 ] */ - int S_offset, - short[] out, /* O: Output signal [ 4 * len ] */ - int out_offset, - short[] in, /* I: Input signal [ len ] */ - int in_offset, - int len /* I: Number of INPUT samples */ - ) - { - int k; - int in32, out32, Y, X; - int out16; - - assert( Silk_resampler_rom.SKP_Silk_resampler_up2_lq_0 > 0 ); - assert( Silk_resampler_rom.SKP_Silk_resampler_up2_lq_1 < 0 ); - - /* Internal variables and state are in Q10 format */ - for( k = 0; k < len; k++ ) - { - /* Convert to Q10 */ - in32 = in[ in_offset+k ] << 10; - - /* All-pass section for even output sample */ - Y = in32 - S[ S_offset + 0 ]; - X = Silk_macros.SKP_SMULWB( Y, Silk_resampler_rom.SKP_Silk_resampler_up2_lq_0 ); - out32 = S[ S_offset + 0 ] + X; - S[ S_offset + 0 ] = in32 + X; - - /* Convert back to int16 and store to output */ - out16 = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( out32, 10 ) ); - out[ out_offset + 4 * k ] = (short)out16; - out[ out_offset + 4 * k + 1 ] = (short)out16; - - /* All-pass section for odd output sample */ - Y = in32 - S[ S_offset + 1 ]; - X = Silk_macros.SKP_SMLAWB( Y, Y, Silk_resampler_rom.SKP_Silk_resampler_up2_lq_1 ); - out32 = S[ S_offset + 1 ] + X; - S[ S_offset + 1 ] = in32 + X; - - /* Convert back to int16 and store to output */ - out16 = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( out32, 10 ) ); - out[ out_offset + 4 * k + 2 ] = (short)out16; - out[ out_offset + 4 * k + 3 ] = (short)out16; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_rom.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_rom.java deleted file mode 100644 index e2bdce471..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_rom.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Filter coefficients for IIR/FIR polyphase resampling. - * Total size: 550 Words (1.1 kB). - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_resampler_rom -{ - static final int RESAMPLER_DOWN_ORDER_FIR = 12; - static final int RESAMPLER_ORDER_FIR_144 = 6; - - /* Tables for 2x downsampler. Values above 32767 intentionally wrap to a negative value. */ - static final short SKP_Silk_resampler_down2_0 = 9872; - static final short SKP_Silk_resampler_down2_1 = (short) 39809; - - /* Tables for 2x upsampler, low quality. Values above 32767 intentionally wrap to a negative value. */ - static final short SKP_Silk_resampler_up2_lq_0 = 8102; - static final short SKP_Silk_resampler_up2_lq_1 = (short) 36783; - - /* Tables for 2x upsampler, high quality. Values above 32767 intentionally wrap to a negative value. */ - static short[] SKP_Silk_resampler_up2_hq_0 = { 4280, (short) 33727 }; - static short[] SKP_Silk_resampler_up2_hq_1 = { 16295, (short) 54015 }; - /* Matlab code for the notch filter coefficients: */ - /* B = [1, 0.12, 1]; A = [1, 0.055, 0.8]; G = 0.87; freqz(G * B, A, 2^14, 16e3); axis([0, 8000, -10, 1]); */ - /* fprintf('\t%6d, %6d, %6d, %6d\n', round(B(2)*2^16), round(-A(2)*2^16), round((1-A(3))*2^16), round(G*2^15)) */ - static short[] SKP_Silk_resampler_up2_hq_notch = { 7864, -3604, 13107, 28508 }; - - /* Tables with IIR and FIR coefficients for fractional downsamplers (70 Words) */ - static short[] SKP_Silk_Resampler_3_4_COEFS = - { - -18249, -12532, - -97, 284, -495, 309, 10268, 20317, - -94, 156, -48, -720, 5984, 18278, - -45, -4, 237, -847, 2540, 14662, - }; - - static short[] SKP_Silk_Resampler_2_3_COEFS = - { - -11891, -12486, - 20, 211, -657, 688, 8423, 15911, - -44, 197, -152, -653, 3855, 13015, - }; - - static short[] SKP_Silk_Resampler_1_2_COEFS = - { - 2415, -13101, - 158, -295, -400, 1265, 4832, 7968, - }; - - static short[] SKP_Silk_Resampler_3_8_COEFS = - { - 13270, -13738, - -294, -123, 747, 2043, 3339, 3995, - -151, -311, 414, 1583, 2947, 3877, - -33, -389, 143, 1141, 2503, 3653, - }; - - static short[] SKP_Silk_Resampler_1_3_COEFS = - { - 16643, -14000, - -331, 19, 581, 1421, 2290, 2845, - }; - - static short[] SKP_Silk_Resampler_2_3_COEFS_LQ = - { - -2797, -6507, - 4697, 10739, - 1567, 8276, - }; - - static short[] SKP_Silk_Resampler_1_3_COEFS_LQ = - { - 16777, -9792, - 890, 1614, 2148, - }; - - /* Tables with coefficients for 4th order ARMA filter (35 Words), in a packed format: */ - /* { B1_Q14[1], B2_Q14[1], -A1_Q14[1], -A1_Q14[2], -A2_Q14[1], -A2_Q14[2], gain_Q16 } */ - /* where it is assumed that B*_Q14[0], B*_Q14[2], A*_Q14[0] are all 16384 */ - static short[] SKP_Silk_Resampler_320_441_ARMA4_COEFS = - { - 31454, 24746, -9706, -3386, -17911, -13243, 24797 - }; - - static short[] SKP_Silk_Resampler_240_441_ARMA4_COEFS = - { - 28721, 11254, 3189, -2546, -1495, -12618, 11562 - }; - - static short[] SKP_Silk_Resampler_160_441_ARMA4_COEFS = - { - 23492, -6457, 14358, -4856, 14654, -13008, 4456 - }; - - static short[] SKP_Silk_Resampler_120_441_ARMA4_COEFS = - { - 19311, -15569, 19489, -6950, 21441, -13559, 2370 - }; - - static short[] SKP_Silk_Resampler_80_441_ARMA4_COEFS = - { - 13248, -23849, 24126, -9486, 26806, -14286, 1065 - }; - - /* Table with interplation fractions of 1/288 : 2/288 : 287/288 (432 Words) */ - static short[][] SKP_Silk_resampler_frac_FIR_144 = - { - { -647, 1884, 30078}, - { -625, 1736, 30044}, - { -603, 1591, 30005}, - { -581, 1448, 29963}, - { -559, 1308, 29917}, - { -537, 1169, 29867}, - { -515, 1032, 29813}, - { -494, 898, 29755}, - { -473, 766, 29693}, - { -452, 636, 29627}, - { -431, 508, 29558}, - { -410, 383, 29484}, - { -390, 260, 29407}, - { -369, 139, 29327}, - { -349, 20, 29242}, - { -330, -97, 29154}, - { -310, -211, 29062}, - { -291, -324, 28967}, - { -271, -434, 28868}, - { -253, -542, 28765}, - { -234, -647, 28659}, - { -215, -751, 28550}, - { -197, -852, 28436}, - { -179, -951, 28320}, - { -162, -1048, 28200}, - { -144, -1143, 28077}, - { -127, -1235, 27950}, - { -110, -1326, 27820}, - { -94, -1414, 27687}, - { -77, -1500, 27550}, - { -61, -1584, 27410}, - { -45, -1665, 27268}, - { -30, -1745, 27122}, - { -15, -1822, 26972}, - { 0, -1897, 26820}, - { 15, -1970, 26665}, - { 29, -2041, 26507}, - { 44, -2110, 26346}, - { 57, -2177, 26182}, - { 71, -2242, 26015}, - { 84, -2305, 25845}, - { 97, -2365, 25673}, - { 110, -2424, 25498}, - { 122, -2480, 25320}, - { 134, -2534, 25140}, - { 146, -2587, 24956}, - { 157, -2637, 24771}, - { 168, -2685, 24583}, - { 179, -2732, 24392}, - { 190, -2776, 24199}, - { 200, -2819, 24003}, - { 210, -2859, 23805}, - { 220, -2898, 23605}, - { 229, -2934, 23403}, - { 238, -2969, 23198}, - { 247, -3002, 22992}, - { 255, -3033, 22783}, - { 263, -3062, 22572}, - { 271, -3089, 22359}, - { 279, -3114, 22144}, - { 286, -3138, 21927}, - { 293, -3160, 21709}, - { 300, -3180, 21488}, - { 306, -3198, 21266}, - { 312, -3215, 21042}, - { 318, -3229, 20816}, - { 323, -3242, 20589}, - { 328, -3254, 20360}, - { 333, -3263, 20130}, - { 338, -3272, 19898}, - { 342, -3278, 19665}, - { 346, -3283, 19430}, - { 350, -3286, 19194}, - { 353, -3288, 18957}, - { 356, -3288, 18718}, - { 359, -3286, 18478}, - { 362, -3283, 18238}, - { 364, -3279, 17996}, - { 366, -3273, 17753}, - { 368, -3266, 17509}, - { 369, -3257, 17264}, - { 371, -3247, 17018}, - { 372, -3235, 16772}, - { 372, -3222, 16525}, - { 373, -3208, 16277}, - { 373, -3192, 16028}, - { 373, -3175, 15779}, - { 373, -3157, 15529}, - { 372, -3138, 15279}, - { 371, -3117, 15028}, - { 370, -3095, 14777}, - { 369, -3072, 14526}, - { 368, -3048, 14274}, - { 366, -3022, 14022}, - { 364, -2996, 13770}, - { 362, -2968, 13517}, - { 359, -2940, 13265}, - { 357, -2910, 13012}, - { 354, -2880, 12760}, - { 351, -2848, 12508}, - { 348, -2815, 12255}, - { 344, -2782, 12003}, - { 341, -2747, 11751}, - { 337, -2712, 11500}, - { 333, -2676, 11248}, - { 328, -2639, 10997}, - { 324, -2601, 10747}, - { 320, -2562, 10497}, - { 315, -2523, 10247}, - { 310, -2482, 9998}, - { 305, -2442, 9750}, - { 300, -2400, 9502}, - { 294, -2358, 9255}, - { 289, -2315, 9009}, - { 283, -2271, 8763}, - { 277, -2227, 8519}, - { 271, -2182, 8275}, - { 265, -2137, 8032}, - { 259, -2091, 7791}, - { 252, -2045, 7550}, - { 246, -1998, 7311}, - { 239, -1951, 7072}, - { 232, -1904, 6835}, - { 226, -1856, 6599}, - { 219, -1807, 6364}, - { 212, -1758, 6131}, - { 204, -1709, 5899}, - { 197, -1660, 5668}, - { 190, -1611, 5439}, - { 183, -1561, 5212}, - { 175, -1511, 4986}, - { 168, -1460, 4761}, - { 160, -1410, 4538}, - { 152, -1359, 4317}, - { 145, -1309, 4098}, - { 137, -1258, 3880}, - { 129, -1207, 3664}, - { 121, -1156, 3450}, - { 113, -1105, 3238}, - { 105, -1054, 3028}, - { 97, -1003, 2820}, - { 89, -952, 2614}, - { 81, -901, 2409}, - { 73, -851, 2207}, - }; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_structs.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_structs.java deleted file mode 100644 index 63c7e3750..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_structs.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -import java.util.*; - -/** - * Classes for IIR/FIR resamplers. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_resampler_structs -{ - /** - * Flag to enable support for input/output sampling rates above 48 kHz. Turn off for embedded devices. - */ - static final int RESAMPLER_SUPPORT_ABOVE_48KHZ = 1; - - static final int SKP_Silk_RESAMPLER_MAX_FIR_ORDER = 16; - static final int SKP_Silk_RESAMPLER_MAX_IIR_ORDER = 6; -} - - class SKP_Silk_resampler_state_struct - { - int[] sIIR = new int[ Silk_resampler_structs.SKP_Silk_RESAMPLER_MAX_IIR_ORDER ]; /* this must be the first element of this struct */ - int[] sFIR = new int[ Silk_resampler_structs.SKP_Silk_RESAMPLER_MAX_FIR_ORDER ]; - int[] sDown2 = new int[ 2 ]; - - String resampler_function; - ResamplerFP resamplerCB; - void resampler_function( Object state, short[] out, int out_offset, short[] in, int in_offset, int len ) - { - resamplerCB.resampler_function(state, out, out_offset, in, in_offset, len); - } - - String up2_function; - Up2FP up2CB; - void up2_function( int[] state, short[] out, int out_offset, short[] in, int in_offset, int len ) - { - up2CB.up2_function(state, out, out_offset, in, in_offset, len); - - } - - int batchSize; - int invRatio_Q16; - int FIR_Fracs; - int input2x; - short[] Coefs; - - int[] sDownPre = new int[ 2 ]; - int[] sUpPost = new int[ 2 ]; - - String down_pre_function; - DownPreFP downPreCB; - void down_pre_function ( int[] state, short[] out, int out_offset, short[] in, int in_offset, int len ) - { - downPreCB.down_pre_function(state, out, out_offset, in, in_offset, len); - } - - String up_post_function; - UpPostFP upPostCB; - void up_post_function ( int[] state, short[] out, int out_offset, short[] in, int in_offset, int len ) - { - upPostCB.up_post_function(state, out, out_offset, in, in_offset, len); - } - int batchSizePrePost; - int ratio_Q16; - int nPreDownsamplers; - int nPostUpsamplers; - int magic_number; - - /** - * set all fields of the instance to zero. - */ - public void memZero() - { -// { -// if(this.Coefs != null) -// { -// Arrays.fill(this.Coefs, (short)0); -// } -// } - this.Coefs = null; - - Arrays.fill(this.sDown2, 0); - Arrays.fill(this.sDownPre, 0); - Arrays.fill(this.sFIR, 0); - Arrays.fill(this.sIIR, 0); - Arrays.fill(this.sUpPost, 0); - - this.batchSize = 0; - this.batchSizePrePost = 0; - this.down_pre_function = null; - this.downPreCB = null; - this.FIR_Fracs = 0; - this.input2x = 0; - this.invRatio_Q16 = 0; - this.magic_number = 0; - this.nPostUpsamplers = 0; - this.nPreDownsamplers = 0; - this.ratio_Q16 = 0; - this.resampler_function = null; - this.resamplerCB = null; - this.up2_function = null; - this.up2CB = null; - this.up_post_function = null; - this.upPostCB = null; - } -} - /*************************************************************************************/ - interface ResamplerFP - { - void resampler_function( Object state, short[] out, int out_offset, short[] in, int in_offset, int len ); - } - interface Up2FP - { - void up2_function( int[] state, short[] out, int out_offset, short[] in, int in_offset, int len ); - } - interface DownPreFP - { - void down_pre_function ( int[] state, short[] out, int out_offset, short[] in, int in_offset, int len ); - } - interface UpPostFP - { - void up_post_function ( int[] state, short[] out, int out_offset, short[] in, int in_offset, int len ); - } - /*************************************************************************************/ - \ No newline at end of file diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_up2.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_up2.java deleted file mode 100644 index 578aa08f9..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_resampler_up2.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Up-sample by a factor 2, low quality. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_resampler_up2 -{ - /** - * Up-sample by a factor 2, low quality. - * @param S State vector [ 2 ]. - * @param S_offset offset of valid data. - * @param out Output signal [ 2 * len ]. - * @param out_offset offset of valid data. - * @param in Input signal [ len ]. - * @param in_offset offset of valid data. - * @param len Number of input samples. - */ - static void SKP_Silk_resampler_up2( - int[] S, /* I/O: State vector [ 2 ] */ - int S_offset, - short[] out, /* O: Output signal [ 2 * len ] */ - int out_offset, - short[] in, /* I: Input signal [ len ] */ - int in_offset, - int len /* I: Number of input samples */ - ) - { - int k; - int in32, out32, Y, X; - - assert( Silk_resampler_rom.SKP_Silk_resampler_up2_lq_0 > 0 ); - assert( Silk_resampler_rom.SKP_Silk_resampler_up2_lq_1 < 0 ); - /* Internal variables and state are in Q10 format */ - for( k = 0; k < len; k++ ) - { - /* Convert to Q10 */ - in32 = in[ in_offset+k ] << 10; - - /* All-pass section for even output sample */ - Y = in32 - S[ S_offset + 0 ]; - X = Silk_macros.SKP_SMULWB( Y, Silk_resampler_rom.SKP_Silk_resampler_up2_lq_0 ); - out32 = S[ S_offset + 0 ] + X; - S[ S_offset + 0 ] = in32 + X; - - /* Convert back to int16 and store to output */ - out[ out_offset + 2 * k ] = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( out32, 10 ) ); - - /* All-pass section for odd output sample */ - Y = in32 - S[ S_offset + 1 ]; - X = Silk_macros.SKP_SMLAWB( Y, Y, Silk_resampler_rom.SKP_Silk_resampler_up2_lq_1 ); - out32 = S[ S_offset + 1 ] + X; - S[ S_offset + 1 ] = in32 + X; - - /* Convert back to int16 and store to output */ - out[ out_offset + 2 * k + 1 ] = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FIX.SKP_RSHIFT_ROUND( out32, 10 ) ); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_residual_energy_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_residual_energy_FLP.java deleted file mode 100644 index 50a707e8c..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_residual_energy_FLP.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Residual energy. - * - * @author Dingxin Xu - */ -public class Silk_residual_energy_FLP -{ - - - static final int MAX_ITERATIONS_RESIDUAL_NRG = 10; - static final float REGULARIZATION_FACTOR = 1e-8f; - - - /** - * Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c. - * @param c Filter coefficients - * @param c_offset offset of valid data. - * @param wXX Weighted correlation matrix, reg. out - * @param wXX_offset offset of valid data. - * @param wXx Weighted correlation vector - * @param wxx Weighted correlation value - * @param D Dimension - * @return Weighted residual energy - */ - static float SKP_Silk_residual_energy_covar_FLP( /* O Weighted residual energy */ - final float []c, /* I Filter coefficients */ - int c_offset, - float []wXX, /* I/O Weighted correlation matrix, reg. out */ - int wXX_offset, - final float []wXx, /* I Weighted correlation vector */ - final float wxx, /* I Weighted correlation value */ - final int D /* I Dimension */ - ) - { - int i, j, k; - float tmp, nrg = 0, regularization; - - /* Safety checks */ - assert( D >= 0 ); - - regularization = REGULARIZATION_FACTOR * ( wXX[ wXX_offset + 0 ] + wXX[ wXX_offset + D * D - 1 ] ); - for( k = 0; k < MAX_ITERATIONS_RESIDUAL_NRG; k++ ) { - nrg = wxx; - - tmp = 0.0f; - for( i = 0; i < D; i++ ) { - tmp += wXx[ i ] * c[ c_offset + i ]; - } - nrg -= 2.0f * tmp; - - /* compute c' * wXX * c, assuming wXX is symmetric */ - for( i = 0; i < D; i++ ) { - tmp = 0.0f; - for( j = i + 1; j < D; j++ ) { -// tmp += matrix_c_ptr( wXX, i, j, D ) * c[ j ]; - tmp += wXX[wXX_offset + i+j*D] * c[c_offset + j]; - } -// nrg += c[ i ] * ( 2.0f * tmp + matrix_c_ptr( wXX, i, i, D ) * c[ i ] ); - nrg += c[ c_offset + i ] * ( 2.0f * tmp + wXX[wXX_offset + i + D*i] * c[ c_offset + i ] ); - } - if( nrg > 0 ) { - break; - } else { - /* Add white noise */ - for( i = 0; i < D; i++ ) { -// matrix_c_ptr( wXX, i, i, D ) += regularization; - wXX[wXX_offset + i + D*i] += regularization; - } - /* Increase noise for next run */ - regularization *= 2.0f; - } - } - if( k == MAX_ITERATIONS_RESIDUAL_NRG ) { - assert( nrg == 0 ); - nrg = 1.0f; - } - - return nrg; - } - - /** - * Calculates residual energies of input subframes where all subframes have LPC_order - * of preceeding samples - * @param nrgs Residual energy per subframe - * @param x Input signal - * @param a AR coefs for each frame half - * @param gains Quantization gains - * @param subfr_length Subframe length - * @param LPC_order LPC order - */ - static void SKP_Silk_residual_energy_FLP( - float nrgs[], /* O Residual energy per subframe */ - final float x[], /* I Input signal */ - final float a[][ ], /* I AR coefs for each frame half */ - final float gains[], /* I Quantization gains */ - final int subfr_length, /* I Subframe length */ - final int LPC_order /* I LPC order */ - ) - { - int shift; -// SKP_float *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + NB_SUBFR * MAX_LPC_ORDER ) / 2 ]; - float LPC_res_ptr[], LPC_res[] = new float[ ( Silk_define.MAX_FRAME_LENGTH + Silk_define.NB_SUBFR * Silk_define.MAX_LPC_ORDER ) / 2 ]; - -// LPC_res_ptr = LPC_res + LPC_order; - LPC_res_ptr = LPC_res; - int LPC_res_ptr_offset = LPC_order; - shift = LPC_order + subfr_length; - - /* Filter input to create the LPC residual for each frame half, and measure subframe energies */ - Silk_LPC_analysis_filter_FLP.SKP_Silk_LPC_analysis_filter_FLP( LPC_res, a[ 0 ], x, 0 + 0 * shift, 2 * shift, LPC_order ); - nrgs[ 0 ] = (float) ( gains[ 0 ] * gains[ 0 ] * Silk_energy_FLP.SKP_Silk_energy_FLP( LPC_res_ptr, LPC_res_ptr_offset + 0 * shift, subfr_length ) ); - nrgs[ 1 ] = (float) ( gains[ 1 ] * gains[ 1 ] * Silk_energy_FLP.SKP_Silk_energy_FLP( LPC_res_ptr, LPC_res_ptr_offset + 1 * shift, subfr_length ) ); - - Silk_LPC_analysis_filter_FLP.SKP_Silk_LPC_analysis_filter_FLP( LPC_res, a[ 1 ], x, 0 + 2 * shift, 2 * shift, LPC_order ); - nrgs[ 2 ] = ( float )( gains[ 2 ] * gains[ 2 ] * Silk_energy_FLP.SKP_Silk_energy_FLP( LPC_res_ptr, LPC_res_ptr_offset + 0 * shift, subfr_length ) ); - nrgs[ 3 ] = ( float )( gains[ 3 ] * gains[ 3 ] * Silk_energy_FLP.SKP_Silk_energy_FLP( LPC_res_ptr, LPC_res_ptr_offset + 1 * shift, subfr_length ) ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_scale_copy_vector_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_scale_copy_vector_FLP.java deleted file mode 100644 index f1333dc55..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_scale_copy_vector_FLP.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * copy and multiply a vector by a constant - * - * @author Dingxin Xu - */ -public class Silk_scale_copy_vector_FLP -{ - /** - * copy and multiply a vector by a constant. - * @param data_out - * @param data_out_offset - * @param data_in - * @param data_in_offset - * @param gain - * @param dataSize - */ - static void SKP_Silk_scale_copy_vector_FLP( - float []data_out, - int data_out_offset, - final float []data_in, - int data_in_offset, - float gain, - int dataSize - ) - { - int i, dataSize4; - - /* 4x unrolled loop */ - dataSize4 = dataSize & 0xFFFC; - for( i = 0; i < dataSize4; i += 4 ) { - data_out[ data_out_offset + i + 0 ] = gain * data_in[ data_in_offset + i + 0 ]; - data_out[ data_out_offset + i + 1 ] = gain * data_in[ data_in_offset + i + 1 ]; - data_out[ data_out_offset + i + 2 ] = gain * data_in[ data_in_offset + i + 2 ]; - data_out[ data_out_offset + i + 3 ] = gain * data_in[ data_in_offset + i + 3 ]; - } - - /* any remaining elements */ - for( ; i < dataSize; i++ ) { - data_out[ data_out_offset + i ] = gain * data_in[ data_in_offset + i ]; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_scale_vector_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_scale_vector_FLP.java deleted file mode 100644 index 4377229e2..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_scale_vector_FLP.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * scale a vector. - * - * @author Dingxin Xu - */ -public class Silk_scale_vector_FLP -{ - /** - * multiply a vector by a constant. - * @param data1 - * @param gain - * @param dataSize - */ - static void SKP_Silk_scale_vector_FLP( - float []data1, - int data1_offset, - float gain, - int dataSize - ) - { - int i, dataSize4; - - /* 4x unrolled loop */ - dataSize4 = dataSize & 0xFFFC; - for( i = 0; i < dataSize4; i += 4 ) { - data1[ data1_offset + i + 0 ] *= gain; - data1[ data1_offset + i + 1 ] *= gain; - data1[ data1_offset + i + 2 ] *= gain; - data1[ data1_offset + i + 3 ] *= gain; - } - - /* any remaining elements */ - for( ; i < dataSize; i++ ) { - data1[ data1_offset + i ] *= gain; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_schur_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_schur_FLP.java deleted file mode 100644 index 4f669c143..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_schur_FLP.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_schur_FLP -{ - /** - * - * @param refl_coef reflection coefficients (length order) - * @param ref1_coef_offset offset of valid data. - * @param auto_corr autotcorreation sequence (length order+1) - * @param auto_corr_offset offset of valid data. - * @param order order - */ - static void SKP_Silk_schur_FLP( - float refl_coef[], /* O reflection coefficients (length order) */ - int ref1_coef_offset, - float auto_corr[], /* I autotcorreation sequence (length order+1) */ - int auto_corr_offset, - int order /* I order */ - ) - { - int k, n; - float[][] C = new float[Silk_SigProc_FIX.SKP_Silk_MAX_ORDER_LPC + 1][2]; - float Ctmp1, Ctmp2, rc_tmp; - - /* copy correlations */ - for (k = 0; k < order + 1; k++) - { - C[k][0] = C[k][1] = auto_corr[auto_corr_offset + k]; - } - - for (k = 0; k < order; k++) - { - /* get reflection coefficient */ - rc_tmp = -C[k + 1][0] / Math.max(C[0][1], 1e-9f); - - /* save the output */ - refl_coef[ref1_coef_offset + k] = rc_tmp; - - /* update correlations */ - for (n = 0; n < order - k; n++) - { - Ctmp1 = C[n + k + 1][0]; - Ctmp2 = C[n][1]; - C[n + k + 1][0] = Ctmp1 + Ctmp2 * rc_tmp; - C[n][1] = Ctmp2 + Ctmp1 * rc_tmp; - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_shell_coder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_shell_coder.java deleted file mode 100644 index 3f03e06c2..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_shell_coder.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * shell coder; pulse-subframe length is hardcoded. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_shell_coder -{ - /** - * - * @param out combined pulses vector [len] - * @param out_offset offset of valid data. - * @param in input vector [2 * len] - * @param in_offset offset of valid data. - * @param len number of OUTPUT samples - */ - static void combine_pulses( - int []out, /* O: combined pulses vector [len] */ - int out_offset, - int []in, /* I: input vector [2 * len] */ - int in_offset, - final int len /* I: number of OUTPUT samples */ - ) - { - int k; - for( k = 0; k < len; k++ ) { - out[ out_offset + k ] = in[ in_offset + 2 * k ] + in[ in_offset + 2 * k + 1 ]; - } - } - - /** - * - * @param sRC compressor data structure - * @param p_child1 pulse amplitude of first child subframe - * @param p pulse amplitude of current subframe - * @param shell_table table of shell cdfs - */ - static void encode_split( - SKP_Silk_range_coder_state sRC, /* I/O: compressor data structure */ - final int p_child1, /* I: pulse amplitude of first child subframe */ - final int p, /* I: pulse amplitude of current subframe */ - final int[] shell_table - ) - { - final int[] cdf; - int cdf_offset; - - if( p > 0 ) - { - cdf = shell_table; - cdf_offset = Silk_tables_pulses_per_block.SKP_Silk_shell_code_table_offsets[ p ] ; - Silk_range_coder.SKP_Silk_range_encoder( sRC, p_child1, cdf, cdf_offset ); - } - } - - /** - * - * @param p_child1 pulse amplitude of first child subframe - * @param p_child1_offset offset of valid data. - * @param p_child2 pulse amplitude of second child subframe - * @param p_child2_offset offset of valid data. - * @param sRC compressor data structure - * @param p pulse amplitude of current subframe - * @param shell_table table of shell cdfs - */ - static void decode_split( - int []p_child1, /* O: pulse amplitude of first child subframe */ - int p_child1_offset, - int []p_child2, /* O: pulse amplitude of second child subframe */ - int p_child2_offset, - SKP_Silk_range_coder_state sRC, /* I/O: compressor data structure */ - final int p, /* I: pulse amplitude of current subframe */ - int[] shell_table /* I: table of shell cdfs */ - ) - { - int cdf_middle; - final int[] cdf; - int cdf_offset; - - if( p > 0 ) - { - cdf_middle = ( p >> 1 ); - cdf = shell_table; - cdf_offset = Silk_tables_pulses_per_block.SKP_Silk_shell_code_table_offsets[ p ]; - - Silk_range_coder.SKP_Silk_range_decoder( p_child1, p_child1_offset, sRC, cdf, cdf_offset, cdf_middle ); - p_child2[ p_child2_offset + 0 ] = p - p_child1[ p_child1_offset + 0 ]; - } - else - { - p_child1[ p_child1_offset + 0 ] = 0; - p_child2[ p_child2_offset + 0 ] = 0; - } - } - - /** - * Shell encoder, operates on one shell code frame of 16 pulses. - * @param sRC compressor data structure. - * @param pulses0 data: nonnegative pulse amplitudes. - * @param pulses0_offset valid data - */ - static void SKP_Silk_shell_encoder( - SKP_Silk_range_coder_state sRC, /* I/O compressor data structure */ - int[] pulses0, /* I data: nonnegative pulse amplitudes */ - int pulses0_offset - ) - { - int[] pulses1 = new int[ 8 ], pulses2 = new int[ 4 ], pulses3 = new int[ 2 ], pulses4 = new int[ 1 ]; - - /* this function operates on one shell code frame of 16 pulses */ - assert( Silk_define.SHELL_CODEC_FRAME_LENGTH == 16 ); - - /* tree representation per pulse-subframe */ - combine_pulses( pulses1,0, pulses0,pulses0_offset, 8 ); - combine_pulses( pulses2,0, pulses1,0, 4 ); - combine_pulses( pulses3,0, pulses2,0, 2 ); - combine_pulses( pulses4,0, pulses3,0, 1 ); - - encode_split( sRC, pulses3[ 0 ], pulses4[ 0 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table3 ); - - encode_split( sRC, pulses2[ 0 ], pulses3[ 0 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table2 ); - - encode_split( sRC, pulses1[ 0 ], pulses2[ 0 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table1 ); - encode_split( sRC, pulses0[ pulses0_offset + 0 ], pulses1[ 0 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table0 ); - encode_split( sRC, pulses0[ pulses0_offset + 2 ], pulses1[ 1 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table0 ); - - encode_split( sRC, pulses1[ 2 ], pulses2[ 1 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table1 ); - encode_split( sRC, pulses0[ pulses0_offset + 4 ], pulses1[ 2 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table0 ); - encode_split( sRC, pulses0[ pulses0_offset + 6 ], pulses1[ 3 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table0 ); - - encode_split( sRC, pulses2[ 2 ], pulses3[ 1 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table2 ); - - encode_split( sRC, pulses1[ 4 ], pulses2[ 2 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table1 ); - encode_split( sRC, pulses0[ pulses0_offset + 8 ], pulses1[ 4 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table0 ); - encode_split( sRC, pulses0[ pulses0_offset + 10 ], pulses1[ 5 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table0 ); - - encode_split( sRC, pulses1[ 6 ], pulses2[ 3 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table1 ); - encode_split( sRC, pulses0[ pulses0_offset + 12 ], pulses1[ 6 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table0 ); - encode_split( sRC, pulses0[ pulses0_offset + 14 ], pulses1[ 7 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table0 ); - } - - /** - * Shell decoder, operates on one shell code frame of 16 pulses. - * @param pulses0 data: nonnegative pulse amplitudes - * @param pulses0_offset offset of valid data. - * @param sRC compressor data structure - * @param pulses4 number of pulses per pulse-subframe - */ - static void SKP_Silk_shell_decoder( - int []pulses0, /* O data: nonnegative pulse amplitudes */ - int pulses0_offset, - SKP_Silk_range_coder_state sRC, /* I/O compressor data structure */ - final int pulses4 /* I number of pulses per pulse-subframe */ - ) - { - int[] pulses3 = new int[ 2 ], pulses2 = new int[ 4 ], pulses1 = new int[ 8 ]; - - /* this function operates on one shell code frame of 16 pulses */ - Silk_typedef.SKP_assert( Silk_define.SHELL_CODEC_FRAME_LENGTH == 16 ); - - decode_split( pulses3, 0, pulses3, 1, sRC, pulses4, Silk_tables_pulses_per_block.SKP_Silk_shell_code_table3 ); - - decode_split( pulses2, 0, pulses2, 1, sRC, pulses3[ 0 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table2 ); - - decode_split( pulses1, 0, pulses1, 1, sRC, pulses2[ 0 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table1 ); - decode_split( pulses0, pulses0_offset + 0, pulses0, pulses0_offset + 1, sRC, pulses1[ 0 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table0 ); - decode_split( pulses0, pulses0_offset + 2, pulses0, pulses0_offset + 3, sRC, pulses1[ 1 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table0 ); - - decode_split( pulses1, 2, pulses1, 3, sRC, pulses2[ 1 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table1 ); - decode_split( pulses0, pulses0_offset + 4, pulses0, pulses0_offset + 5, sRC, pulses1[ 2 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table0 ); - decode_split( pulses0, pulses0_offset + 6, pulses0, pulses0_offset + 7, sRC, pulses1[ 3 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table0 ); - - decode_split( pulses2, 2, pulses2, 3, sRC, pulses3[ 1 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table2 ); - - decode_split( pulses1, 4, pulses1, 5, sRC, pulses2[ 2 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table1 ); - decode_split( pulses0, pulses0_offset + 8, pulses0, pulses0_offset + 9, sRC, pulses1[ 4 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table0 ); - decode_split( pulses0, pulses0_offset + 10,pulses0, pulses0_offset + 11, sRC, pulses1[ 5 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table0 ); - - decode_split( pulses1, 6, pulses1, 7, sRC, pulses2[ 3 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table1 ); - decode_split( pulses0, pulses0_offset + 12, pulses0, pulses0_offset + 13, sRC, pulses1[ 6 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table0 ); - decode_split( pulses0, pulses0_offset + 14, pulses0, pulses0_offset + 15, sRC, pulses1[ 7 ], Silk_tables_pulses_per_block.SKP_Silk_shell_code_table0 ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_sigm_Q15.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_sigm_Q15.java deleted file mode 100644 index 3fdadb66a..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_sigm_Q15.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * approximate sigmoid function. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_sigm_Q15 -{ - /* fprintf(1, '%d, ', round(1024 * ([1 ./ (1 + exp(-(1:5))), 1] - 1 ./ (1 + exp(-(0:5)))))); */ - static int[] sigm_LUT_slope_Q10 = - { - 237, 153, 73, 30, 12, 7 - }; - /* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp(-(0:5))))); */ - static int[] sigm_LUT_pos_Q15 = - { - 16384, 23955, 28861, 31213, 32178, 32548 - }; - /* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp((0:5))))); */ - static int[] sigm_LUT_neg_Q15 = - { - 16384, 8812, 3906, 1554, 589, 219 - }; - - static int SKP_Silk_sigm_Q15( int in_Q5 ) - { - int ind; - - if( in_Q5 < 0 ) - { - /* Negative input */ - in_Q5 = -in_Q5; - if( in_Q5 >= 6 * 32 ) - { - return 0; /* Clip */ - } - else - { - /* Linear interpolation of look up table */ - ind = in_Q5 >> 5; - return( sigm_LUT_neg_Q15[ ind ] - Silk_macros.SKP_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) ); - } - } - else - { - /* Positive input */ - if( in_Q5 >= 6 * 32 ) - { - return 32767; /* clip */ - } - else - { - /* Linear interpolation of look up table */ - ind = in_Q5 >> 5; - return( sigm_LUT_pos_Q15[ ind ] + Silk_macros.SKP_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) ); - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_solve_LS_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_solve_LS_FLP.java deleted file mode 100644 index 05eae418b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_solve_LS_FLP.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -public class Silk_solve_LS_FLP -{ - /** - * Function to solve linear equation Ax = b, when A is a MxM - * symmetric square matrix - using LDL factorisation. - * @param A Symmetric square matrix, out: reg. - * @param A_offset offset of valid data. - * @param M Size of matrix - * @param b Pointer to b vector - * @param x Pointer to x solution vector - * @param x_offset offset of valid data. - */ - static void SKP_Silk_solve_LDL_FLP( - float []A, /* I/O Symmetric square matrix, out: reg. */ - int A_offset, - final int M, /* I Size of matrix */ - final float []b, /* I Pointer to b vector */ - float []x, /* O Pointer to x solution vector */ - int x_offset - ) - { - int i; -// float L[][] = new float[Silk_define.MAX_MATRIX_SIZE][Silk_define.MAX_MATRIX_SIZE]; -//TODO:change L from two dimension to one dimension. - float L_tmp[] = new float[Silk_define.MAX_MATRIX_SIZE*Silk_define.MAX_MATRIX_SIZE]; - float T[] = new float[Silk_define.MAX_MATRIX_SIZE]; - float Dinv[] = new float[Silk_define.MAX_MATRIX_SIZE];// inverse diagonal elements of D - - assert( M <= Silk_define.MAX_MATRIX_SIZE ); - - /*************************************************** - Factorize A by LDL such that A = L*D*(L^T), - where L is lower triangular with ones on diagonal - ****************************************************/ -// SKP_Silk_LDL_FLP( A, M, &L[ 0 ][ 0 ], Dinv ); - SKP_Silk_LDL_FLP(A, A_offset, M, L_tmp, Dinv); - - /**************************************************** - * substitute D*(L^T) = T. ie: - L*D*(L^T)*x = b => L*T = b <=> T = inv(L)*b - ******************************************************/ -// SKP_Silk_SolveWithLowerTriangularWdiagOnes_FLP( &L[ 0 ][ 0 ], M, b, T ); - SKP_Silk_SolveWithLowerTriangularWdiagOnes_FLP( L_tmp, M, b, T ); - - /**************************************************** - D*(L^T)*x = T <=> (L^T)*x = inv(D)*T, because D is - diagonal just multiply with 1/d_i - ****************************************************/ - for( i = 0; i < M; i++ ) { - T[ i ] = T[ i ] * Dinv[ i ]; - } - /**************************************************** - x = inv(L') * inv(D) * T - *****************************************************/ -// SKP_Silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( &L[ 0 ][ 0 ], M, T, x ); - SKP_Silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( L_tmp, M, T, x, x_offset ); - - } - - /** - * Function to solve linear equation (A^T)x = b, when A is a MxM lower - * triangular, with ones on the diagonal. (ie then A^T is upper triangular) - * @param L Pointer to Lower Triangular Matrix - * @param M Dim of Matrix equation - * @param b b Vector - * @param x x Vector - * @param x_offset offset of valid data. - */ - static void SKP_Silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( - final float []L, /* (I) Pointer to Lower Triangular Matrix */ - int M, /* (I) Dim of Matrix equation */ - final float []b, /* (I) b Vector */ - float []x, /* (O) x Vector */ - int x_offset - ) - { -// SKP_int i, j; -// SKP_float temp; -// const SKP_float *ptr1; - int i,j; - float temp; -//TODO:ignore const - float []ptr1; - int ptr1_offset; - - for( i = M - 1; i >= 0; i-- ) { -// ptr1 = matrix_adr( L, 0, i, M ); - ptr1 = L; - ptr1_offset = i; - temp = 0; - for( j = M - 1; j > i ; j-- ) { - temp += ptr1[ ptr1_offset + j * M ] * x[ x_offset + j ]; - } - temp = b[ i ] - temp; - x[ x_offset + i ] = temp; - } - } - - /** - * Function to solve linear equation Ax = b, when A is a MxM lower - * triangular matrix, with ones on the diagonal. - * @param L Pointer to Lower Triangular Matrix - * @param M Pointer to Lower Triangular Matrix - * @param b b Vector - * @param x x Vector - */ - static void SKP_Silk_SolveWithLowerTriangularWdiagOnes_FLP( - final float []L, /* (I) Pointer to Lower Triangular Matrix */ - int M, /* (I) Pointer to Lower Triangular Matrix */ - final float []b, /* (I) b Vector */ - float []x /* (O) x Vector */ - ) - { -// SKP_int i, j; -// SKP_float temp; -// const SKP_float *ptr1; - int i,j; - float temp; -//TODO:ignore const - float []ptr1; - int ptr1_offset; - - for( i = 0; i < M; i++ ) { -// ptr1 = matrix_adr( L, i, 0, M ); - ptr1 = L; - ptr1_offset = i*M; - temp = 0; - for( j = 0; j < i; j++ ) { - temp += ptr1[ ptr1_offset + j ] * x[ j ]; - } - temp = b[ i ] - temp; - x[ i ] = temp; - } - } - - /** - * LDL Factorisation. Finds the upper triangular matrix L and the diagonal - * Matrix D (only the diagonal elements returned in a vector)such that - * the symmetric matric A is given by A = L*D*L'. - * @param A Pointer to Symetric Square Matrix - * @param A_offset offset of valid data. - * @param M Size of Matrix - * @param L Pointer to Square Upper triangular Matrix - * @param Dinv Pointer to vector holding the inverse diagonal elements of D - */ - static void SKP_Silk_LDL_FLP( - float []A, /* (I/O) Pointer to Symetric Square Matrix */ - int A_offset, - int M, /* (I) Size of Matrix */ - float []L, /* (I/O) Pointer to Square Upper triangular Matrix */ - float []Dinv /* (I/O) Pointer to vector holding the inverse diagonal elements of D */ - ) - { -/* SKP_int i, j, k, loop_count, err = 1; - SKP_float *ptr1, *ptr2; - double temp, diag_min_value; - SKP_float v[ MAX_MATRIX_SIZE ], D[ MAX_MATRIX_SIZE ]; // temp arrays -*/ - int i, j, k, loop_count, err = 1; - float ptr1[], ptr2[]; - int ptr1_offset, ptr2_offset; - double temp, diag_min_value; - float v[] = new float[ Silk_define.MAX_MATRIX_SIZE ], D[] = new float[ Silk_define.MAX_MATRIX_SIZE ]; // temp arrays - - assert( M <= Silk_define.MAX_MATRIX_SIZE ); - - diag_min_value = Silk_define_FLP.FIND_LTP_COND_FAC * 0.5f * ( A[ A_offset + 0 ] + A[ A_offset + M * M - 1 ] ); - for( loop_count = 0; loop_count < M && err == 1; loop_count++ ) { - err = 0; - for( j = 0; j < M; j++ ) { -// ptr1 = matrix_adr( L, j, 0, M ); -// temp = matrix_ptr( A, j, j, M ); // element in row j column j - ptr1 = L; - ptr1_offset = j*M + 0; - temp = A[A_offset + j*M + j]; - for( i = 0; i < j; i++ ) { - v[ i ] = ptr1[ ptr1_offset + i ] * D[ i ]; - temp -= ptr1[ ptr1_offset + i ] * v[ i ]; - } - if( temp < diag_min_value ) { - /* Badly conditioned matrix: add white noise and run again */ - temp = ( loop_count + 1 ) * diag_min_value - temp; - for( i = 0; i < M; i++ ) { -// matrix_ptr( A, i, i, M ) += ( SKP_float )temp; - A[A_offset + i*M+i] += temp; - } - err = 1; - break; - } - D[ j ] = ( float )temp; - Dinv[ j ] = ( float )( 1.0f / temp ); -// matrix_ptr( L, j, j, M ) = 1.0f; - L[j*M+j] = 1.0f; - -// ptr1 = matrix_adr( A, j, 0, M ); -// ptr2 = matrix_adr( L, j + 1, 0, M); - ptr1 = A; - ptr1_offset = A_offset + j*M; - ptr2 = L; - ptr2_offset = (j+1)*M; - - for( i = j + 1; i < M; i++ ) { - temp = 0.0; - for( k = 0; k < j; k++ ) { - temp += ptr2[ ptr2_offset + k ] * v[ k ]; - } -// matrix_ptr( L, i, j, M ) = ( SKP_float )( ( ptr1[ i ] - temp ) * Dinv[ j ] ); - L[i*M+j] = (float) ( ( ptr1[ ptr1_offset + i ] - temp ) * Dinv[ j ] ); - ptr2_offset += M; // go to next column - } - } - } - assert( err == 0 ); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_sort.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_sort.java deleted file mode 100644 index f15e43224..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_sort.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Insertion sort (fast for already almost sorted arrays): - * Best case: O(n) for an already sorted array - * Worst case: O(n^2) for an inversely sorted array - * Shell short: http://en.wikipedia.org/wiki/Shell_sort - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_sort -{ - /** - * - * @param a Unsorted / Sorted vector - * @param index Index vector for the sorted elements - * @param L Vector length - * @param K Number of correctly sorted positions - */ - static void SKP_Silk_insertion_sort_increasing( - int []a, /* I/O: Unsorted / Sorted vector */ - int []index, /* O: Index vector for the sorted elements */ - final int L, /* I: Vector length */ - final int K /* I: Number of correctly sorted positions */ - ) - { - int value; - int i, j; - - /* Safety checks */ - assert( K > 0 ); - assert( L > 0 ); - assert( L >= K ); - - /* Write start indices in index vector */ - for( i = 0; i < K; i++ ) { - index[ i ] = i; - } - - /* Sort vector elements by value, increasing order */ - for( i = 1; i < K; i++ ) { - value = a[ i ]; - for( j = i - 1; ( j >= 0 ) && ( value < a[ j ] ); j-- ) { - a[ j + 1 ] = a[ j ]; /* Shift value */ - index[ j + 1 ] = index[ j ]; /* Shift index */ - } - a[ j + 1 ] = value; /* Write value */ - index[ j + 1 ] = i; /* Write index */ - } - - /* If less than L values are asked for, check the remaining values, */ - /* but only spend CPU to ensure that the K first values are correct */ - for( i = K; i < L; i++ ) { - value = a[ i ]; - if( value < a[ K - 1 ] ) { - for( j = K - 2; ( j >= 0 ) && ( value < a[ j ] ); j-- ) { - a[ j + 1 ] = a[ j ]; /* Shift value */ - index[ j + 1 ] = index[ j ]; /* Shift index */ - } - a[ j + 1 ] = value; /* Write value */ - index[ j + 1 ] = i; /* Write index */ - } - } - } - - /** - * - * @param a Unsorted / Sorted vector - * @param index Index vector for the sorted elements - * @param L Vector length - * @param K Number of correctly sorted positions - */ - static void SKP_Silk_insertion_sort_decreasing( - int []a, /* I/O: Unsorted / Sorted vector */ - int []index, /* O: Index vector for the sorted elements */ - final int L, /* I: Vector length */ - final int K /* I: Number of correctly sorted positions */ - ) - { - int value; - int i, j; - - /* Safety checks */ - assert( K > 0 ); - assert( L > 0 ); - assert( L >= K ); - - /* Write start indices in index vector */ - for( i = 0; i < K; i++ ) { - index[ i ] = i; - } - - /* Sort vector elements by value, decreasing order */ - for( i = 1; i < K; i++ ) { - value = a[ i ]; - for( j = i - 1; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { - a[ j + 1 ] = a[ j ]; /* Shift value */ - index[ j + 1 ] = index[ j ]; /* Shift index */ - } - a[ j + 1 ] = value; /* Write value */ - index[ j + 1 ] = i; /* Write index */ - } - - /* If less than L values are asked for, check the remaining values, */ - /* but only spend CPU to ensure that the K first values are correct */ - for( i = K; i < L; i++ ) { - value = a[ i ]; - if( value > a[ K - 1 ] ) { - for( j = K - 2; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { - a[ j + 1 ] = a[ j ]; /* Shift value */ - index[ j + 1 ] = index[ j ]; /* Shift index */ - } - a[ j + 1 ] = value; /* Write value */ - index[ j + 1 ] = i; /* Write index */ - } - } - } - - /** - * - * @param a Unsorted / Sorted vector - * @param index Index vector for the sorted elements - * @param L Vector length - * @param K Number of correctly sorted positions - */ - static void SKP_Silk_insertion_sort_decreasing_int16( - short []a, /* I/O: Unsorted / Sorted vector */ - int []index, /* O: Index vector for the sorted elements */ - final int L, /* I: Vector length */ - final int K /* I: Number of correctly sorted positions */ - ) - { - int i, j; - int value; - - /* Safety checks */ - assert( K > 0 ); - assert( L > 0 ); - assert( L >= K ); - - /* Write start indices in index vector */ - for( i = 0; i < K; i++ ) { - index[ i ] = i; - } - - /* Sort vector elements by value, decreasing order */ - for( i = 1; i < K; i++ ) { - value = a[ i ]; - for( j = i - 1; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { - a[ j + 1 ] = a[ j ]; /* Shift value */ - index[ j + 1 ] = index[ j ]; /* Shift index */ - } - a[ j + 1 ] = (short) value; /* Write value */ - index[ j + 1 ] = i; /* Write index */ - } - - /* If less than L values are asked for, check the remaining values, */ - /* but only spend CPU to ensure that the K first values are correct */ - for( i = K; i < L; i++ ) { - value = a[ i ]; - if( value > a[ K - 1 ] ) { - for( j = K - 2; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { - a[ j + 1 ] = a[ j ]; /* Shift value */ - index[ j + 1 ] = index[ j ]; /* Shift index */ - } - a[ j + 1 ] = (short) value; /* Write value */ - index[ j + 1 ] = i; /* Write index */ - } - } - } - - /** - * - * @param a Unsorted / Sorted vector - * @param a_offset offset of valid data. - * @param L Vector length - */ - static void SKP_Silk_insertion_sort_increasing_all_values( - int []a, /* I/O: Unsorted / Sorted vector */ - int a_offset, - final int L /* I: Vector length */ - ) - { - int value; - int i, j; - - /* Safety checks */ - Silk_typedef.SKP_assert( L > 0 ); - - /* Sort vector elements by value, increasing order */ - for( i = 1; i < L; i++ ) { - value = a[ a_offset+i ]; - for( j = i - 1; ( j >= 0 ) && ( value < a[ a_offset+j ] ); j-- ) { - a[ a_offset+j + 1 ] = a[ a_offset+j ]; /* Shift value */ - } - a[ a_offset+j + 1 ] = value; /* Write value */ - } - } - - /** - * - * @param a Unsorted / Sorted vector - * @param index Index vector for the sorted elements - * @param L Vector length - * @param K Number of correctly sorted positions - */ - static void SKP_Silk_shell_insertion_sort_increasing( - int []a, /* I/O: Unsorted / Sorted vector */ - int []index, /* O: Index vector for the sorted elements */ - final int L, /* I: Vector length */ - final int K /* I: Number of correctly sorted positions */ - ) - { - int value, inc_Q16_tmp; - int i, j, inc, idx; - - /* Safety checks */ - Silk_typedef.SKP_assert( K > 0 ); - Silk_typedef.SKP_assert( L > 0 ); - Silk_typedef.SKP_assert( L >= K ); - - /* Calculate initial step size */ - inc_Q16_tmp = ( L << 15 ); -// inc = SKP_RSHIFT( inc_Q16_tmp, 16 ); - inc = ( inc_Q16_tmp >> 16 ); - - /* Write start indices in index vector */ - for( i = 0; i < K; i++ ) { - index[ i ] = i; - } - - /* Shell sort first values */ - while( inc > 0 ) { - for( i = inc; i < K; i++ ) { - value = a[ i ]; - idx = index[ i ]; - for( j = i - inc; ( j >= 0 ) && ( value < a[ j ] ); j -= inc ) { - a[ j + inc ] = a[ j ]; /* Shift value */ - index[ j + inc ] = index[ j ]; /* Shift index */ - } - a[ j + inc ] = value; /* Write value */ - index[ j + inc ] = idx; /* Write index */ - } -// inc_Q16_tmp = SKP_SMULWB( inc_Q16_tmp, 29789 ); // 29789_Q16 = 2.2^(-1)_Q0 - inc_Q16_tmp = Silk_macros.SKP_SMULWB( inc_Q16_tmp, 29789 ); // 29789_Q16 = 2.2^(-1)_Q0 - -// inc = SKP_RSHIFT_ROUND( inc_Q16_tmp, 16 ); - inc = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( inc_Q16_tmp, 16 ); - - } - - /* If less than L values are asked for, check the remaining values, */ - /* but only spend CPU to ensure that the K first values are correct */ - /* Insertion sort remaining values */ - for( i = K; i < L; i++ ) { - value = a[ i ]; - if( value < a[ K - 1 ] ) { - for( j = K - 2; ( j >= 0 ) && ( value < a[ j ] ); j-- ) { - a[ j + 1 ] = a[ j ]; /* Shift value */ - index[ j + 1 ] = index[ j ]; /* Shift index */ - } - a[ j + 1 ] = value; /* Write value */ - index[ j + 1 ] = i; /* Write index */ - } - } - } - - /** - * - * @param a Unsorted / Sorted vector. - * @param index Index vector for the sorted elements. - * @param L Vector length. - */ - static void SKP_Silk_shell_sort_increasing_all_values( - int []a, /* I/O: Unsorted / Sorted vector */ - int []index, /* O: Index vector for the sorted elements */ - final int L /* I: Vector length */ - ) - { - int value, inc_Q16_tmp; - int i, j, inc, idx; - - /* Safety checks */ - Silk_typedef.SKP_assert( L > 0 ); - - /* Calculate initial step size */ -// inc_Q16_tmp = SKP_LSHIFT( (int)L, 15 ); - inc_Q16_tmp = ( L << 15 ); -// inc = SKP_RSHIFT( inc_Q16_tmp, 16 ); - inc = ( inc_Q16_tmp >> 16 ); - - - /* Write start indices in index vector */ - for( i = 0; i < L; i++ ) { - index[ i ] = i; - } - - /* Sort vector elements by value, increasing order */ - while( inc > 0 ) { - for( i = inc; i < L; i++ ) { - value = a[ i ]; - idx = index[ i ]; - for( j = i - inc; ( j >= 0 ) && ( value < a[ j ] ); j -= inc ) { - a[ j + inc ] = a[ j ]; /* Shift value */ - index[ j + inc ] = index[ j ]; /* Shift index */ - } - a[ j + inc ] = value; /* Write value */ - index[ j + inc ] = idx; /* Write index */ - } -// inc_Q16_tmp = SKP_SMULWB( inc_Q16_tmp, 29789 ); // 29789_Q16 = 2.2^(-1)_Q0 - inc_Q16_tmp = Silk_macros.SKP_SMULWB( inc_Q16_tmp, 29789 ); // 29789_Q16 = 2.2^(-1)_Q0 - -// inc = SKP_RSHIFT_ROUND( inc_Q16_tmp, 16 ); - inc = Silk_SigProc_FIX.SKP_RSHIFT_ROUND( inc_Q16_tmp, 16 ); - - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_sort_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_sort_FLP.java deleted file mode 100644 index 28b905c1b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_sort_FLP.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * Insertion sort (fast for already almost sorted arrays): - * Best case: O(n) for an already sorted array - * Worst case: O(n^2) for an inversely sorted array - * - * To be implemented: - * Shell short: http://en.wikipedia.org/wiki/Shell_sort - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_sort_FLP -{ - /** - * - * @param a Unsorted / Sorted vector - * @param a_offset - * @param index Index vector for the sorted elements - * @param L Vector length - * @param K Number of correctly sorted positions - */ - static void SKP_Silk_insertion_sort_increasing_FLP - ( - float[] a, /* I/O: Unsorted / Sorted vector */ - int a_offset, - int[] index, /* O: Index vector for the sorted elements */ - final int L, /* I: Vector length */ - final int K /* I: Number of correctly sorted positions */ - ) - { - float value; - int i, j; - - /* Safety checks */ - assert (K > 0); - assert (L > 0); - assert (L >= K); - - /* Write start indices in index vector */ - for (i = 0; i < K; i++) - { - index[i] = i; - } - - /* Sort vector elements by value, increasing order */ - for (i = 1; i < K; i++) - { - value = a[a_offset + i]; - for (j = i - 1; (j >= 0) && (value < a[a_offset + j]); j--) - { - a[a_offset + j + 1] = a[a_offset + j]; /* Shift value */ - index[j + 1] = index[j]; /* Shift index */ - } - a[a_offset + j + 1] = value; /* Write value */ - index[j + 1] = i; /* Write index */ - } - - /* If less than L values are asked check the remaining values, */ - /* but only spend CPU to ensure that the K first values are correct */ - for (i = K; i < L; i++) - { - value = a[a_offset + i]; - if (value < a[a_offset + K - 1]) - { - for (j = K - 2; (j >= 0) && (value < a[a_offset + j]); j--) - { - a[a_offset + j + 1] = a[a_offset + j]; /* Shift value */ - index[j + 1] = index[j]; /* Shift index */ - } - a[a_offset + j + 1] = value; /* Write value */ - index[j + 1] = i; /* Write index */ - } - } - } - - /** - * - * @param a Unsorted / Sorted vector. - * @param a_offset offset of valid data. - * @param index Index vector for the sorted elements. - * @param L Vector length. - * @param K Number of correctly sorted positions. - */ - static void SKP_Silk_insertion_sort_decreasing_FLP - ( - float[] a, /* I/O: Unsorted / Sorted vector */ - int a_offset, - int[] index, /* O: Index vector for the sorted elements */ - final int L, /* I: Vector length */ - final int K /* I: Number of correctly sorted positions */ - ) - { - float value; - int i, j; - - /* Safety checks */ - assert (K > 0); - assert (L > 0); - assert (L >= K); - - /* Write start indices in index vector */ - for (i = 0; i < K; i++) - { - index[i] = i; - } - - /* Sort vector elements by value, decreasing order */ - for (i = 1; i < K; i++) - { - value = a[a_offset + i]; - for (j = i - 1; (j >= 0) && (value > a[a_offset + j]); j--) - { - a[a_offset + j + 1] = a[a_offset + j]; /* Shift value */ - index[j + 1] = index[j]; /* Shift index */ - } - a[a_offset + j + 1] = value; /* Write value */ - index[j + 1] = i; /* Write index */ - } - - /* If less than L values are asked check the remaining values, */ - /* but only spend CPU to ensure that the K first values are correct */ - for (i = K; i < L; i++) - { - value = a[a_offset + i]; - if (value > a[a_offset + K - 1]) - { - for (j = K - 2; (j >= 0) && (value > a[a_offset + j]); j--) - { - a[a_offset + j + 1] = a[a_offset + j]; /* Shift value */ - index[j + 1] = index[j]; /* Shift index */ - } - a[a_offset + j + 1] = value; /* Write value */ - index[j + 1] = i; /* Write index */ - } - } - } - - /** - * - * @param a Unsorted / Sorted vector - * @param a_offset offset of valid data. - * @param L Vector length - */ - static void SKP_Silk_insertion_sort_increasing_all_values_FLP - ( - float[] a, /* I/O: Unsorted / Sorted vector */ - int a_offset, - final int L /* I: Vector length */ - ) - { - float value; - int i, j; - - /* Safety checks */ - assert (L > 0); - - /* Sort vector elements by value, increasing order */ - for (i = 1; i < L; i++) - { - value = a[a_offset + i]; - for (j = i - 1; (j >= 0) && (value < a[a_offset + j]); j--) - { - a[a_offset + j + 1] = a[a_offset + j]; /* Shift value */ - } - a[a_offset + j + 1] = value; /* Write value */ - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_structs.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_structs.java deleted file mode 100644 index 8957614ef..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_structs.java +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -import java.util.*; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_structs -{ - -} - -/** - * Noise shaping quantization state. - * - * @author Jing Dai - * @author Dingxin Xu - */ -class SKP_Silk_nsq_state implements Cloneable -{ - short[] xq = new short[2 * Silk_define.MAX_FRAME_LENGTH]; /* Buffer for quantized output signal */ - int[] sLTP_shp_Q10 = new int[ 2 * Silk_define.MAX_FRAME_LENGTH ]; - int[] sLPC_Q14 = new int[ Silk_define.MAX_FRAME_LENGTH / Silk_define.NB_SUBFR + Silk_define.MAX_LPC_ORDER ]; - int[] sAR2_Q14 = new int[ Silk_define.SHAPE_LPC_ORDER_MAX ]; - int sLF_AR_shp_Q12; - int lagPrev; - int sLTP_buf_idx; - int sLTP_shp_buf_idx; - int rand_seed; - int prev_inv_gain_Q16; - int rewhite_flag; - - /** - * override clone mthod. - */ - //TODO: - public Object clone() - { - SKP_Silk_nsq_state clone = null; - try { - clone = (SKP_Silk_nsq_state) super.clone(); - } catch (CloneNotSupportedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return clone; - } - - /** - * set all fields of the instance to zero - */ - public void memZero() - { - Arrays.fill(this.sAR2_Q14, 0); - Arrays.fill(this.sLPC_Q14, 0); - Arrays.fill(this.sLTP_shp_Q10, 0); - Arrays.fill(this.xq, (short)0); - - this.lagPrev = 0; - this.prev_inv_gain_Q16 = 0; - this.rand_seed = 0; - this.rewhite_flag = 0; - this.sLF_AR_shp_Q12 = 0; - this.sLTP_buf_idx = 0; - this.sLTP_shp_buf_idx = 0; - } -}/* FIX*/ - -/** - * Class for Low BitRate Redundant (LBRR) information. - * - * @author Jing Dai - * @author Dingxin Xu - */ -class SKP_SILK_LBRR_struct -{ - byte[] payload = new byte[Silk_define.MAX_ARITHM_BYTES]; - int nBytes; /* Number of bytes in payload */ - int usage; /* Tells how the payload should be used as FEC */ - - public void memZero() - { - this.nBytes = 0; - this.usage = 0; - Arrays.fill(this.payload, (byte)0); - } -} - -/** - * VAD state. - * - * @author Jing Dai - * @author Dingxin Xu - */ -class SKP_Silk_VAD_state -{ - int[] AnaState = new int[ 2 ]; /* Analysis filterbank state: 0-8 kHz */ - int[] AnaState1 = new int[ 2 ]; /* Analysis filterbank state: 0-4 kHz */ - int[] AnaState2 = new int[ 2 ]; /* Analysis filterbank state: 0-2 kHz */ - int[] XnrgSubfr = new int[ Silk_define.VAD_N_BANDS ]; /* Subframe energies */ - int[] NrgRatioSmth_Q8 = new int[ Silk_define.VAD_N_BANDS ]; /* Smoothed energy level in each band */ - short HPstate; /* State of differentiator in the lowest band */ - int[] NL = new int[ Silk_define.VAD_N_BANDS ]; /* Noise energy level in each band */ - int[] inv_NL = new int[ Silk_define.VAD_N_BANDS ]; /* Inverse noise energy level in each band */ - int[] NoiseLevelBias = new int[ Silk_define.VAD_N_BANDS ]; /* Noise level estimator bias/offset */ - int counter; /* Frame counter used in the initial phase */ -} - -/** - * Range encoder/decoder state. - * - * @author Jing Dai - * @author Dingxin Xu - */ -class SKP_Silk_range_coder_state -{ - int bufferLength; - int bufferIx; - long base_Q32; - long range_Q16; - int error; - byte[] buffer = new byte[Silk_define.MAX_ARITHM_BYTES];/* Buffer containing payload */ -} - -/** - * Input frequency range detection struct. - * - * @author Jing Dai - * @author Dingxin Xu - */ -class SKP_Silk_detect_SWB_state -{ - int[][] S_HP_8_kHz = new int[ Silk_define.NB_SOS ][ 2 ]; /* HP filter State */ - int ConsecSmplsAboveThres; - int ActiveSpeech_ms; /* Accumulated time with active speech */ - int SWB_detected; /* Flag to indicate SWB input */ - int WB_detected; /* Flag to indicate WB input */ -} - -/** - * Variable cut-off low-pass filter state. - * - * @author Jing Dai - * @author Dingxin Xu - */ -class SKP_Silk_LP_state -{ - int[] In_LP_State = new int[ 2 ]; /* Low pass filter state */ - int transition_frame_no; /* Counter which is mapped to a cut-off frequency */ - int mode; /* Operating mode, 0: switch down, 1: switch up */ -} - -/** - * Class for one stage of MSVQ. - * - * @author Jing Dai - * @author Dingxin Xu - */ -class SKP_Silk_NLSF_CBS -{ - public SKP_Silk_NLSF_CBS(int nVectors, short[] CB_NLSF_Q15, short[] Rates_Q5) - { - this.CB_NLSF_Q15 = CB_NLSF_Q15; - this.nVectors = nVectors; - this.Rates_Q5 = Rates_Q5; - } - public SKP_Silk_NLSF_CBS(int nVectors, short[] SKP_Silk_NLSF_MSVQ_CB0_10_Q15, int Q15_offset, - short[] SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5, int Q5_offset) - { - this.nVectors = nVectors; - this.CB_NLSF_Q15 = new short[SKP_Silk_NLSF_MSVQ_CB0_10_Q15.length-Q15_offset]; - System.arraycopy( SKP_Silk_NLSF_MSVQ_CB0_10_Q15, Q15_offset, this.CB_NLSF_Q15, 0, this.CB_NLSF_Q15.length); - this.Rates_Q5 = new short[SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5.length - Q5_offset]; - System.arraycopy(SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5, Q5_offset, this.Rates_Q5, 0, this.Rates_Q5.length); - } - public SKP_Silk_NLSF_CBS() - { - super(); - } - //TODO: the three fields are constant in C. - int nVectors; - short[] CB_NLSF_Q15; - short[] Rates_Q5; -} - -/** - * Class containing NLSF MSVQ codebook. - * - * @author Jing Dai - * @author Dingxin Xu - */ -class SKP_Silk_NLSF_CB_struct -{ - public SKP_Silk_NLSF_CB_struct(int nStates, SKP_Silk_NLSF_CBS[] CBStages, int[] NDeltaMin_Q15, - int[] CDF, int[][] StartPtr, int[] MiddleIx) - { - this.CBStages = CBStages; - this.CDF = CDF; - this.MiddleIx = MiddleIx; - this.NDeltaMin_Q15 = NDeltaMin_Q15; - this.nStages = nStates; - this.StartPtr = StartPtr; - - } - public SKP_Silk_NLSF_CB_struct() - { - super(); - } -//TODO: this filed is constant in C. - int nStages; - - /* Fields for (de)quantizing */ -//TODO:CBStates should be defined as an array or an object reference? - SKP_Silk_NLSF_CBS[] CBStages; - int[] NDeltaMin_Q15; - - /* Fields for arithmetic (de)coding */ - int[] CDF; - int[][] StartPtr; - int[] MiddleIx; -} - -/** - * Encoder state. - * - * @author Jing Dai - * @author Dingxin Xu - */ -class SKP_Silk_encoder_state -{ - SKP_Silk_range_coder_state sRC = new SKP_Silk_range_coder_state(); /* Range coder state */ - SKP_Silk_range_coder_state sRC_LBRR = new SKP_Silk_range_coder_state(); /* Range coder state (for low bitrate redundancy) */ - int[] In_HP_State = new int[ 2 ]; /* High pass filter state */ - SKP_Silk_LP_state sLP = new SKP_Silk_LP_state(); /* Low pass filter state */ - SKP_Silk_VAD_state sVAD = new SKP_Silk_VAD_state(); /* Voice activity detector state */ - - int LBRRprevLastGainIndex; - int prev_sigtype; - int typeOffsetPrev; /* Previous signal type and quantization offset */ - int prevLag; - int prev_lagIndex; - int API_fs_Hz; /* API sampling frequency (Hz) */ - int prev_API_fs_Hz; /* Previous API sampling frequency (Hz) */ - int maxInternal_fs_kHz; /* Maximum internal sampling frequency (kHz) */ - int fs_kHz; /* Internal sampling frequency (kHz) */ - int fs_kHz_changed; /* Did we switch yet? */ - int frame_length; /* Frame length (samples) */ - int subfr_length; /* Subframe length (samples) */ - int la_pitch; /* Look-ahead for pitch analysis (samples) */ - int la_shape; /* Look-ahead for noise shape analysis (samples) */ - int TargetRate_bps; /* Target bitrate (bps) */ - int PacketSize_ms; /* Number of milliseconds to put in each packet */ - int PacketLoss_perc; /* Packet loss rate measured by farend */ - int frameCounter; - int Complexity; /* Complexity setting: 0-> low; 1-> medium; 2->high */ - int nStatesDelayedDecision; /* Number of states in delayed decision quantization */ - int useInterpolatedNLSFs; /* Flag for using NLSF interpolation */ - int shapingLPCOrder; /* Filter order for noise shaping filters */ - int predictLPCOrder; /* Filter order for prediction filters */ - int pitchEstimationComplexity; /* Complexity level for pitch estimator */ - int pitchEstimationLPCOrder; /* Whitening filter order for pitch estimator */ - int LTPQuantLowComplexity; /* Flag for low complexity LTP quantization */ - int NLSF_MSVQ_Survivors; /* Number of survivors in NLSF MSVQ */ - int first_frame_after_reset; /* Flag for deactivating NLSF interp. and fluc. reduction after resets */ - - /* Input/output buffering */ - short[] inputBuf = new short[ Silk_define.MAX_FRAME_LENGTH ]; /* buffer containin input signal */ - int inputBufIx; - int nFramesInPayloadBuf; /* number of frames sitting in outputBuf */ - int nBytesInPayloadBuf; /* number of bytes sitting in outputBuf */ - - /* Parameters For LTP scaling Control */ - int frames_since_onset; - - SKP_Silk_NLSF_CB_struct[] psNLSF_CB = new SKP_Silk_NLSF_CB_struct[ 2 ]; /* Pointers to voiced/unvoiced NLSF codebooks */ - - /* Struct for Inband LBRR */ - SKP_SILK_LBRR_struct[] LBRR_buffer = new SKP_SILK_LBRR_struct[ Silk_define.MAX_LBRR_DELAY ]; - /* - * LBRR_buffer is an array of references, which has to be created manually. - */ - { - for(int LBRR_bufferIni_i=0; LBRR_bufferIni_i>> 2 ); - nrg = (int)( ((nrg)&0xFFFFFFFFL) >>> 2 ); - shft = 2; - break; - } - } - for( ; i < len; i += 2 ) { - /* Load two values at once */ - in32 = x[x_offset + i]; - nrg_tmp = Silk_macros.SKP_SMULBB( in32, in32 ); - nrg_tmp = Silk_SigProc_FIX.SKP_SMLATT_ovflw( nrg_tmp, in32, in32 ); -// TODO: ??? -// nrg = (int)SKP_ADD_RSHIFT_uint( nrg, (SKP_uint32)nrg_tmp, shft ); - nrg = nrg + (nrg_tmp>>>shft); -//or nrg = (int)( nrg + (((long)nrg_tmp)&0xFFFFFFFFL) >>> shft ); - - if( nrg < 0 ) { - /* Scale down */ - nrg = ( nrg >>> 2 ); - shft += 2; - } - } - if( i == len ) { - /* One sample left to process */ - nrg_tmp = Silk_macros.SKP_SMULBB( x[ x_offset + i ], x[ x_offset + i ] ); -//TODO: -// nrg = (int)SKP_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); - nrg = ( nrg + (nrg_tmp >>> shft) ); - } - - /* Make sure to have at least one extra leading zero (two leading zeros in total) */ - if( (nrg & 0xC0000000) != 0 ) { - nrg = ( nrg >>> 2 ); - shft += 2; - } - - /* Output arguments */ - shift[0] = shft; - energy[0] = nrg; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables.java deleted file mode 100644 index 9b308c3e4..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -public class Silk_tables -{ - static final int PITCH_EST_MAX_LAG_MS = 18; /* 18 ms -> 56 Hz */ - static final int PITCH_EST_MIN_LAG_MS = 2; /* 2 ms -> 500 Hz */ - - /** - * Copies the specified range of the specified array into a new array. The - * initial index of the range (from) must lie between zero and - * original.length, inclusive. The value at original[from] - * is placed into the initial element of the copy (unless - * from == original.length or from == to). Values from - * subsequent elements in the original array are placed into subsequent - * elements in the copy. The final index of the range (to), which - * must be greater than or equal to from, may be greater than - * original.length, in which case 0 is placed in all - * elements of the copy whose index is greater than or equal to - * original.length - from. The length of the returned array will be - * to - from. - * - * @param original the array from which a range is to be copied - * @param from the initial index of the range to be copied, inclusive - * @param to the final index of the range to be copied, exclusive. (This - * index may lie outside the array.) - * @return a new array containing the specified range from the original - * array, truncated or padded with zeros to obtain the required length - * @throws ArrayIndexOutOfBoundsException if from < 0 or - * from > original.length() - * @throws IllegalArgumentException if from > to - * @throws NullPointerException if original is null - */ - static int[] copyOfRange(int[] original, int from, int to) - { - if ((from < 0) || (from > original.length)) - throw new ArrayIndexOutOfBoundsException(from); - if (from > to) - throw new IllegalArgumentException("to"); - - int length = to - from; - int[] copy = new int[length]; - - for (int c = 0, o = from; c < length; c++, o++) - copy[c] = (o < original.length) ? original[o] : 0; - - return copy; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_LTP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_LTP.java deleted file mode 100644 index cd31cb2dc..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_LTP.java +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_tables_LTP -{ - static int[] SKP_Silk_LTP_per_index_CDF = { - 0, 20992, 40788, 65535 - }; - - static final int SKP_Silk_LTP_per_index_CDF_offset = 1; - - static int[] SKP_Silk_LTP_gain_CDF_0 = { - 0, 49380, 54463, 56494, 58437, 60101, 61683, 62985, - 64066, 64823, 65535 - }; - - static int[] SKP_Silk_LTP_gain_CDF_1 = { - 0, 25290, 30654, 35710, 40386, 42937, 45250, 47459, - 49411, 51348, 52974, 54517, 55976, 57423, 58865, 60285, - 61667, 62895, 63827, 64724, 65535 - }; - - static int[] SKP_Silk_LTP_gain_CDF_2 = { - 0, 4958, 9439, 13581, 17638, 21651, 25015, 28025, - 30287, 32406, 34330, 36240, 38130, 39790, 41281, 42764, - 44229, 45676, 47081, 48431, 49675, 50849, 51932, 52966, - 53957, 54936, 55869, 56789, 57708, 58504, 59285, 60043, - 60796, 61542, 62218, 62871, 63483, 64076, 64583, 65062, - 65535 - }; - - static int[] SKP_Silk_LTP_gain_CDF_offsets = { - 1, 3, 10 - }; - - static final int SKP_Silk_LTP_gain_middle_avg_RD_Q14 = 11010; - - static short[] SKP_Silk_LTP_gain_BITS_Q6_0 = { - 26, 236, 321, 325, 339, 344, 362, 379, - 412, 418 - }; - - static short[] SKP_Silk_LTP_gain_BITS_Q6_1 = { - 88, 231, 237, 244, 300, 309, 313, 324, - 325, 341, 346, 351, 352, 352, 354, 356, - 367, 393, 396, 406 - }; - - static short[] SKP_Silk_LTP_gain_BITS_Q6_2 = { - 238, 248, 255, 257, 258, 274, 284, 311, - 317, 326, 326, 327, 339, 349, 350, 351, - 352, 355, 358, 366, 371, 379, 383, 387, - 388, 393, 394, 394, 407, 409, 412, 412, - 413, 422, 426, 432, 434, 449, 454, 455 - }; - - static int[][] SKP_Silk_LTP_gain_CDF_ptrs = { - SKP_Silk_LTP_gain_CDF_0, - SKP_Silk_LTP_gain_CDF_1, - SKP_Silk_LTP_gain_CDF_2 - }; - - static short[][] SKP_Silk_LTP_gain_BITS_Q6_ptrs = { - SKP_Silk_LTP_gain_BITS_Q6_0, - SKP_Silk_LTP_gain_BITS_Q6_1, - SKP_Silk_LTP_gain_BITS_Q6_2 - }; - - static short[][] SKP_Silk_LTP_gain_vq_0_Q14 = - { - { - 594, 984, 2840, 1021, 669 - }, - { - 10, 35, 304, -1, 23 - }, - { - -694, 1923, 4603, 2975, 2335 - }, - { - 2437, 3176, 3778, 1940, 481 - }, - { - 214, -46, 7870, 4406, -521 - }, - { - -896, 4818, 8501, 1623, -887 - }, - { - -696, 3178, 6480, -302, 1081 - }, - { - 517, 599, 1002, 567, 560 - }, - { - -2075, -834, 4712, -340, 896 - }, - { - 1435, -644, 3993, -612, -2063 - } - }; - - static short[][] SKP_Silk_LTP_gain_vq_1_Q14 = - { - { - 1655, 2918, 5001, 3010, 1775 - }, - { - 113, 198, 856, 176, 178 - }, - { - -843, 2479, 7858, 5371, 574 - }, - { - 59, 5356, 7648, 2850, -315 - }, - { - 3840, 4851, 6527, 1583, -1233 - }, - { - 1620, 1760, 2330, 1876, 2045 - }, - { - -545, 1854, 11792, 1547, -307 - }, - { - -604, 689, 5369, 5074, 4265 - }, - { - 521, -1331, 9829, 6209, -1211 - }, - { - -1315, 6747, 9929, -1410, 546 - }, - { - 117, -144, 2810, 1649, 5240 - }, - { - 5392, 3476, 2425, -38, 633 - }, - { - 14, -449, 5274, 3547, -171 - }, - { - -98, 395, 9114, 1676, 844 - }, - { - -908, 3843, 8861, -957, 1474 - }, - { - 396, 6747, 5379, -329, 1269 - }, - { - -335, 2830, 4281, 270, -54 - }, - { - 1502, 5609, 8958, 6045, 2059 - }, - { - -370, 479, 5267, 5726, 1174 - }, - { - 5237, -1144, 6510, 455, 512 - } - }; - - static short[][] SKP_Silk_LTP_gain_vq_2_Q14 = - { - { - -278, 415, 9345, 7106, -431 - }, - { - -1006, 3863, 9524, 4724, -871 - }, - { - -954, 4624, 11722, 973, -300 - }, - { - -117, 7066, 8331, 1959, -901 - }, - { - 593, 3412, 6070, 4914, 1567 - }, - { - 54, -51, 12618, 4228, -844 - }, - { - 3157, 4822, 5229, 2313, 717 - }, - { - -244, 1161, 14198, 779, 69 - }, - { - -1218, 5603, 12894, -2301, 1001 - }, - { - -132, 3960, 9526, 577, 1806 - }, - { - -1633, 8815, 10484, -2452, 895 - }, - { - 235, 450, 1243, 667, 437 - }, - { - 959, -2630, 10897, 8772, -1852 - }, - { - 2420, 2046, 8893, 4427, -1569 - }, - { - 23, 7091, 8356, -1285, 1508 - }, - { - -1133, 835, 7662, 6043, 2800 - }, - { - 439, 391, 11016, 2253, 1362 - }, - { - -1020, 2876, 13436, 4015, -3020 - }, - { - 1060, -2690, 13512, 5565, -1394 - }, - { - -1420, 8007, 11421, -152, -1672 - }, - { - -893, 2895, 15434, -1490, 159 - }, - { - -1054, 428, 12208, 8538, -3344 - }, - { - 1772, -1304, 7593, 6185, 561 - }, - { - 525, -1207, 6659, 11151, -1170 - }, - { - 439, 2667, 4743, 2359, 5515 - }, - { - 2951, 7432, 7909, -230, -1564 - }, - { - -72, 2140, 5477, 1391, 1580 - }, - { - 476, -1312, 15912, 2174, -1027 - }, - { - 5737, 441, 2493, 2043, 2757 - }, - { - 228, -43, 1803, 6663, 7064 - }, - { - 4596, 9182, 1917, -200, 203 - }, - { - -704, 12039, 5451, -1188, 542 - }, - { - 1782, -1040, 10078, 7513, -2767 - }, - { - -2626, 7747, 9019, 62, 1710 - }, - { - 235, -233, 2954, 10921, 1947 - }, - { - 10854, 2814, 1232, -111, 222 - }, - { - 2267, 2778, 12325, 156, -1658 - }, - { - -2950, 8095, 16330, 268, -3626 - }, - { - 67, 2083, 7950, -80, -2432 - }, - { - 518, -66, 1718, 415, 11435 - } - }; - - private static final short[] SKP_Silk_LTP_gain_vq_0_Q14_00 = - { -// { - 594, 984, 2840, 1021, 669, -// }, -// { - 10, 35, 304, -1, 23, -// }, -// { - -694, 1923, 4603, 2975, 2335, -// }, -// { - 2437, 3176, 3778, 1940, 481, -// }, -// { - 214, -46, 7870, 4406, -521, -// }, -// { - -896, 4818, 8501, 1623, -887, -// }, -// { - -696, 3178, 6480, -302, 1081, -// }, -// { - 517, 599, 1002, 567, 560, -// }, -// { - -2075, -834, 4712, -340, 896, -// }, -// { - 1435, -644, 3993, -612, -2063 -// } - }; - private static final short[] SKP_Silk_LTP_gain_vq_1_Q14_00 = - { -// { - 1655, 2918, 5001, 3010, 1775, -// }, -// { - 113, 198, 856, 176, 178, -// }, -// { - -843, 2479, 7858, 5371, 574, -// }, -// { - 59, 5356, 7648, 2850, -315, -// }, -// { - 3840, 4851, 6527, 1583, -1233, -// }, -// { - 1620, 1760, 2330, 1876, 2045, -// }, -// { - -545, 1854, 11792, 1547, -307, -// }, -// { - -604, 689, 5369, 5074, 4265, -// }, -// { - 521, -1331, 9829, 6209, -1211, -// }, -// { - -1315, 6747, 9929, -1410, 546, -// }, -// { - 117, -144, 2810, 1649, 5240, -// }, -// { - 5392, 3476, 2425, -38, 633, -// }, -// { - 14, -449, 5274, 3547, -171, -// }, -// { - -98, 395, 9114, 1676, 844, -// }, -// { - -908, 3843, 8861, -957, 1474, -// }, -// { - 396, 6747, 5379, -329, 1269, -// }, -// { - -335, 2830, 4281, 270, -54, -// }, -// { - 1502, 5609, 8958, 6045, 2059, -// }, -// { - -370, 479, 5267, 5726, 1174, -// }, -// { - 5237, -1144, 6510, 455, 512 -// } - }; - private static final short[] SKP_Silk_LTP_gain_vq_2_Q14_00 = - { -// { - -278, 415, 9345, 7106, -431, -// }, -// { - -1006, 3863, 9524, 4724, -871, -// }, -// { - -954, 4624, 11722, 973, -300, -// }, -// { - -117, 7066, 8331, 1959, -901, -// }, -// { - 593, 3412, 6070, 4914, 1567, -// }, -// { - 54, -51, 12618, 4228, -844, -// }, -// { - 3157, 4822, 5229, 2313, 717, -// }, -// { - -244, 1161, 14198, 779, 69, -// }, -// { - -1218, 5603, 12894, -2301, 1001, -// }, -// { - -132, 3960, 9526, 577, 1806, -// }, -// { - -1633, 8815, 10484, -2452, 895, -// }, -// { - 235, 450, 1243, 667, 437, -// }, -// { - 959, -2630, 10897, 8772, -1852, -// }, -// { - 2420, 2046, 8893, 4427, -1569, -// }, -// { - 23, 7091, 8356, -1285, 1508, -// }, -// { - -1133, 835, 7662, 6043, 2800, -// }, -// { - 439, 391, 11016, 2253, 1362, -// }, -// { - -1020, 2876, 13436, 4015, -3020, -// }, -// { - 1060, -2690, 13512, 5565, -1394, -// }, -// { - -1420, 8007, 11421, -152, -1672, -// }, -// { - -893, 2895, 15434, -1490, 159, -// }, -// { - -1054, 428, 12208, 8538, -3344, -// }, -// { - 1772, -1304, 7593, 6185, 561, -// }, -// { - 525, -1207, 6659, 11151, -1170, -// }, -// { - 439, 2667, 4743, 2359, 5515, -// }, -// { - 2951, 7432, 7909, -230, -1564, -// }, -// { - -72, 2140, 5477, 1391, 1580, -// }, -// { - 476, -1312, 15912, 2174, -1027, -// }, -// { - 5737, 441, 2493, 2043, 2757, -// }, -// { - 228, -43, 1803, 6663, 7064, -// }, -// { - 4596, 9182, 1917, -200, 203, -// }, -// { - -704, 12039, 5451, -1188, 542, -// }, -// { - 1782, -1040, 10078, 7513, -2767, -// }, -// { - -2626, 7747, 9019, 62, 1710, -// }, -// { - 235, -233, 2954, 10921, 1947, -// }, -// { - 10854, 2814, 1232, -111, 222, -// }, -// { - 2267, 2778, 12325, 156, -1658, -// }, -// { - -2950, 8095, 16330, 268, -3626, -// }, -// { - 67, 2083, 7950, -80, -2432, -// }, -// { - 518, -66, 1718, 415, 11435 -// } - }; - - static short[][] SKP_Silk_LTP_vq_ptrs_Q14 = { - SKP_Silk_LTP_gain_vq_0_Q14_00, - SKP_Silk_LTP_gain_vq_1_Q14_00, - SKP_Silk_LTP_gain_vq_2_Q14_00 - }; - - static int[] SKP_Silk_LTP_vq_sizes = { - 10, 20, 40 - }; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB0_10.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB0_10.java deleted file mode 100644 index 3f1712a75..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB0_10.java +++ /dev/null @@ -1,885 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * This file has been automatically generated - * ROM usage: 0.29 + 2.66 kB - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_tables_NLSF_CB0_10 -{ - static final int NLSF_MSVQ_CB0_10_STAGES = 6; - static final int NLSF_MSVQ_CB0_10_VECTORS = 120; - - static final int[] SKP_Silk_NLSF_MSVQ_CB0_10_CDF = - { - 0, - 2658, - 4420, - 6107, - 7757, - 9408, - 10955, - 12502, - 13983, - 15432, - 16882, - 18331, - 19750, - 21108, - 22409, - 23709, - 25010, - 26256, - 27501, - 28747, - 29965, - 31158, - 32351, - 33544, - 34736, - 35904, - 36997, - 38091, - 39185, - 40232, - 41280, - 42327, - 43308, - 44290, - 45271, - 46232, - 47192, - 48132, - 49032, - 49913, - 50775, - 51618, - 52462, - 53287, - 54095, - 54885, - 55675, - 56449, - 57222, - 57979, - 58688, - 59382, - 60076, - 60726, - 61363, - 61946, - 62505, - 63052, - 63543, - 63983, - 64396, - 64766, - 65023, - 65279, - 65535, - 0, - 4977, - 9542, - 14106, - 18671, - 23041, - 27319, - 31596, - 35873, - 39969, - 43891, - 47813, - 51652, - 55490, - 59009, - 62307, - 65535, - 0, - 8571, - 17142, - 25529, - 33917, - 42124, - 49984, - 57844, - 65535, - 0, - 8732, - 17463, - 25825, - 34007, - 42189, - 50196, - 58032, - 65535, - 0, - 8948, - 17704, - 25733, - 33762, - 41791, - 49821, - 57678, - 65535, - 0, - 4374, - 8655, - 12936, - 17125, - 21313, - 25413, - 29512, - 33611, - 37710, - 41809, - 45820, - 49832, - 53843, - 57768, - 61694, - 65535 - }; - static private int [] SKP_Silk_NLSF_MSVQ_CB0_10_CDF_0 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB0_10_CDF, 0, SKP_Silk_NLSF_MSVQ_CB0_10_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB0_10_CDF_65 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB0_10_CDF, 65, SKP_Silk_NLSF_MSVQ_CB0_10_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB0_10_CDF_82 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB0_10_CDF, 82, SKP_Silk_NLSF_MSVQ_CB0_10_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB0_10_CDF_91 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB0_10_CDF, 91, SKP_Silk_NLSF_MSVQ_CB0_10_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB0_10_CDF_100 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB0_10_CDF, 100, SKP_Silk_NLSF_MSVQ_CB0_10_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB0_10_CDF_109 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB0_10_CDF, 109, SKP_Silk_NLSF_MSVQ_CB0_10_CDF.length); - - static final int[][] SKP_Silk_NLSF_MSVQ_CB0_10_CDF_start_ptr = - { - SKP_Silk_NLSF_MSVQ_CB0_10_CDF_0, - SKP_Silk_NLSF_MSVQ_CB0_10_CDF_65, - SKP_Silk_NLSF_MSVQ_CB0_10_CDF_82, - SKP_Silk_NLSF_MSVQ_CB0_10_CDF_91, - SKP_Silk_NLSF_MSVQ_CB0_10_CDF_100, - SKP_Silk_NLSF_MSVQ_CB0_10_CDF_109 - }; - - static final int[] SKP_Silk_NLSF_MSVQ_CB0_10_CDF_middle_idx = - { - 23, - 8, - 5, - 5, - 5, - 9 - }; - - static final short[] SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5 = - { - 148, 167, - 169, 170, - 170, 173, - 173, 175, - 176, 176, - 176, 177, - 179, 181, - 181, 181, - 183, 183, - 183, 184, - 185, 185, - 185, 185, - 186, 189, - 189, 189, - 191, 191, - 191, 194, - 194, 194, - 195, 195, - 196, 198, - 199, 200, - 201, 201, - 202, 203, - 204, 204, - 205, 205, - 206, 209, - 210, 210, - 213, 214, - 218, 220, - 221, 226, - 231, 234, - 239, 256, - 256, 256, - 119, 123, - 123, 123, - 125, 126, - 126, 126, - 128, 130, - 130, 131, - 131, 135, - 138, 139, - 94, 94, - 95, 95, - 96, 98, - 98, 99, - 93, 93, - 95, 96, - 96, 97, - 98, 100, - 92, 93, - 97, 97, - 97, 97, - 98, 98, - 125, 126, - 126, 127, - 127, 128, - 128, 128, - 128, 128, - 129, 129, - 129, 130, - 130, 131 - }; - - static final int[] SKP_Silk_NLSF_MSVQ_CB0_10_ndelta_min_Q15 = - { - 563, - 3, - 22, - 20, - 3, - 3, - 132, - 119, - 358, - 86, - 964 - }; - - static final short[] SKP_Silk_NLSF_MSVQ_CB0_10_Q15 = - { - 2210, 4023, - 6981, 9260, - 12573, 15687, - 19207, 22383, - 25981, 29142, - 3285, 4172, - 6116, 10856, - 15289, 16826, - 19701, 22010, - 24721, 29313, - 1554, 2511, - 6577, 10337, - 13837, 16511, - 20086, 23214, - 26480, 29464, - 3062, 4017, - 5771, 10037, - 13365, 14952, - 20140, 22891, - 25229, 29603, - 2085, 3457, - 5934, 8718, - 11501, 13670, - 17997, 21817, - 24935, 28745, - 2776, 4093, - 6421, 10413, - 15111, 16806, - 20825, 23826, - 26308, 29411, - 2717, 4034, - 5697, 8463, - 14301, 16354, - 19007, 23413, - 25812, 28506, - 2872, 3702, - 5881, 11034, - 17141, 18879, - 21146, 23451, - 25817, 29600, - 2999, 4015, - 7357, 11219, - 12866, 17307, - 20081, 22644, - 26774, 29107, - 2942, 3866, - 5918, 11915, - 13909, 16072, - 20453, 22279, - 27310, 29826, - 2271, 3527, - 6606, 9729, - 12943, 17382, - 20224, 22345, - 24602, 28290, - 2207, 3310, - 5844, 9339, - 11141, 15651, - 18576, 21177, - 25551, 28228, - 3963, 4975, - 6901, 11588, - 13466, 15577, - 19231, 21368, - 25510, 27759, - 2749, 3549, - 6966, 13808, - 15653, 17645, - 20090, 22599, - 26467, 28537, - 2126, 3504, - 5109, 9954, - 12550, 14620, - 19703, 21687, - 26457, 29106, - 3966, 5745, - 7442, 9757, - 14468, 16404, - 19135, 23048, - 25375, 28391, - 3197, 4751, - 6451, 9298, - 13038, 14874, - 17962, 20627, - 23835, 28464, - 3195, 4081, - 6499, 12252, - 14289, 16040, - 18357, 20730, - 26980, 29309, - 1533, 2471, - 4486, 7796, - 12332, 15758, - 19567, 22298, - 25673, 29051, - 2002, 2971, - 4985, 8083, - 13181, 15435, - 18237, 21517, - 24595, 28351, - 3808, 4925, - 6710, 10201, - 12011, 14300, - 18457, 20391, - 26525, 28956, - 2281, 3418, - 4979, 8726, - 15964, 18104, - 20250, 22771, - 25286, 28954, - 3051, 5479, - 7290, 9848, - 12744, 14503, - 18665, 23684, - 26065, 28947, - 2364, 3565, - 5502, 9621, - 14922, 16621, - 19005, 20996, - 26310, 29302, - 4093, 5212, - 6833, 9880, - 16303, 18286, - 20571, 23614, - 26067, 29128, - 2941, 3996, - 6038, 10638, - 12668, 14451, - 16798, 19392, - 26051, 28517, - 3863, 5212, - 7019, 9468, - 11039, 13214, - 19942, 22344, - 25126, 29539, - 4615, 6172, - 7853, 10252, - 12611, 14445, - 19719, 22441, - 24922, 29341, - 3566, 4512, - 6985, 8684, - 10544, 16097, - 18058, 22475, - 26066, 28167, - 4481, 5489, - 7432, 11414, - 13191, 15225, - 20161, 22258, - 26484, 29716, - 3320, 4320, - 6621, 9867, - 11581, 14034, - 21168, 23210, - 26588, 29903, - 3794, 4689, - 6916, 8655, - 10143, 16144, - 19568, 21588, - 27557, 29593, - 2446, 3276, - 5918, 12643, - 16601, 18013, - 21126, 23175, - 27300, 29634, - 2450, 3522, - 5437, 8560, - 15285, 19911, - 21826, 24097, - 26567, 29078, - 2580, 3796, - 5580, 8338, - 9969, 12675, - 18907, 22753, - 25450, 29292, - 3325, 4312, - 6241, 7709, - 9164, 14452, - 21665, 23797, - 27096, 29857, - 3338, 4163, - 7738, 11114, - 12668, 14753, - 16931, 22736, - 25671, 28093, - 3840, 4755, - 7755, 13471, - 15338, 17180, - 20077, 22353, - 27181, 29743, - 2504, 4079, - 8351, 12118, - 15046, 18595, - 21684, 24704, - 27519, 29937, - 5234, 6342, - 8267, 11821, - 15155, 16760, - 20667, 23488, - 25949, 29307, - 2681, 3562, - 6028, 10827, - 18458, 20458, - 22303, 24701, - 26912, 29956, - 3374, 4528, - 6230, 8256, - 9513, 12730, - 18666, 20720, - 26007, 28425, - 2731, 3629, - 8320, 12450, - 14112, 16431, - 18548, 22098, - 25329, 27718, - 3481, 4401, - 7321, 9319, - 11062, 13093, - 15121, 22315, - 26331, 28740, - 3577, 4945, - 6669, 8792, - 10299, 12645, - 19505, 24766, - 26996, 29634, - 4058, 5060, - 7288, 10190, - 11724, 13936, - 15849, 18539, - 26701, 29845, - 4262, 5390, - 7057, 8982, - 10187, 15264, - 20480, 22340, - 25958, 28072, - 3404, 4329, - 6629, 7946, - 10121, 17165, - 19640, 22244, - 25062, 27472, - 3157, 4168, - 6195, 9319, - 10771, 13325, - 15416, 19816, - 24672, 27634, - 2503, 3473, - 5130, 6767, - 8571, 14902, - 19033, 21926, - 26065, 28728, - 4133, 5102, - 7553, 10054, - 11757, 14924, - 17435, 20186, - 23987, 26272, - 4972, 6139, - 7894, 9633, - 11320, 14295, - 21737, 24306, - 26919, 29907, - 2958, 3816, - 6851, 9204, - 10895, 18052, - 20791, 23338, - 27556, 29609, - 5234, 6028, - 8034, 10154, - 11242, 14789, - 18948, 20966, - 26585, 29127, - 5241, 6838, - 10526, 12819, - 14681, 17328, - 19928, 22336, - 26193, 28697, - 3412, 4251, - 5988, 7094, - 9907, 18243, - 21669, 23777, - 26969, 29087, - 2470, 3217, - 7797, 15296, - 17365, 19135, - 21979, 24256, - 27322, 29442, - 4939, 5804, - 8145, 11809, - 13873, 15598, - 17234, 19423, - 26476, 29645, - 5051, 6167, - 8223, 9655, - 12159, 17995, - 20464, 22832, - 26616, 28462, - 4987, 5907, - 9319, 11245, - 13132, 15024, - 17485, 22687, - 26011, 28273, - 5137, 6884, - 11025, 14950, - 17191, 19425, - 21807, 24393, - 26938, 29288, - 7057, 7884, - 9528, 10483, - 10960, 14811, - 19070, 21675, - 25645, 28019, - 6759, 7160, - 8546, 11779, - 12295, 13023, - 16627, 21099, - 24697, 28287, - 3863, 9762, - 11068, 11445, - 12049, 13960, - 18085, 21507, - 25224, 28997, - 397, 335, - 651, 1168, - 640, 765, - 465, 331, - 214, -194, - -578, -647, - -657, 750, - 564, 613, - 549, 630, - 304, -52, - 828, 922, - 443, 111, - 138, 124, - 169, 14, - 144, 83, - 132, 58, - -413, -752, - 869, 336, - 385, 69, - 56, 830, - -227, -266, - -368, -440, - -1195, 163, - 126, -228, - 802, 156, - 188, 120, - 376, 59, - -358, -558, - -1326, -254, - -202, -789, - 296, 92, - -70, -129, - -718, -1135, - 292, -29, - -631, 487, - -157, -153, - -279, 2, - -419, -342, - -34, -514, - -799, -1571, - -687, -609, - -546, -130, - -215, -252, - -446, -574, - -1337, 207, - -72, 32, - 103, -642, - 942, 733, - 187, 29, - -211, -814, - 143, 225, - 20, 24, - -268, -377, - 1623, 1133, - 667, 164, - 307, 366, - 187, 34, - 62, -313, - -832, -1482, - -1181, 483, - -42, -39, - -450, -1406, - -587, -52, - -760, 334, - 98, -60, - -500, -488, - -1058, 299, - 131, -250, - -251, -703, - 1037, 568, - -413, -265, - 1687, 573, - 345, 323, - 98, 61, - -102, 31, - 135, 149, - 617, 365, - -39, 34, - -611, 1201, - 1421, 736, - -414, -393, - -492, -343, - -316, -532, - 528, 172, - 90, 322, - -294, -319, - -541, 503, - 639, 401, - 1, -149, - -73, -167, - 150, 118, - 308, 218, - 121, 195, - -143, -261, - -1013, -802, - 387, 436, - 130, -427, - -448, -681, - 123, -87, - -251, -113, - 274, 310, - 445, 501, - 354, 272, - 141, -285, - 569, 656, - 37, -49, - 251, -386, - -263, 1122, - 604, 606, - 336, 95, - 34, 0, - 85, 180, - 207, -367, - -622, 1070, - -6, -79, - -160, -92, - -137, -276, - -323, -371, - -696, -1036, - 407, 102, - -86, -214, - -482, -647, - -28, -291, - -97, -180, - -250, -435, - -18, -76, - -332, 410, - 407, 168, - 539, 411, - 254, 111, - 58, -145, - 200, 30, - 187, 116, - 131, -367, - -475, 781, - -559, 561, - 195, -115, - 8, -168, - 30, 55, - -122, 131, - 82, -5, - -273, -50, - -632, 668, - 4, 32, - -26, -279, - 315, 165, - 197, 377, - 155, -41, - -138, -324, - -109, -617, - 360, 98, - -53, -319, - -114, -245, - -82, 507, - 468, 263, - -137, -389, - 652, 354, - -18, -227, - -462, -135, - 317, 53, - -16, 66, - -72, -126, - -356, -347, - -328, -72, - -337, 324, - 152, 349, - 169, -196, - 179, 254, - 260, 325, - -74, -80, - 75, -31, - 270, 275, - 87, 278, - -446, -301, - 309, 71, - -25, -242, - 516, 161, - -162, -83, - 329, 230, - -311, -259, - 177, -26, - -462, 89, - 257, 6, - -130, -93, - -456, -317, - -221, -206, - -417, -182, - -74, 234, - 48, 261, - 359, 231, - 258, 85, - -282, 252, - -147, -222, - 251, -207, - 443, 123, - -417, -36, - 273, -241, - 240, -112, - 44, -167, - 126, -124, - -77, 58, - -401, 333, - -118, 82, - 126, 151, - -433, 359, - -130, -102, - 131, -244, - 86, 85, - -462, 414, - -240, 16, - 145, 28, - -205, -481, - 373, 293, - -72, -174, - 62, 259, - -8, -18, - 362, 233, - 185, 43, - 278, 27, - 193, 570, - -248, 189, - 92, 31, - -275, -3, - 243, 176, - 438, 209, - 206, -51, - 79, 109, - 168, -185, - -308, -68, - -618, 385, - -310, -108, - -164, 165, - 61, -152, - -101, -412, - -268, -257, - -40, -20, - -28, -158, - -301, 271, - 380, -338, - -367, -132, - 64, 114, - -131, -225, - -156, -260, - -63, -116, - 155, -586, - -202, 254, - -287, 178, - 227, -106, - -294, 164, - 298, -100, - 185, 317, - 193, -45, - 28, 80, - -87, -433, - 22, -48, - 48, -237, - -229, -139, - 120, -364, - 268, -136, - 396, 125, - 130, -89, - -272, 118, - -256, -68, - -451, 488, - 143, -165, - -48, -190, - 106, 219, - 47, 435, - 245, 97, - 75, -418, - 121, -187, - 570, -200, - -351, 225, - -21, -217, - 234, -111, - 194, 14, - 242, 118, - 140, -397, - 355, 361, - -45, -195 - }; - - static final SKP_Silk_NLSF_CBS[] SKP_Silk_NLSF_CB0_10_Stage_info= - { - new SKP_Silk_NLSF_CBS(64, SKP_Silk_NLSF_MSVQ_CB0_10_Q15, 10*0, SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5, 0), - new SKP_Silk_NLSF_CBS(16, SKP_Silk_NLSF_MSVQ_CB0_10_Q15, 10*64, SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5, 64), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB0_10_Q15, 10*80, SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5, 80), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB0_10_Q15, 10*88, SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5, 88), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB0_10_Q15, 10*96, SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5, 96), - new SKP_Silk_NLSF_CBS(16, SKP_Silk_NLSF_MSVQ_CB0_10_Q15, 10*104, SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5, 104) - }; - - static final SKP_Silk_NLSF_CB_struct SKP_Silk_NLSF_CB0_10 = - new SKP_Silk_NLSF_CB_struct( - NLSF_MSVQ_CB0_10_STAGES, - SKP_Silk_NLSF_CB0_10_Stage_info, - SKP_Silk_NLSF_MSVQ_CB0_10_ndelta_min_Q15, - SKP_Silk_NLSF_MSVQ_CB0_10_CDF, - SKP_Silk_NLSF_MSVQ_CB0_10_CDF_start_ptr, - SKP_Silk_NLSF_MSVQ_CB0_10_CDF_middle_idx - ); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB0_10_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB0_10_FLP.java deleted file mode 100644 index edcab768b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB0_10_FLP.java +++ /dev/null @@ -1,740 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * This file has been automatically generated. - * ROM usage: 5.32 kB - * - * @author Dingxin Xu - */ -public class Silk_tables_NLSF_CB0_10_FLP -{ -// const SKP_float SKP_Silk_NLSF_MSVQ_CB0_10_rates[ NLSF_MSVQ_CB0_10_VECTORS ] = - static final float SKP_Silk_NLSF_MSVQ_CB0_10_rates[] = - { - 4.62500000000000000000f, 5.21875000000000000000f, - 5.28125000000000000000f, 5.31250000000000000000f, - 5.31250000000000000000f, 5.40625000000000000000f, - 5.40625000000000000000f, 5.46875000000000000000f, - 5.50000000000000000000f, 5.50000000000000000000f, - 5.50000000000000000000f, 5.53125000000000000000f, - 5.59375000000000000000f, 5.65625000000000000000f, - 5.65625000000000000000f, 5.65625000000000000000f, - 5.71875000000000000000f, 5.71875000000000000000f, - 5.71875000000000000000f, 5.75000000000000000000f, - 5.78125000000000000000f, 5.78125000000000000000f, - 5.78125000000000000000f, 5.78125000000000000000f, - 5.81250000000000000000f, 5.90625000000000000000f, - 5.90625000000000000000f, 5.90625000000000000000f, - 5.96875000000000000000f, 5.96875000000000000000f, - 5.96875000000000000000f, 6.06250000000000000000f, - 6.06250000000000000000f, 6.06250000000000000000f, - 6.09375000000000000000f, 6.09375000000000000000f, - 6.12500000000000000000f, 6.18750000000000000000f, - 6.21875000000000000000f, 6.25000000000000000000f, - 6.28125000000000000000f, 6.28125000000000000000f, - 6.31250000000000000000f, 6.34375000000000000000f, - 6.37500000000000000000f, 6.37500000000000000000f, - 6.40625000000000000000f, 6.40625000000000000000f, - 6.43750000000000000000f, 6.53125000000000000000f, - 6.56250000000000000000f, 6.56250000000000000000f, - 6.65625000000000000000f, 6.68750000000000000000f, - 6.81250000000000000000f, 6.87500000000000000000f, - 6.90625000000000000000f, 7.06250000000000000000f, - 7.21875000000000000000f, 7.31250000000000000000f, - 7.46875000000000000000f, 8.00000000000000000000f, - 8.00000000000000000000f, 8.00000000000000000000f, - 3.71875000000000000000f, 3.84375000000000000000f, - 3.84375000000000000000f, 3.84375000000000000000f, - 3.90625000000000000000f, 3.93750000000000000000f, - 3.93750000000000000000f, 3.93750000000000000000f, - 4.00000000000000000000f, 4.06250000000000000000f, - 4.06250000000000000000f, 4.09375000000000000000f, - 4.09375000000000000000f, 4.21875000000000000000f, - 4.31250000000000000000f, 4.34375000000000000000f, - 2.93750000000000000000f, 2.93750000000000000000f, - 2.96875000000000000000f, 2.96875000000000000000f, - 3.00000000000000000000f, 3.06250000000000000000f, - 3.06250000000000000000f, 3.09375000000000000000f, - 2.90625000000000000000f, 2.90625000000000000000f, - 2.96875000000000000000f, 3.00000000000000000000f, - 3.00000000000000000000f, 3.03125000000000000000f, - 3.06250000000000000000f, 3.12500000000000000000f, - 2.87500000000000000000f, 2.90625000000000000000f, - 3.03125000000000000000f, 3.03125000000000000000f, - 3.03125000000000000000f, 3.03125000000000000000f, - 3.06250000000000000000f, 3.06250000000000000000f, - 3.90625000000000000000f, 3.93750000000000000000f, - 3.93750000000000000000f, 3.96875000000000000000f, - 3.96875000000000000000f, 4.00000000000000000000f, - 4.00000000000000000000f, 4.00000000000000000000f, - 4.00000000000000000000f, 4.00000000000000000000f, - 4.03125000000000000000f, 4.03125000000000000000f, - 4.03125000000000000000f, 4.06250000000000000000f, - 4.06250000000000000000f, 4.09375000000000000000f - }; - -// const SKP_float SKP_Silk_NLSF_MSVQ_CB0_10_ndelta_min[ 10 + 1 ] = - static final float SKP_Silk_NLSF_MSVQ_CB0_10_ndelta_min[] = - { - 0.01718139648437500000f, - 0.00009155273437500000f, - 0.00067138671874999989f, - 0.00061035156250000000f, - 0.00009155273437500000f, - 0.00009155273437500000f, - 0.00402832031250000000f, - 0.00363159179687500000f, - 0.01092529296875000000f, - 0.00262451171875000000f, - 0.02941894531250000300f - }; - -// const SKP_float SKP_Silk_NLSF_MSVQ_CB0_10[ 10 * NLSF_MSVQ_CB0_10_VECTORS ] = - static final float SKP_Silk_NLSF_MSVQ_CB0_10[] = - { - 0.06744384765625000000f, 0.12277221679687500000f, - 0.21304321289062497000f, 0.28259277343750000000f, - 0.38369750976562500000f, 0.47872924804687500000f, - 0.58615112304687500000f, 0.68307495117187489000f, - 0.79287719726562500000f, 0.88934326171875011000f, - 0.10025024414062500000f, 0.12731933593750000000f, - 0.18664550781250003000f, 0.33129882812500000000f, - 0.46658325195312494000f, 0.51348876953125000000f, - 0.60122680664062500000f, 0.67169189453125000000f, - 0.75442504882812500000f, 0.89456176757812500000f, - 0.04742431640624999300f, 0.07662963867187500000f, - 0.20071411132812500000f, 0.31546020507812500000f, - 0.42227172851562494000f, 0.50387573242187500000f, - 0.61297607421875000000f, 0.70843505859375000000f, - 0.80810546875000000000f, 0.89916992187500000000f, - 0.09344482421875000000f, 0.12258911132812500000f, - 0.17611694335937500000f, 0.30630493164062500000f, - 0.40786743164062500000f, 0.45629882812500000000f, - 0.61462402343750000000f, 0.69857788085937500000f, - 0.76992797851562500000f, 0.90341186523437500000f, - 0.06362915039062500000f, 0.10549926757812500000f, - 0.18109130859375000000f, 0.26605224609375000000f, - 0.35098266601562494000f, 0.41717529296875000000f, - 0.54922485351562500000f, 0.66580200195312500000f, - 0.76095581054687489000f, 0.87722778320312500000f, - 0.08471679687500000000f, 0.12490844726562501000f, - 0.19595336914062500000f, 0.31777954101562500000f, - 0.46115112304687500000f, 0.51287841796875000000f, - 0.63552856445312500000f, 0.72711181640625000000f, - 0.80285644531250000000f, 0.89755249023437500000f, - 0.08291625976562498600f, 0.12310791015625000000f, - 0.17385864257812500000f, 0.25827026367187500000f, - 0.43643188476562500000f, 0.49908447265625000000f, - 0.58004760742187500000f, 0.71450805664062500000f, - 0.78771972656249989000f, 0.86993408203125011000f, - 0.08764648437500000000f, 0.11297607421875001000f, - 0.17947387695312500000f, 0.33673095703124994000f, - 0.52310180664062500000f, 0.57614135742187500000f, - 0.64532470703125000000f, 0.71566772460937500000f, - 0.78787231445312500000f, 0.90332031250000000000f, - 0.09152221679687500000f, 0.12252807617187500000f, - 0.22451782226562500000f, 0.34237670898437500000f, - 0.39263916015625000000f, 0.52816772460937500000f, - 0.61282348632812500000f, 0.69104003906250000000f, - 0.81707763671875000000f, 0.88827514648437500000f, - 0.08978271484375000000f, 0.11798095703125000000f, - 0.18060302734375003000f, 0.36361694335937500000f, - 0.42446899414062500000f, 0.49047851562500000000f, - 0.62417602539062500000f, 0.67990112304687500000f, - 0.83343505859375000000f, 0.91021728515625011000f, - 0.06930541992187500000f, 0.10763549804687500000f, - 0.20159912109375000000f, 0.29690551757812500000f, - 0.39498901367187506000f, 0.53045654296875000000f, - 0.61718750000000000000f, 0.68191528320312500000f, - 0.75079345703125000000f, 0.86334228515624989000f, - 0.06735229492187500000f, 0.10101318359375000000f, - 0.17834472656250000000f, 0.28500366210937500000f, - 0.33999633789062500000f, 0.47763061523437506000f, - 0.56689453125000000000f, 0.64627075195312511000f, - 0.77975463867187489000f, 0.86145019531250011000f, - 0.12094116210937500000f, 0.15182495117187500000f, - 0.21060180664062500000f, 0.35363769531250000000f, - 0.41094970703125000000f, 0.47537231445312494000f, - 0.58688354492187500000f, 0.65209960937500000000f, - 0.77850341796875000000f, 0.84713745117187500000f, - 0.08389282226562500000f, 0.10830688476562500000f, - 0.21258544921875000000f, 0.42138671875000000000f, - 0.47769165039062500000f, 0.53848266601562500000f, - 0.61309814453125000000f, 0.68966674804687511000f, - 0.80770874023437500000f, 0.87088012695312489000f, - 0.06488037109375000000f, 0.10693359375000001000f, - 0.15591430664062500000f, 0.30377197265625000000f, - 0.38299560546875006000f, 0.44616699218750000000f, - 0.60128784179687500000f, 0.66183471679687500000f, - 0.80740356445312500000f, 0.88824462890625000000f, - 0.12103271484375000000f, 0.17532348632812500000f, - 0.22711181640625000000f, 0.29776000976562500000f, - 0.44152832031250000000f, 0.50061035156250000000f, - 0.58395385742187500000f, 0.70336914062500000000f, - 0.77438354492187489000f, 0.86642456054687500000f, - 0.09756469726562500000f, 0.14498901367187500000f, - 0.19686889648437500000f, 0.28375244140625000000f, - 0.39788818359374994000f, 0.45391845703125000000f, - 0.54815673828125000000f, 0.62948608398437500000f, - 0.72738647460937500000f, 0.86865234375000000000f, - 0.09750366210937500000f, 0.12454223632812500000f, - 0.19833374023437500000f, 0.37390136718750000000f, - 0.43606567382812500000f, 0.48950195312500000000f, - 0.56021118164062500000f, 0.63262939453125000000f, - 0.82336425781250000000f, 0.89443969726562489000f, - 0.04678344726562500000f, 0.07540893554687500000f, - 0.13690185546875000000f, 0.23791503906250000000f, - 0.37634277343750000000f, 0.48089599609375000000f, - 0.59713745117187500000f, 0.68048095703124989000f, - 0.78347778320312489000f, 0.88656616210937511000f, - 0.06109619140625000000f, 0.09066772460937500000f, - 0.15213012695312500000f, 0.24667358398437497000f, - 0.40225219726562500000f, 0.47103881835937500000f, - 0.55654907226562500000f, 0.65664672851562500000f, - 0.75057983398437500000f, 0.86520385742187500000f, - 0.11621093750000000000f, 0.15029907226562500000f, - 0.20477294921875003000f, 0.31130981445312500000f, - 0.36654663085937500000f, 0.43640136718750000000f, - 0.56326293945312500000f, 0.62228393554687500000f, - 0.80947875976562500000f, 0.88366699218750000000f, - 0.06961059570312500000f, 0.10430908203125000000f, - 0.15194702148437500000f, 0.26629638671875000000f, - 0.48718261718750000000f, 0.55249023437500000000f, - 0.61798095703125000000f, 0.69491577148437500000f, - 0.77166748046875000000f, 0.88360595703125000000f, - 0.09310913085937500000f, 0.16720581054687500000f, - 0.22247314453125000000f, 0.30053710937500000000f, - 0.38891601562500000000f, 0.44259643554687500000f, - 0.56961059570312500000f, 0.72277832031250000000f, - 0.79544067382812511000f, 0.88339233398437500000f, - 0.07214355468750000000f, 0.10879516601562499000f, - 0.16790771484375000000f, 0.29360961914062500000f, - 0.45538330078125000000f, 0.50723266601562500000f, - 0.57998657226562500000f, 0.64074707031250000000f, - 0.80291748046875000000f, 0.89422607421875000000f, - 0.12490844726562501000f, 0.15905761718750000000f, - 0.20852661132812500000f, 0.30151367187500000000f, - 0.49752807617187500000f, 0.55804443359375000000f, - 0.62777709960937500000f, 0.72064208984375000000f, - 0.79550170898437500000f, 0.88891601562500000000f, - 0.08975219726562500000f, 0.12194824218750000000f, - 0.18426513671875000000f, 0.32464599609374994000f, - 0.38659667968750000000f, 0.44100952148437500000f, - 0.51263427734375000000f, 0.59179687500000000000f, - 0.79501342773437500000f, 0.87026977539062489000f, - 0.11788940429687500000f, 0.15905761718750000000f, - 0.21420288085937500000f, 0.28894042968750000000f, - 0.33688354492187500000f, 0.40325927734374994000f, - 0.60858154296875000000f, 0.68188476562500000000f, - 0.76678466796875000000f, 0.90145874023437489000f, - 0.14083862304687500000f, 0.18835449218749997000f, - 0.23965454101562500000f, 0.31286621093750000000f, - 0.38485717773437506000f, 0.44082641601562500000f, - 0.60177612304687500000f, 0.68484497070312500000f, - 0.76055908203125000000f, 0.89541625976562500000f, - 0.10882568359375000000f, 0.13769531250000000000f, - 0.21316528320312500000f, 0.26501464843750000000f, - 0.32177734375000000000f, 0.49124145507812500000f, - 0.55108642578125000000f, 0.68588256835937500000f, - 0.79547119140625000000f, 0.85958862304687500000f, - 0.13674926757812500000f, 0.16751098632812500000f, - 0.22680664062500000000f, 0.34832763671875000000f, - 0.40255737304687500000f, 0.46463012695312500000f, - 0.61526489257812500000f, 0.67926025390625000000f, - 0.80822753906250000000f, 0.90686035156250000000f, - 0.10131835937500000000f, 0.13183593750000000000f, - 0.20205688476562500000f, 0.30111694335937500000f, - 0.35342407226562500000f, 0.42828369140625000000f, - 0.64599609375000000000f, 0.70831298828125000000f, - 0.81140136718750000000f, 0.91256713867187500000f, - 0.11578369140625000000f, 0.14309692382812500000f, - 0.21105957031250000000f, 0.26412963867187500000f, - 0.30953979492187500000f, 0.49267578125000000000f, - 0.59716796875000000000f, 0.65881347656250000000f, - 0.84097290039062500000f, 0.90310668945312489000f, - 0.07464599609375000000f, 0.09997558593750000000f, - 0.18060302734375003000f, 0.38583374023437500000f, - 0.50662231445312500000f, 0.54971313476562500000f, - 0.64471435546875011000f, 0.70724487304687489000f, - 0.83312988281250000000f, 0.90435791015625000000f, - 0.07476806640625000000f, 0.10748291015625000000f, - 0.16592407226562500000f, 0.26123046875000000000f, - 0.46646118164062500000f, 0.60763549804687500000f, - 0.66607666015625000000f, 0.73538208007812500000f, - 0.81076049804687489000f, 0.88739013671875000000f, - 0.07873535156250000000f, 0.11584472656249999000f, - 0.17028808593750000000f, 0.25445556640625000000f, - 0.30422973632812500000f, 0.38681030273437500000f, - 0.57699584960937500000f, 0.69436645507812500000f, - 0.77667236328125000000f, 0.89392089843749989000f, - 0.10147094726562500000f, 0.13159179687500000000f, - 0.19046020507812500000f, 0.23526000976562500000f, - 0.27966308593750000000f, 0.44104003906250000000f, - 0.66116333007812489000f, 0.72622680664062511000f, - 0.82690429687500000000f, 0.91116333007812489000f, - 0.10186767578125000000f, 0.12704467773437500000f, - 0.23614501953125000000f, 0.33917236328125000000f, - 0.38659667968750000000f, 0.45022583007812500000f, - 0.51669311523437500000f, 0.69384765625000000000f, - 0.78341674804687500000f, 0.85733032226562500000f, - 0.11718749999999999000f, 0.14511108398437500000f, - 0.23666381835937500000f, 0.41110229492187506000f, - 0.46807861328125000000f, 0.52429199218750000000f, - 0.61270141601562500000f, 0.68215942382812500000f, - 0.82949829101562500000f, 0.90768432617187500000f, - 0.07641601562500000000f, 0.12448120117187500000f, - 0.25485229492187500000f, 0.36981201171875000000f, - 0.45916748046875000000f, 0.56747436523437500000f, - 0.66174316406250000000f, 0.75390625000000000000f, - 0.83981323242187500000f, 0.91360473632812500000f, - 0.15972900390625000000f, 0.19354248046875000000f, - 0.25228881835937500000f, 0.36074829101562500000f, - 0.46249389648437500000f, 0.51147460937500000000f, - 0.63070678710937500000f, 0.71679687500000000000f, - 0.79190063476562500000f, 0.89437866210937500000f, - 0.08181762695312500000f, 0.10870361328125000000f, - 0.18395996093750003000f, 0.33041381835937506000f, - 0.56329345703125000000f, 0.62432861328125000000f, - 0.68063354492187500000f, 0.75381469726562500000f, - 0.82128906250000000000f, 0.91418457031250000000f, - 0.10296630859375000000f, 0.13818359375000000000f, - 0.19012451171875000000f, 0.25195312500000000000f, - 0.29031372070312500000f, 0.38848876953124994000f, - 0.56964111328125000000f, 0.63232421875000000000f, - 0.79367065429687500000f, 0.86746215820312500000f, - 0.08334350585937500000f, 0.11074829101562500000f, - 0.25390625000000000000f, 0.37994384765625000000f, - 0.43066406250000000000f, 0.50143432617187500000f, - 0.56604003906250000000f, 0.67437744140625000000f, - 0.77297973632812500000f, 0.84588623046875000000f, - 0.10623168945312500000f, 0.13430786132812500000f, - 0.22341918945312503000f, 0.28439331054687500000f, - 0.33758544921875000000f, 0.39956665039062500000f, - 0.46145629882812500000f, 0.68099975585937489000f, - 0.80355834960937500000f, 0.87707519531250000000f, - 0.10916137695312500000f, 0.15090942382812500000f, - 0.20352172851562500000f, 0.26831054687500000000f, - 0.31430053710937500000f, 0.38589477539062506000f, - 0.59524536132812500000f, 0.75579833984375000000f, - 0.82385253906250011000f, 0.90435791015625000000f, - 0.12384033203125000000f, 0.15441894531250000000f, - 0.22241210937500000000f, 0.31097412109375000000f, - 0.35778808593750000000f, 0.42529296875000000000f, - 0.48367309570312500000f, 0.56576538085937500000f, - 0.81484985351562500000f, 0.91079711914062500000f, - 0.13006591796875000000f, 0.16448974609374997000f, - 0.21536254882812503000f, 0.27410888671875000000f, - 0.31088256835937500000f, 0.46582031250000000000f, - 0.62500000000000000000f, 0.68176269531250000000f, - 0.79217529296875000000f, 0.85668945312500000000f, - 0.10388183593750000000f, 0.13211059570312500000f, - 0.20230102539062497000f, 0.24249267578125000000f, - 0.30886840820312500000f, 0.52383422851562500000f, - 0.59936523437500000000f, 0.67883300781249989000f, - 0.76483154296875000000f, 0.83837890625000000000f, - 0.09634399414062501400f, 0.12719726562500000000f, - 0.18905639648437500000f, 0.28439331054687500000f, - 0.32870483398437500000f, 0.40664672851562500000f, - 0.47045898437500000000f, 0.60473632812500000000f, - 0.75292968750000000000f, 0.84332275390625000000f, - 0.07638549804687500000f, 0.10598754882812500000f, - 0.15655517578125000000f, 0.20651245117187500000f, - 0.26156616210937500000f, 0.45477294921875000000f, - 0.58084106445312500000f, 0.66912841796874989000f, - 0.79544067382812511000f, 0.87670898437500000000f, - 0.12612915039062500000f, 0.15570068359375000000f, - 0.23049926757812503000f, 0.30682373046875000000f, - 0.35879516601562500000f, 0.45544433593750000000f, - 0.53207397460937500000f, 0.61602783203125000000f, - 0.73202514648437489000f, 0.80175781249999989000f, - 0.15173339843750000000f, 0.18734741210937500000f, - 0.24090576171875000000f, 0.29397583007812500000f, - 0.34545898437500000000f, 0.43624877929687500000f, - 0.66336059570312500000f, 0.74176025390625000000f, - 0.82150268554687489000f, 0.91268920898437500000f, - 0.09027099609375000000f, 0.11645507812500000000f, - 0.20907592773437500000f, 0.28088378906250000000f, - 0.33248901367187506000f, 0.55090332031250000000f, - 0.63449096679687500000f, 0.71221923828125000000f, - 0.84094238281250000000f, 0.90359497070312500000f, - 0.15972900390625000000f, 0.18395996093750003000f, - 0.24517822265625000000f, 0.30987548828125000000f, - 0.34307861328125000000f, 0.45132446289062500000f, - 0.57824707031250000000f, 0.63983154296875000000f, - 0.81130981445312500000f, 0.88888549804687500000f, - 0.15994262695312503000f, 0.20867919921875000000f, - 0.32122802734375006000f, 0.39120483398437500000f, - 0.44802856445312500000f, 0.52880859375000000000f, - 0.60815429687500000000f, 0.68164062500000000000f, - 0.79934692382812500000f, 0.87576293945312500000f, - 0.10412597656250000000f, 0.12973022460937500000f, - 0.18273925781250000000f, 0.21649169921875000000f, - 0.30233764648437500000f, 0.55673217773437500000f, - 0.66128540039062500000f, 0.72561645507812511000f, - 0.82302856445312500000f, 0.88766479492187500000f, - 0.07537841796875000000f, 0.09817504882812500000f, - 0.23794555664062500000f, 0.46679687499999994000f, - 0.52993774414062500000f, 0.58395385742187500000f, - 0.67074584960937500000f, 0.74023437500000000000f, - 0.83380126953124989000f, 0.89849853515625000000f, - 0.15072631835937500000f, 0.17712402343750000000f, - 0.24856567382812500000f, 0.36038208007812506000f, - 0.42337036132812500000f, 0.47601318359375000000f, - 0.52593994140625000000f, 0.59274291992187500000f, - 0.80798339843750000000f, 0.90469360351562500000f, - 0.15414428710937500000f, 0.18820190429687497000f, - 0.25094604492187500000f, 0.29464721679687500000f, - 0.37106323242187500000f, 0.54916381835937500000f, - 0.62451171875000000000f, 0.69677734375000011000f, - 0.81225585937500000000f, 0.86859130859375000000f, - 0.15219116210937500000f, 0.18026733398437500000f, - 0.28439331054687500000f, 0.34317016601562500000f, - 0.40075683593750000000f, 0.45849609375000000000f, - 0.53359985351562500000f, 0.69235229492187511000f, - 0.79379272460937511000f, 0.86282348632812489000f, - 0.15676879882812500000f, 0.21008300781250000000f, - 0.33645629882812500000f, 0.45623779296875000000f, - 0.52462768554687500000f, 0.59280395507812500000f, - 0.66549682617187489000f, 0.74441528320312511000f, - 0.82208251953125000000f, 0.89379882812500000000f, - 0.21536254882812503000f, 0.24060058593750000000f, - 0.29077148437500000000f, 0.31991577148437500000f, - 0.33447265625000000000f, 0.45199584960937500000f, - 0.58197021484375000000f, 0.66146850585937500000f, - 0.78262329101562511000f, 0.85507202148437500000f, - 0.20626831054687500000f, 0.21850585937500000000f, - 0.26080322265625000000f, 0.35946655273437500000f, - 0.37521362304687500000f, 0.39743041992187500000f, - 0.50741577148437500000f, 0.64389038085937500000f, - 0.75369262695312500000f, 0.86325073242187500000f, - 0.11788940429687500000f, 0.29791259765625000000f, - 0.33776855468749994000f, 0.34927368164062500000f, - 0.36770629882812506000f, 0.42602539062500000000f, - 0.55191040039062500000f, 0.65634155273437500000f, - 0.76977539062500000000f, 0.88491821289062489000f, - 0.01211547851562500000f, 0.01022338867187500000f, - 0.01986694335937500000f, 0.03564453125000000000f, - 0.01953125000000000000f, 0.02334594726562500000f, - 0.01419067382812500000f, 0.01010131835937500000f, - 0.00653076171875000000f, -0.00592041015625000000f, - -0.01763916015625000000f, -0.01974487304687500000f, - -0.02005004882812500000f, 0.02288818359375000000f, - 0.01721191406250000000f, 0.01870727539062500000f, - 0.01675415039062500000f, 0.01922607421875000000f, - 0.00927734375000000000f, -0.00158691406250000020f, - 0.02526855468749999700f, 0.02813720703125000000f, - 0.01351928710937500000f, 0.00338745117187500000f, - 0.00421142578125000000f, 0.00378417968750000000f, - 0.00515747070312500000f, 0.00042724609375000000f, - 0.00439453125000000000f, 0.00253295898437500040f, - 0.00402832031250000000f, 0.00177001953125000000f, - -0.01260375976562500000f, -0.02294921875000000000f, - 0.02651977539062500000f, 0.01025390625000000000f, - 0.01174926757812500200f, 0.00210571289062500000f, - 0.00170898437500000000f, 0.02532958984375000000f, - -0.00692749023437500000f, -0.00811767578125000000f, - -0.01123046875000000000f, -0.01342773437500000000f, - -0.03646850585937500000f, 0.00497436523437500000f, - 0.00384521484375000000f, -0.00695800781250000000f, - 0.02447509765625000000f, 0.00476074218750000000f, - 0.00573730468750000000f, 0.00366210937499999960f, - 0.01147460937500000000f, 0.00180053710937500000f, - -0.01092529296875000000f, -0.01702880859375000000f, - -0.04046630859375000000f, -0.00775146484375000000f, - -0.00616455078125000000f, -0.02407836914062500000f, - 0.00903320312500000000f, 0.00280761718750000000f, - -0.00213623046875000000f, -0.00393676757812500000f, - -0.02191162109375000000f, -0.03463745117187500000f, - 0.00891113281250000000f, -0.00088500976562500000f, - -0.01925659179687500000f, 0.01486206054687500000f, - -0.00479125976562500000f, -0.00466918945312500000f, - -0.00851440429687500000f, 0.00006103515625000000f, - -0.01278686523437500000f, -0.01043701171875000000f, - -0.00103759765625000000f, -0.01568603515625000000f, - -0.02438354492187499700f, -0.04794311523437500000f, - -0.02096557617187500000f, -0.01858520507812500000f, - -0.01666259765625000000f, -0.00396728515625000000f, - -0.00656127929687500000f, -0.00769042968750000000f, - -0.01361083984375000000f, -0.01751708984375000000f, - -0.04080200195312500000f, 0.00631713867187499910f, - -0.00219726562500000000f, 0.00097656250000000000f, - 0.00314331054687500000f, -0.01959228515625000000f, - 0.02874755859375000300f, 0.02236938476562499700f, - 0.00570678710937500090f, 0.00088500976562500000f, - -0.00643920898437500000f, -0.02484130859375000300f, - 0.00436401367187500000f, 0.00686645507812500000f, - 0.00061035156250000000f, 0.00073242187500000000f, - -0.00817871093750000000f, -0.01150512695312500000f, - 0.04953002929687499300f, 0.03457641601562500000f, - 0.02035522460937500000f, 0.00500488281250000000f, - 0.00936889648437500000f, 0.01116943359375000000f, - 0.00570678710937500090f, 0.00103759765625000000f, - 0.00189208984375000000f, -0.00955200195312500000f, - -0.02539062500000000300f, -0.04522705078125000000f, - -0.03604125976562500000f, 0.01473999023437500000f, - -0.00128173828125000000f, -0.00119018554687500000f, - -0.01373291015625000000f, -0.04290771484375000000f, - -0.01791381835937500000f, -0.00158691406250000020f, - -0.02319335937500000000f, 0.01019287109375000000f, - 0.00299072265625000000f, -0.00183105468749999980f, - -0.01525878906249999800f, -0.01489257812500000000f, - -0.03228759765625000000f, 0.00912475585937500000f, - 0.00399780273437500000f, -0.00762939453124999910f, - -0.00765991210937500090f, -0.02145385742187500000f, - 0.03164672851562500000f, 0.01733398437500000000f, - -0.01260375976562500000f, -0.00808715820312500000f, - 0.05148315429687500000f, 0.01748657226562500000f, - 0.01052856445312500000f, 0.00985717773437500000f, - 0.00299072265625000000f, 0.00186157226562500000f, - -0.00311279296875000000f, 0.00094604492187500000f, - 0.00411987304687500000f, 0.00454711914062500000f, - 0.01882934570312500000f, 0.01113891601562500000f, - -0.00119018554687500000f, 0.00103759765625000000f, - -0.01864624023437500000f, 0.03665161132812500000f, - 0.04336547851562500000f, 0.02246093750000000000f, - -0.01263427734374999800f, -0.01199340820312500000f, - -0.01501464843750000000f, -0.01046752929687500200f, - -0.00964355468750000000f, -0.01623535156250000000f, - 0.01611328125000000000f, 0.00524902343750000000f, - 0.00274658203125000000f, 0.00982666015625000000f, - -0.00897216796875000000f, -0.00973510742187500000f, - -0.01651000976562500000f, 0.01535034179687500000f, - 0.01950073242187500000f, 0.01223754882812500000f, - 0.00003051757812500000f, -0.00454711914062500000f, - -0.00222778320312500000f, -0.00509643554687500000f, - 0.00457763671875000000f, 0.00360107421875000000f, - 0.00939941406250000000f, 0.00665283203124999910f, - 0.00369262695312500000f, 0.00595092773437500000f, - -0.00436401367187500000f, -0.00796508789062500000f, - -0.03091430664062500000f, -0.02447509765625000000f, - 0.01181030273437500000f, 0.01330566406249999800f, - 0.00396728515625000000f, -0.01303100585937500200f, - -0.01367187500000000000f, -0.02078247070312500000f, - 0.00375366210937500000f, -0.00265502929687500000f, - -0.00765991210937500090f, -0.00344848632812500000f, - 0.00836181640625000000f, 0.00946044921875000000f, - 0.01358032226562500000f, 0.01528930664062500000f, - 0.01080322265625000200f, 0.00830078125000000000f, - 0.00430297851562500000f, -0.00869750976562500000f, - 0.01736450195312500000f, 0.02001953125000000000f, - 0.00112915039062500000f, -0.00149536132812500000f, - 0.00765991210937500090f, -0.01177978515625000000f, - -0.00802612304687500000f, 0.03424072265625000000f, - 0.01843261718750000000f, 0.01849365234375000000f, - 0.01025390625000000000f, 0.00289916992187500000f, - 0.00103759765625000000f, 0.00000000000000000000f, - 0.00259399414062500000f, 0.00549316406250000000f, - 0.00631713867187499910f, -0.01119995117187500000f, - -0.01898193359375000000f, 0.03265380859375000000f, - -0.00018310546875000000f, -0.00241088867187500000f, - -0.00488281250000000000f, -0.00280761718750000000f, - -0.00418090820312500000f, -0.00842285156250000000f, - -0.00985717773437500000f, -0.01132202148437500000f, - -0.02124023437500000000f, -0.03161621093750000000f, - 0.01242065429687500200f, 0.00311279296875000000f, - -0.00262451171875000000f, -0.00653076171875000000f, - -0.01470947265625000200f, -0.01974487304687500000f, - -0.00085449218750000000f, -0.00888061523437500000f, - -0.00296020507812500000f, -0.00549316406250000000f, - -0.00762939453124999910f, -0.01327514648437500000f, - -0.00054931640625000000f, -0.00231933593750000000f, - -0.01013183593750000200f, 0.01251220703125000000f, - 0.01242065429687500200f, 0.00512695312500000000f, - 0.01644897460937500000f, 0.01254272460937500000f, - 0.00775146484375000000f, 0.00338745117187500000f, - 0.00177001953125000000f, -0.00442504882812500000f, - 0.00610351562500000000f, 0.00091552734374999989f, - 0.00570678710937500090f, 0.00354003906250000000f, - 0.00399780273437500000f, -0.01119995117187500000f, - -0.01449584960937500000f, 0.02383422851562500300f, - -0.01705932617187500000f, 0.01712036132812500000f, - 0.00595092773437500000f, -0.00350952148437500040f, - 0.00024414062500000000f, -0.00512695312500000000f, - 0.00091552734374999989f, 0.00167846679687500000f, - -0.00372314453125000000f, 0.00399780273437500000f, - 0.00250244140625000000f, -0.00015258789062500000f, - -0.00833129882812500000f, -0.00152587890625000000f, - -0.01928710937500000000f, 0.02038574218750000000f, - 0.00012207031250000000f, 0.00097656250000000000f, - -0.00079345703125000011f, -0.00851440429687500000f, - 0.00961303710937500000f, 0.00503540039062499910f, - 0.00601196289062499910f, 0.01150512695312500000f, - 0.00473022460937500000f, -0.00125122070312500000f, - -0.00421142578125000000f, -0.00988769531250000000f, - -0.00332641601562499960f, -0.01882934570312500000f, - 0.01098632812500000000f, 0.00299072265625000000f, - -0.00161743164062500000f, -0.00973510742187500000f, - -0.00347900390625000000f, -0.00747680664062500000f, - -0.00250244140625000000f, 0.01547241210937500000f, - 0.01428222656250000000f, 0.00802612304687500000f, - -0.00418090820312500000f, -0.01187133789062500000f, - 0.01989746093750000000f, 0.01080322265625000200f, - -0.00054931640625000000f, -0.00692749023437500000f, - -0.01409912109375000000f, -0.00411987304687500000f, - 0.00967407226562500000f, 0.00161743164062500000f, - -0.00048828125000000000f, 0.00201416015625000000f, - -0.00219726562500000000f, -0.00384521484375000000f, - -0.01086425781250000000f, -0.01058959960937500000f, - -0.01000976562500000000f, -0.00219726562500000000f, - -0.01028442382812500000f, 0.00988769531250000000f, - 0.00463867187500000000f, 0.01065063476562500000f, - 0.00515747070312500000f, -0.00598144531250000000f, - 0.00546264648437500000f, 0.00775146484375000000f, - 0.00793457031250000000f, 0.00991821289062500000f, - -0.00225830078125000000f, -0.00244140625000000000f, - 0.00228881835937500000f, -0.00094604492187500000f, - 0.00823974609375000000f, 0.00839233398437500000f, - 0.00265502929687500000f, 0.00848388671875000000f, - -0.01361083984375000000f, -0.00918579101562500000f, - 0.00942993164062500000f, 0.00216674804687500000f, - -0.00076293945312500000f, -0.00738525390625000000f, - 0.01574707031250000000f, 0.00491333007812500000f, - -0.00494384765625000000f, -0.00253295898437500040f, - 0.01004028320312500000f, 0.00701904296875000090f, - -0.00949096679687500000f, -0.00790405273437500000f, - 0.00540161132812500090f, -0.00079345703125000011f, - -0.01409912109375000000f, 0.00271606445312500000f, - 0.00784301757812500000f, 0.00018310546875000000f, - -0.00396728515625000000f, -0.00283813476562499960f, - -0.01391601562500000000f, -0.00967407226562500000f, - -0.00674438476562500000f, -0.00628662109375000000f, - -0.01272583007812500000f, -0.00555419921875000000f, - -0.00225830078125000000f, 0.00714111328125000000f, - 0.00146484375000000000f, 0.00796508789062500000f, - 0.01095581054687500000f, 0.00704956054687500000f, - 0.00787353515625000000f, 0.00259399414062500000f, - -0.00860595703125000000f, 0.00769042968750000000f, - -0.00448608398437500000f, -0.00677490234375000000f, - 0.00765991210937500090f, -0.00631713867187499910f, - 0.01351928710937500000f, 0.00375366210937500000f, - -0.01272583007812500000f, -0.00109863281250000000f, - 0.00833129882812500000f, -0.00735473632812500090f, - 0.00732421874999999910f, -0.00341796875000000000f, - 0.00134277343749999980f, -0.00509643554687500000f, - 0.00384521484375000000f, -0.00378417968750000000f, - -0.00234985351562500000f, 0.00177001953125000000f, - -0.01223754882812500000f, 0.01016235351562500000f, - -0.00360107421875000000f, 0.00250244140625000000f, - 0.00384521484375000000f, 0.00460815429687500000f, - -0.01321411132812500000f, 0.01095581054687500000f, - -0.00396728515625000000f, -0.00311279296875000000f, - 0.00399780273437500000f, -0.00744628906250000000f, - 0.00262451171875000000f, 0.00259399414062500000f, - -0.01409912109375000000f, 0.01263427734374999800f, - -0.00732421874999999910f, 0.00048828125000000000f, - 0.00442504882812500000f, 0.00085449218750000000f, - -0.00625610351562500000f, -0.01467895507812500000f, - 0.01138305664062500000f, 0.00894165039062500000f, - -0.00219726562500000000f, -0.00531005859375000000f, - 0.00189208984375000000f, 0.00790405273437500000f, - -0.00024414062500000000f, -0.00054931640625000000f, - 0.01104736328125000000f, 0.00711059570312500000f, - 0.00564575195312500000f, 0.00131225585937500000f, - 0.00848388671875000000f, 0.00082397460937500000f, - 0.00588989257812500000f, 0.01739501953125000000f, - -0.00756835937500000000f, 0.00576782226562500000f, - 0.00280761718750000000f, 0.00094604492187500000f, - -0.00839233398437500000f, -0.00009155273437500000f, - 0.00741577148437500000f, 0.00537109374999999910f, - 0.01336669921875000200f, 0.00637817382812500090f, - 0.00628662109375000000f, -0.00155639648437500000f, - 0.00241088867187500000f, 0.00332641601562499960f, - 0.00512695312500000000f, -0.00564575195312500000f, - -0.00939941406250000000f, -0.00207519531250000000f, - -0.01885986328125000000f, 0.01174926757812500200f, - -0.00946044921875000000f, -0.00329589843750000000f, - -0.00500488281250000000f, 0.00503540039062499910f, - 0.00186157226562500000f, -0.00463867187500000000f, - -0.00308227539062500000f, -0.01257324218750000000f, - -0.00817871093750000000f, -0.00784301757812500000f, - -0.00122070312500000000f, -0.00061035156250000000f, - -0.00085449218750000000f, -0.00482177734375000000f, - -0.00918579101562500000f, 0.00827026367187500000f, - 0.01159667968750000000f, -0.01031494140625000000f, - -0.01119995117187500000f, -0.00402832031250000000f, - 0.00195312500000000000f, 0.00347900390625000000f, - -0.00399780273437500000f, -0.00686645507812500000f, - -0.00476074218750000000f, -0.00793457031250000000f, - -0.00192260742187500000f, -0.00354003906250000000f, - 0.00473022460937500000f, -0.01788330078125000000f, - -0.00616455078125000000f, 0.00775146484375000000f, - -0.00875854492187500000f, 0.00543212890625000000f, - 0.00692749023437500000f, -0.00323486328125000000f, - -0.00897216796875000000f, 0.00500488281250000000f, - 0.00909423828125000000f, -0.00305175781250000000f, - 0.00564575195312500000f, 0.00967407226562500000f, - 0.00588989257812500000f, -0.00137329101562500000f, - 0.00085449218750000000f, 0.00244140625000000000f, - -0.00265502929687500000f, -0.01321411132812500000f, - 0.00067138671874999989f, -0.00146484375000000000f, - 0.00146484375000000000f, -0.00723266601562500000f, - -0.00698852539062499910f, -0.00424194335937500000f, - 0.00366210937499999960f, -0.01110839843750000000f, - 0.00817871093750000000f, -0.00415039062500000000f, - 0.01208496093750000200f, 0.00381469726562499960f, - 0.00396728515625000000f, -0.00271606445312500000f, - -0.00830078125000000000f, 0.00360107421875000000f, - -0.00781250000000000000f, -0.00207519531250000000f, - -0.01376342773437500000f, 0.01489257812500000000f, - 0.00436401367187500000f, -0.00503540039062499910f, - -0.00146484375000000000f, -0.00579833984375000000f, - 0.00323486328125000000f, 0.00668334960937500090f, - 0.00143432617187500000f, 0.01327514648437500000f, - 0.00747680664062500000f, 0.00296020507812500000f, - 0.00228881835937500000f, -0.01275634765625000200f, - 0.00369262695312500000f, -0.00570678710937500090f, - 0.01739501953125000000f, -0.00610351562500000000f, - -0.01071166992187500000f, 0.00686645507812500000f, - -0.00064086914062500000f, -0.00662231445312500000f, - 0.00714111328125000000f, -0.00338745117187500000f, - 0.00592041015625000000f, 0.00042724609375000000f, - 0.00738525390625000000f, 0.00360107421875000000f, - 0.00427246093750000000f, -0.01211547851562500000f, - 0.01083374023437500000f, 0.01101684570312499800f, - -0.00137329101562500000f, -0.00595092773437500000f - }; - -// const SKP_Silk_NLSF_CBS_FLP SKP_Silk_NLSF_CB0_10_Stage_info_FLP[ NLSF_MSVQ_CB0_10_STAGES ] = -// { -// { 64, &SKP_Silk_NLSF_MSVQ_CB0_10[ 10 * 0 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates[ 0 ] }, -// { 16, &SKP_Silk_NLSF_MSVQ_CB0_10[ 10 * 64 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates[ 64 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB0_10[ 10 * 80 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates[ 80 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB0_10[ 10 * 88 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates[ 88 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB0_10[ 10 * 96 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates[ 96 ] }, -// { 16, &SKP_Silk_NLSF_MSVQ_CB0_10[ 10 * 104 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates[ 104 ] } -// }; - static final SKP_Silk_NLSF_CBS_FLP[] SKP_Silk_NLSF_CB0_10_Stage_info_FLP = - { - new SKP_Silk_NLSF_CBS_FLP(64, SKP_Silk_NLSF_MSVQ_CB0_10, 10*0, SKP_Silk_NLSF_MSVQ_CB0_10_rates, 0), - new SKP_Silk_NLSF_CBS_FLP(16, SKP_Silk_NLSF_MSVQ_CB0_10, 10*64, SKP_Silk_NLSF_MSVQ_CB0_10_rates, 64), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB0_10, 10*80, SKP_Silk_NLSF_MSVQ_CB0_10_rates, 80), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB0_10, 10*88, SKP_Silk_NLSF_MSVQ_CB0_10_rates, 88), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB0_10, 10*96, SKP_Silk_NLSF_MSVQ_CB0_10_rates, 96), - new SKP_Silk_NLSF_CBS_FLP(16, SKP_Silk_NLSF_MSVQ_CB0_10, 10*104, SKP_Silk_NLSF_MSVQ_CB0_10_rates, 104) - }; - -// const SKP_Silk_NLSF_CB_FLP SKP_Silk_NLSF_CB0_10_FLP = -// { -// NLSF_MSVQ_CB0_10_STAGES, -// SKP_Silk_NLSF_CB0_10_Stage_info_FLP, -// SKP_Silk_NLSF_MSVQ_CB0_10_ndelta_min, -// SKP_Silk_NLSF_MSVQ_CB0_10_CDF, -// SKP_Silk_NLSF_MSVQ_CB0_10_CDF_start_ptr, -// SKP_Silk_NLSF_MSVQ_CB0_10_CDF_middle_idx -// }; - static final SKP_Silk_NLSF_CB_FLP SKP_Silk_NLSF_CB0_10_FLP = - new SKP_Silk_NLSF_CB_FLP( - Silk_tables_NLSF_CB0_10.NLSF_MSVQ_CB0_10_STAGES, - SKP_Silk_NLSF_CB0_10_Stage_info_FLP, - SKP_Silk_NLSF_MSVQ_CB0_10_ndelta_min, - Silk_tables_NLSF_CB0_10.SKP_Silk_NLSF_MSVQ_CB0_10_CDF, - Silk_tables_NLSF_CB0_10.SKP_Silk_NLSF_MSVQ_CB0_10_CDF_start_ptr, - Silk_tables_NLSF_CB0_10.SKP_Silk_NLSF_MSVQ_CB0_10_CDF_middle_idx - ); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB0_16.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB0_16.java deleted file mode 100644 index f42e661bf..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB0_16.java +++ /dev/null @@ -1,1325 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * This file has been automatically generated - * ROM usage: 0.51 + 7.38 kB - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_tables_NLSF_CB0_16 -{ - static final int NLSF_MSVQ_CB0_16_STAGES = 10; - static final int NLSF_MSVQ_CB0_16_VECTORS = 216; - - static final int[] SKP_Silk_NLSF_MSVQ_CB0_16_CDF = - { - 0, - 1449, - 2749, - 4022, - 5267, - 6434, - 7600, - 8647, - 9695, - 10742, - 11681, - 12601, - 13444, - 14251, - 15008, - 15764, - 16521, - 17261, - 18002, - 18710, - 19419, - 20128, - 20837, - 21531, - 22225, - 22919, - 23598, - 24277, - 24956, - 25620, - 26256, - 26865, - 27475, - 28071, - 28667, - 29263, - 29859, - 30443, - 31026, - 31597, - 32168, - 32727, - 33273, - 33808, - 34332, - 34855, - 35379, - 35902, - 36415, - 36927, - 37439, - 37941, - 38442, - 38932, - 39423, - 39914, - 40404, - 40884, - 41364, - 41844, - 42324, - 42805, - 43285, - 43754, - 44224, - 44694, - 45164, - 45623, - 46083, - 46543, - 46993, - 47443, - 47892, - 48333, - 48773, - 49213, - 49653, - 50084, - 50515, - 50946, - 51377, - 51798, - 52211, - 52614, - 53018, - 53422, - 53817, - 54212, - 54607, - 55002, - 55388, - 55775, - 56162, - 56548, - 56910, - 57273, - 57635, - 57997, - 58352, - 58698, - 59038, - 59370, - 59702, - 60014, - 60325, - 60630, - 60934, - 61239, - 61537, - 61822, - 62084, - 62346, - 62602, - 62837, - 63072, - 63302, - 63517, - 63732, - 63939, - 64145, - 64342, - 64528, - 64701, - 64867, - 65023, - 65151, - 65279, - 65407, - 65535, - 0, - 5099, - 9982, - 14760, - 19538, - 24213, - 28595, - 32976, - 36994, - 41012, - 44944, - 48791, - 52557, - 56009, - 59388, - 62694, - 65535, - 0, - 9955, - 19697, - 28825, - 36842, - 44686, - 52198, - 58939, - 65535, - 0, - 8949, - 17335, - 25720, - 33926, - 41957, - 49987, - 57845, - 65535, - 0, - 9724, - 18642, - 26998, - 35355, - 43532, - 51534, - 59365, - 65535, - 0, - 8750, - 17499, - 26249, - 34448, - 42471, - 50494, - 58178, - 65535, - 0, - 8730, - 17273, - 25816, - 34176, - 42536, - 50203, - 57869, - 65535, - 0, - 8769, - 17538, - 26307, - 34525, - 42742, - 50784, - 58319, - 65535, - 0, - 8736, - 17101, - 25466, - 33653, - 41839, - 50025, - 57864, - 65535, - 0, - 4368, - 8735, - 12918, - 17100, - 21283, - 25465, - 29558, - 33651, - 37744, - 41836, - 45929, - 50022, - 54027, - 57947, - 61782, - 65535 - }; - - static private int [] SKP_Silk_NLSF_MSVQ_CB0_16_CDF_0 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB0_16_CDF, 0, SKP_Silk_NLSF_MSVQ_CB0_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB0_16_CDF_129 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB0_16_CDF, 129, SKP_Silk_NLSF_MSVQ_CB0_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB0_16_CDF_146 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB0_16_CDF, 146, SKP_Silk_NLSF_MSVQ_CB0_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB0_16_CDF_155 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB0_16_CDF, 155, SKP_Silk_NLSF_MSVQ_CB0_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB0_16_CDF_164 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB0_16_CDF, 164, SKP_Silk_NLSF_MSVQ_CB0_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB0_16_CDF_173 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB0_16_CDF, 173, SKP_Silk_NLSF_MSVQ_CB0_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB0_16_CDF_182 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB0_16_CDF, 182, SKP_Silk_NLSF_MSVQ_CB0_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB0_16_CDF_191 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB0_16_CDF, 191, SKP_Silk_NLSF_MSVQ_CB0_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB0_16_CDF_200 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB0_16_CDF, 200, SKP_Silk_NLSF_MSVQ_CB0_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB0_16_CDF_209 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB0_16_CDF, 209, SKP_Silk_NLSF_MSVQ_CB0_16_CDF.length); - - static final int[][] SKP_Silk_NLSF_MSVQ_CB0_16_CDF_start_ptr = - { - SKP_Silk_NLSF_MSVQ_CB0_16_CDF_0, - SKP_Silk_NLSF_MSVQ_CB0_16_CDF_129, - SKP_Silk_NLSF_MSVQ_CB0_16_CDF_146, - SKP_Silk_NLSF_MSVQ_CB0_16_CDF_155, - SKP_Silk_NLSF_MSVQ_CB0_16_CDF_164, - SKP_Silk_NLSF_MSVQ_CB0_16_CDF_173, - SKP_Silk_NLSF_MSVQ_CB0_16_CDF_182, - SKP_Silk_NLSF_MSVQ_CB0_16_CDF_191, - SKP_Silk_NLSF_MSVQ_CB0_16_CDF_200, - SKP_Silk_NLSF_MSVQ_CB0_16_CDF_209 - }; - - static final int[] SKP_Silk_NLSF_MSVQ_CB0_16_CDF_middle_idx = - { - 42, - 8, - 4, - 5, - 5, - 5, - 5, - 5, - 5, - 9 - }; - - static final short[] SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5 = - { - 176, 181, - 182, 183, - 186, 186, - 191, 191, - 191, 196, - 197, 201, - 203, 206, - 206, 206, - 207, 207, - 209, 209, - 209, 209, - 210, 210, - 210, 211, - 211, 211, - 212, 214, - 216, 216, - 217, 217, - 217, 217, - 218, 218, - 219, 219, - 220, 221, - 222, 223, - 223, 223, - 223, 224, - 224, 224, - 225, 225, - 226, 226, - 226, 226, - 227, 227, - 227, 227, - 227, 227, - 228, 228, - 228, 228, - 229, 229, - 229, 230, - 230, 230, - 231, 231, - 231, 231, - 232, 232, - 232, 232, - 233, 234, - 235, 235, - 235, 236, - 236, 236, - 236, 237, - 237, 237, - 237, 240, - 240, 240, - 240, 241, - 242, 243, - 244, 244, - 247, 247, - 248, 248, - 248, 249, - 251, 255, - 255, 256, - 260, 260, - 261, 264, - 264, 266, - 266, 268, - 271, 274, - 276, 279, - 288, 288, - 288, 288, - 118, 120, - 121, 121, - 122, 125, - 125, 129, - 129, 130, - 131, 132, - 136, 137, - 138, 145, - 87, 88, - 91, 97, - 98, 100, - 105, 106, - 92, 95, - 95, 96, - 97, 97, - 98, 99, - 88, 92, - 95, 95, - 96, 97, - 98, 109, - 93, 93, - 93, 96, - 97, 97, - 99, 101, - 93, 94, - 94, 95, - 95, 99, - 99, 99, - 93, 93, - 93, 96, - 96, 97, - 100, 102, - 93, 95, - 95, 96, - 96, 96, - 98, 99, - 125, 125, - 127, 127, - 127, 127, - 128, 128, - 128, 128, - 128, 128, - 129, 130, - 131, 132 - }; - - static final int[] SKP_Silk_NLSF_MSVQ_CB0_16_ndelta_min_Q15 = - { - 266, - 3, - 40, - 3, - 3, - 16, - 78, - 89, - 107, - 141, - 188, - 146, - 272, - 240, - 235, - 215, - 632 - }; - - static final short[]SKP_Silk_NLSF_MSVQ_CB0_16_Q15 = - { - 1170, 2278, 3658, 5374, - 7666, 9113, 11298, 13304, - 15371, 17549, 19587, 21487, - 23798, 26038, 28318, 30201, - 1628, 2334, 4115, 6036, - 7818, 9544, 11777, 14021, - 15787, 17408, 19466, 21261, - 22886, 24565, 26714, 28059, - 1724, 2670, 4056, 6532, - 8357, 10119, 12093, 14061, - 16491, 18795, 20417, 22402, - 24251, 26224, 28410, 29956, - 1493, 3427, 4789, 6399, - 8435, 10168, 12000, 14066, - 16229, 18210, 20040, 22098, - 24153, 26095, 28183, 30121, - 1119, 2089, 4295, 6245, - 8691, 10741, 12688, 15057, - 17028, 18792, 20717, 22514, - 24497, 26548, 28619, 30630, - 1363, 2417, 3927, 5556, - 7422, 9315, 11879, 13767, - 16143, 18520, 20458, 22578, - 24539, 26436, 28318, 30318, - 1122, 2503, 5216, 7148, - 9310, 11078, 13175, 14800, - 16864, 18700, 20436, 22488, - 24572, 26602, 28555, 30426, - 600, 1317, 2970, 5609, - 7694, 9784, 12169, 14087, - 16379, 18378, 20551, 22686, - 24739, 26697, 28646, 30355, - 941, 1882, 4274, 5540, - 8482, 9858, 11940, 14287, - 16091, 18501, 20326, 22612, - 24711, 26638, 28814, 30430, - 635, 1699, 4376, 5948, - 8097, 10115, 12274, 14178, - 16111, 17813, 19695, 21773, - 23927, 25866, 28022, 30134, - 1408, 2222, 3524, 5615, - 7345, 8849, 10989, 12772, - 15352, 17026, 18919, 21062, - 23329, 25215, 27209, 29023, - 701, 1307, 3548, 6301, - 7744, 9574, 11227, 12978, - 15170, 17565, 19775, 22097, - 24230, 26335, 28377, 30231, - 1752, 2364, 4879, 6569, - 7813, 9796, 11199, 14290, - 15795, 18000, 20396, 22417, - 24308, 26124, 28360, 30633, - 901, 1629, 3356, 4635, - 7256, 8767, 9971, 11558, - 15215, 17544, 19523, 21852, - 23900, 25978, 28133, 30184, - 981, 1669, 3323, 4693, - 6213, 8692, 10614, 12956, - 15211, 17711, 19856, 22122, - 24344, 26592, 28723, 30481, - 1607, 2577, 4220, 5512, - 8532, 10388, 11627, 13671, - 15752, 17199, 19840, 21859, - 23494, 25786, 28091, 30131, - 811, 1471, 3144, 5041, - 7430, 9389, 11174, 13255, - 15157, 16741, 19583, 22167, - 24115, 26142, 28383, 30395, - 1543, 2144, 3629, 6347, - 7333, 9339, 10710, 13596, - 15099, 17340, 20102, 21886, - 23732, 25637, 27818, 29917, - 492, 1185, 2940, 5488, - 7095, 8751, 11596, 13579, - 16045, 18015, 20178, 22127, - 24265, 26406, 28484, 30357, - 1547, 2282, 3693, 6341, - 7758, 9607, 11848, 13236, - 16564, 18069, 19759, 21404, - 24110, 26606, 28786, 30655, - 685, 1338, 3409, 5262, - 6950, 9222, 11414, 14523, - 16337, 17893, 19436, 21298, - 23293, 25181, 27973, 30520, - 887, 1581, 3057, 4318, - 7192, 8617, 10047, 13106, - 16265, 17893, 20233, 22350, - 24379, 26384, 28314, 30189, - 2285, 3745, 5662, 7576, - 9323, 11320, 13239, 15191, - 17175, 19225, 21108, 22972, - 24821, 26655, 28561, 30460, - 1496, 2108, 3448, 6898, - 8328, 9656, 11252, 12823, - 14979, 16482, 18180, 20085, - 22962, 25160, 27705, 29629, - 575, 1261, 3861, 6627, - 8294, 10809, 12705, 14768, - 17076, 19047, 20978, 23055, - 24972, 26703, 28720, 30345, - 1682, 2213, 3882, 6238, - 7208, 9646, 10877, 13431, - 14805, 16213, 17941, 20873, - 23550, 25765, 27756, 29461, - 888, 1616, 3924, 5195, - 7206, 8647, 9842, 11473, - 16067, 18221, 20343, 22774, - 24503, 26412, 28054, 29731, - 805, 1454, 2683, 4472, - 7936, 9360, 11398, 14345, - 16205, 17832, 19453, 21646, - 23899, 25928, 28387, 30463, - 1640, 2383, 3484, 5082, - 6032, 8606, 11640, 12966, - 15842, 17368, 19346, 21182, - 23638, 25889, 28368, 30299, - 1632, 2204, 4510, 7580, - 8718, 10512, 11962, 14096, - 15640, 17194, 19143, 22247, - 24563, 26561, 28604, 30509, - 2043, 2612, 3985, 6851, - 8038, 9514, 10979, 12789, - 15426, 16728, 18899, 20277, - 22902, 26209, 28711, 30618, - 2224, 2798, 4465, 5320, - 7108, 9436, 10986, 13222, - 14599, 18317, 20141, 21843, - 23601, 25700, 28184, 30582, - 835, 1541, 4083, 5769, - 7386, 9399, 10971, 12456, - 15021, 18642, 20843, 23100, - 25292, 26966, 28952, 30422, - 1795, 2343, 4809, 5896, - 7178, 8545, 10223, 13370, - 14606, 16469, 18273, 20736, - 23645, 26257, 28224, 30390, - 1734, 2254, 4031, 5188, - 6506, 7872, 9651, 13025, - 14419, 17305, 19495, 22190, - 24403, 26302, 28195, 30177, - 1841, 2349, 3968, 4764, - 6376, 9825, 11048, 13345, - 14682, 16252, 18183, 21363, - 23918, 26156, 28031, 29935, - 1432, 2047, 5631, 6927, - 8198, 9675, 11358, 13506, - 14802, 16419, 18339, 22019, - 24124, 26177, 28130, 30586, - 1730, 2320, 3744, 4808, - 6007, 9666, 10997, 13622, - 15234, 17495, 20088, 22002, - 23603, 25400, 27379, 29254, - 1267, 1915, 5483, 6812, - 8229, 9919, 11589, 13337, - 14747, 17965, 20552, 22167, - 24519, 26819, 28883, 30642, - 1526, 2229, 4240, 7388, - 8953, 10450, 11899, 13718, - 16861, 18323, 20379, 22672, - 24797, 26906, 28906, 30622, - 2175, 2791, 4104, 6875, - 8612, 9798, 12152, 13536, - 15623, 17682, 19213, 21060, - 24382, 26760, 28633, 30248, - 454, 1231, 4339, 5738, - 7550, 9006, 10320, 13525, - 16005, 17849, 20071, 21992, - 23949, 26043, 28245, 30175, - 2250, 2791, 4230, 5283, - 6762, 10607, 11879, 13821, - 15797, 17264, 20029, 22266, - 24588, 26437, 28244, 30419, - 1696, 2216, 4308, 8385, - 9766, 11030, 12556, 14099, - 16322, 17640, 19166, 20590, - 23967, 26858, 28798, 30562, - 2452, 3236, 4369, 6118, - 7156, 9003, 11509, 12796, - 15749, 17291, 19491, 22241, - 24530, 26474, 28273, 30073, - 1811, 2541, 3555, 5480, - 9123, 10527, 11894, 13659, - 15262, 16899, 19366, 21069, - 22694, 24314, 27256, 29983, - 1553, 2246, 4559, 5500, - 6754, 7874, 11739, 13571, - 15188, 17879, 20281, 22510, - 24614, 26649, 28786, 30755, - 1982, 2768, 3834, 5964, - 8732, 9908, 11797, 14813, - 16311, 17946, 21097, 22851, - 24456, 26304, 28166, 29755, - 1824, 2529, 3817, 5449, - 6854, 8714, 10381, 12286, - 14194, 15774, 19524, 21374, - 23695, 26069, 28096, 30212, - 2212, 2854, 3947, 5898, - 9930, 11556, 12854, 14788, - 16328, 17700, 20321, 22098, - 23672, 25291, 26976, 28586, - 2023, 2599, 4024, 4916, - 6613, 11149, 12457, 14626, - 16320, 17822, 19673, 21172, - 23115, 26051, 28825, 30758, - 1628, 2206, 3467, 4364, - 8679, 10173, 11864, 13679, - 14998, 16938, 19207, 21364, - 23850, 26115, 28124, 30273, - 2014, 2603, 4114, 7254, - 8516, 10043, 11822, 13503, - 16329, 17826, 19697, 21280, - 23151, 24661, 26807, 30161, - 2376, 2980, 4422, 5770, - 7016, 9723, 11125, 13516, - 15485, 16985, 19160, 20587, - 24401, 27180, 29046, 30647, - 2454, 3502, 4624, 6019, - 7632, 8849, 10792, 13964, - 15523, 17085, 19611, 21238, - 22856, 25108, 28106, 29890, - 1573, 2274, 3308, 5999, - 8977, 10104, 12457, 14258, - 15749, 18180, 19974, 21253, - 23045, 25058, 27741, 30315, - 1943, 2730, 4140, 6160, - 7491, 8986, 11309, 12775, - 14820, 16558, 17909, 19757, - 21512, 23605, 27274, 29527, - 2021, 2582, 4494, 5835, - 6993, 8245, 9827, 14733, - 16462, 17894, 19647, 21083, - 23764, 26667, 29072, 30990, - 1052, 1775, 3218, 4378, - 7666, 9403, 11248, 13327, - 14972, 17962, 20758, 22354, - 25071, 27209, 29001, 30609, - 2218, 2866, 4223, 5352, - 6581, 9980, 11587, 13121, - 15193, 16583, 18386, 20080, - 22013, 25317, 28127, 29880, - 2146, 2840, 4397, 5840, - 7449, 8721, 10512, 11936, - 13595, 17253, 19310, 20891, - 23417, 25627, 27749, 30231, - 1972, 2619, 3756, 6367, - 7641, 8814, 12286, 13768, - 15309, 18036, 19557, 20904, - 22582, 24876, 27800, 30440, - 2005, 2577, 4272, 7373, - 8558, 10223, 11770, 13402, - 16502, 18000, 19645, 21104, - 22990, 26806, 29505, 30942, - 1153, 1822, 3724, 5443, - 6990, 8702, 10289, 11899, - 13856, 15315, 17601, 21064, - 23692, 26083, 28586, 30639, - 1304, 1869, 3318, 7195, - 9613, 10733, 12393, 13728, - 15822, 17474, 18882, 20692, - 23114, 25540, 27684, 29244, - 2093, 2691, 4018, 6658, - 7947, 9147, 10497, 11881, - 15888, 17821, 19333, 21233, - 23371, 25234, 27553, 29998, - 575, 1331, 5304, 6910, - 8425, 10086, 11577, 13498, - 16444, 18527, 20565, 22847, - 24914, 26692, 28759, 30157, - 1435, 2024, 3283, 4156, - 7611, 10592, 12049, 13927, - 15459, 18413, 20495, 22270, - 24222, 26093, 28065, 30099, - 1632, 2168, 5540, 7478, - 8630, 10391, 11644, 14321, - 15741, 17357, 18756, 20434, - 22799, 26060, 28542, 30696, - 1407, 2245, 3405, 5639, - 9419, 10685, 12104, 13495, - 15535, 18357, 19996, 21689, - 24351, 26550, 28853, 30564, - 1675, 2226, 4005, 8223, - 9975, 11155, 12822, 14316, - 16504, 18137, 19574, 21050, - 22759, 24912, 28296, 30634, - 1080, 1614, 3622, 7565, - 8748, 10303, 11713, 13848, - 15633, 17434, 19761, 21825, - 23571, 25393, 27406, 29063, - 1693, 2229, 3456, 4354, - 5670, 10890, 12563, 14167, - 15879, 17377, 19817, 21971, - 24094, 26131, 28298, 30099, - 2042, 2959, 4195, 5740, - 7106, 8267, 11126, 14973, - 16914, 18295, 20532, 21982, - 23711, 25769, 27609, 29351, - 984, 1612, 3808, 5265, - 6885, 8411, 9547, 10889, - 12522, 16520, 19549, 21639, - 23746, 26058, 28310, 30374, - 2036, 2538, 4166, 7761, - 9146, 10412, 12144, 13609, - 15588, 17169, 18559, 20113, - 21820, 24313, 28029, 30612, - 1871, 2355, 4061, 5143, - 7464, 10129, 11941, 15001, - 16680, 18354, 19957, 22279, - 24861, 26872, 28988, 30615, - 2566, 3161, 4643, 6227, - 7406, 9970, 11618, 13416, - 15889, 17364, 19121, 20817, - 22592, 24720, 28733, 31082, - 1700, 2327, 4828, 5939, - 7567, 9154, 11087, 12771, - 14209, 16121, 20222, 22671, - 24648, 26656, 28696, 30745, - 3169, 3873, 5046, 6868, - 8184, 9480, 12335, 14068, - 15774, 17971, 20231, 21711, - 23520, 25245, 27026, 28730, - 1564, 2391, 4229, 6730, - 8905, 10459, 13026, 15033, - 17265, 19809, 21849, 23741, - 25490, 27312, 29061, 30527, - 2864, 3559, 4719, 6441, - 9592, 11055, 12763, 14784, - 16428, 18164, 20486, 22262, - 24183, 26263, 28383, 30224, - 2673, 3449, 4581, 5983, - 6863, 8311, 12464, 13911, - 15738, 17791, 19416, 21182, - 24025, 26561, 28723, 30440, - 2419, 3049, 4274, 6384, - 8564, 9661, 11288, 12676, - 14447, 17578, 19816, 21231, - 23099, 25270, 26899, 28926, - 1278, 2001, 3000, 5353, - 9995, 11777, 13018, 14570, - 16050, 17762, 19982, 21617, - 23371, 25083, 27656, 30172, - 932, 1624, 2798, 4570, - 8592, 9988, 11552, 13050, - 16921, 18677, 20415, 22810, - 24817, 26819, 28804, 30385, - 2324, 2973, 4156, 5702, - 6919, 8806, 10259, 12503, - 15015, 16567, 19418, 21375, - 22943, 24550, 27024, 29849, - 1564, 2373, 3455, 4907, - 5975, 7436, 11786, 14505, - 16107, 18148, 20019, 21653, - 23740, 25814, 28578, 30372, - 3025, 3729, 4866, 6520, - 9487, 10943, 12358, 14258, - 16174, 17501, 19476, 21408, - 23227, 24906, 27347, 29407, - 1270, 1965, 6802, 7995, - 9204, 10828, 12507, 14230, - 15759, 17860, 20369, 22502, - 24633, 26514, 28535, 30525, - 2210, 2749, 4266, 7487, - 9878, 11018, 12823, 14431, - 16247, 18626, 20450, 22054, - 23739, 25291, 27074, 29169, - 1275, 1926, 4330, 6573, - 8441, 10920, 13260, 15008, - 16927, 18573, 20644, 22217, - 23983, 25474, 27372, 28645, - 3015, 3670, 5086, 6372, - 7888, 9309, 10966, 12642, - 14495, 16172, 18080, 19972, - 22454, 24899, 27362, 29975, - 2882, 3733, 5113, 6482, - 8125, 9685, 11598, 13288, - 15405, 17192, 20178, 22426, - 24801, 27014, 29212, 30811, - 2300, 2968, 4101, 5442, - 6327, 7910, 12455, 13862, - 15747, 17505, 19053, 20679, - 22615, 24658, 27499, 30065, - 2257, 2940, 4430, 5991, - 7042, 8364, 9414, 11224, - 15723, 17420, 19253, 21469, - 23915, 26053, 28430, 30384, - 1227, 2045, 3818, 5011, - 6990, 9231, 11024, 13011, - 17341, 19017, 20583, 22799, - 25195, 26876, 29351, 30805, - 1354, 1924, 3789, 8077, - 10453, 11639, 13352, 14817, - 16743, 18189, 20095, 22014, - 24593, 26677, 28647, 30256, - 3142, 4049, 6197, 7417, - 8753, 10156, 11533, 13181, - 15947, 17655, 19606, 21402, - 23487, 25659, 28123, 30304, - 1317, 2263, 4725, 7611, - 9667, 11634, 14143, 16258, - 18724, 20698, 22379, 24007, - 25775, 27251, 28930, 30593, - 1570, 2323, 3818, 6215, - 9893, 11556, 13070, 14631, - 16152, 18290, 21386, 23346, - 25114, 26923, 28712, 30168, - 2297, 3905, 6287, 8558, - 10668, 12766, 15019, 17102, - 19036, 20677, 22341, 23871, - 25478, 27085, 28851, 30520, - 1915, 2507, 4033, 5749, - 7059, 8871, 10659, 12198, - 13937, 15383, 16869, 18707, - 23175, 25818, 28514, 30501, - 2404, 2918, 5190, 6252, - 7426, 9887, 12387, 14795, - 16754, 18368, 20338, 22003, - 24236, 26456, 28490, 30397, - 1621, 2227, 3479, 5085, - 9425, 12892, 14246, 15652, - 17205, 18674, 20446, 22209, - 23778, 25867, 27931, 30093, - 1869, 2390, 4105, 7021, - 11221, 12775, 14059, 15590, - 17024, 18608, 20595, 22075, - 23649, 25154, 26914, 28671, - 2551, 3252, 4688, 6562, - 7869, 9125, 10475, 11800, - 15402, 18780, 20992, 22555, - 24289, 25968, 27465, 29232, - 2705, 3493, 4735, 6360, - 7905, 9352, 11538, 13430, - 15239, 16919, 18619, 20094, - 21800, 23342, 25200, 29257, - 2166, 2791, 4011, 5081, - 5896, 9038, 13407, 14703, - 16543, 18189, 19896, 21857, - 24872, 26971, 28955, 30514, - 1865, 3021, 4696, 6534, - 8343, 9914, 12789, 14103, - 16533, 17729, 21340, 22439, - 24873, 26330, 28428, 30154, - 3369, 4345, 6573, 8763, - 10309, 11713, 13367, 14784, - 16483, 18145, 19839, 21247, - 23292, 25477, 27555, 29447, - 1265, 2184, 5443, 7893, - 10591, 13139, 15105, 16639, - 18402, 19826, 21419, 22995, - 24719, 26437, 28363, 30125, - 1584, 2004, 3535, 4450, - 8662, 10764, 12832, 14978, - 16972, 18794, 20932, 22547, - 24636, 26521, 28701, 30567, - 3419, 4528, 6602, 7890, - 9508, 10875, 12771, 14357, - 16051, 18330, 20630, 22490, - 25070, 26936, 28946, 30542, - 1726, 2252, 4597, 6950, - 8379, 9823, 11363, 12794, - 14306, 15476, 16798, 18018, - 21671, 25550, 28148, 30367, - 3385, 3870, 5307, 6388, - 7141, 8684, 12695, 14939, - 16480, 18277, 20537, 22048, - 23947, 25965, 28214, 29956, - 2771, 3306, 4450, 5560, - 6453, 9493, 13548, 14754, - 16743, 18447, 20028, 21736, - 23746, 25353, 27141, 29066, - 3028, 3900, 6617, 7893, - 9211, 10480, 12047, 13583, - 15182, 16662, 18502, 20092, - 22190, 24358, 26302, 28957, - 2000, 2550, 4067, 6837, - 9628, 11002, 12594, 14098, - 15589, 17195, 18679, 20099, - 21530, 23085, 24641, 29022, - 2844, 3302, 5103, 6107, - 6911, 8598, 12416, 14054, - 16026, 18567, 20672, 22270, - 23952, 25771, 27658, 30026, - 4043, 5150, 7268, 9056, - 10916, 12638, 14543, 16184, - 17948, 19691, 21357, 22981, - 24825, 26591, 28479, 30233, - 2109, 2625, 4320, 5525, - 7454, 10220, 12980, 14698, - 17627, 19263, 20485, 22381, - 24279, 25777, 27847, 30458, - 1550, 2667, 6473, 9496, - 10985, 12352, 13795, 15233, - 17099, 18642, 20461, 22116, - 24197, 26291, 28403, 30132, - 2411, 3084, 4145, 5394, - 6367, 8154, 13125, 16049, - 17561, 19125, 21258, 22762, - 24459, 26317, 28255, 29702, - 4159, 4516, 5956, 7635, - 8254, 8980, 11208, 14133, - 16210, 17875, 20196, 21864, - 23840, 25747, 28058, 30012, - 2026, 2431, 2845, 3618, - 7950, 9802, 12721, 14460, - 16576, 18984, 21376, 23319, - 24961, 26718, 28971, 30640, - 3429, 3833, 4472, 4912, - 7723, 10386, 12981, 15322, - 16699, 18807, 20778, 22551, - 24627, 26494, 28334, 30482, - 4740, 5169, 5796, 6485, - 6998, 8830, 11777, 14414, - 16831, 18413, 20789, 22369, - 24236, 25835, 27807, 30021, - 150, 168, -17, -107, - -142, -229, -320, -406, - -503, -620, -867, -935, - -902, -680, -398, -114, - -398, -355, 49, 255, - 114, 260, 399, 264, - 317, 431, 514, 531, - 435, 356, 238, 106, - -43, -36, -169, -224, - -391, -633, -776, -970, - -844, -455, -181, -12, - 85, 85, 164, 195, - 122, 85, -158, -640, - -903, 9, 7, -124, - 149, 32, 220, 369, - 242, 115, 79, 84, - -146, -216, -70, 1024, - 751, 574, 440, 377, - 352, 203, 30, 16, - -3, 81, 161, 100, - -148, -176, 933, 750, - 404, 171, -2, -146, - -411, -442, -541, -552, - -442, -269, -240, -52, - 603, 635, 405, 178, - 215, 19, -153, -167, - -290, -219, 151, 271, - 151, 119, 303, 266, - 100, 69, -293, -657, - 939, 659, 442, 351, - 132, 98, -16, -1, - -135, -200, -223, -89, - 167, 154, 172, 237, - -45, -183, -228, -486, - 263, 608, 158, -125, - -390, -227, -118, 43, - -457, -392, -769, -840, - 20, -117, -194, -189, - -173, -173, -33, 32, - 174, 144, 115, 167, - 57, 44, 14, 147, - 96, -54, -142, -129, - -254, -331, 304, 310, - -52, -419, -846, -1060, - -88, -123, -202, -343, - -554, -961, -951, 327, - 159, 81, 255, 227, - 120, 203, 256, 192, - 164, 224, 290, 195, - 216, 209, 128, 832, - 1028, 889, 698, 504, - 408, 355, 218, 32, - -115, -84, -276, -100, - -312, -484, 899, 682, - 465, 456, 241, -12, - -275, -425, -461, -367, - -33, -28, -102, -194, - -527, 863, 906, 463, - 245, 13, -212, -305, - -105, 163, 279, 176, - 93, 67, 115, 192, - 61, -50, -132, -175, - -224, -271, -629, -252, - 1158, 972, 638, 280, - 300, 326, 143, -152, - -214, -287, 53, -42, - -236, -352, -423, -248, - -129, -163, -178, -119, - 85, 57, 514, 382, - 374, 402, 424, 423, - 271, 197, 97, 40, - 39, -97, -191, -164, - -230, -256, -410, 396, - 327, 127, 10, -119, - -167, -291, -274, -141, - -99, -226, -218, -139, - -224, -209, -268, -442, - -413, 222, 58, 521, - 344, 258, 76, -42, - -142, -165, -123, -92, - 47, 8, -3, -191, - -11, -164, -167, -351, - -740, 311, 538, 291, - 184, 29, -105, 9, - -30, -54, -17, -77, - -271, -412, -622, -648, - 476, 186, -66, -197, - -73, -94, -15, 47, - 28, 112, -58, -33, - 65, 19, 84, 86, - 276, 114, 472, 786, - 799, 625, 415, 178, - -35, -26, 5, 9, - 83, 39, 37, 39, - -184, -374, -265, -362, - -501, 337, 716, 478, - -60, -125, -163, 362, - 17, -122, -233, 279, - 138, 157, 318, 193, - 189, 209, 266, 252, - -46, -56, -277, -429, - 464, 386, 142, 44, - -43, 66, 264, 182, - 47, 14, -26, -79, - 49, 15, -128, -203, - -400, -478, 325, 27, - 234, 411, 205, 129, - 12, 58, 123, 57, - 171, 137, 96, 128, - -32, 134, -12, 57, - 119, 26, -22, -165, - -500, -701, -528, -116, - 64, -8, 97, -9, - -162, -66, -156, -194, - -303, -546, -341, 546, - 358, 95, 45, 76, - 270, 403, 205, 100, - 123, 50, -53, -144, - -110, -13, 32, -228, - -130, 353, 296, 56, - -372, -253, 365, 73, - 10, -34, -139, -191, - -96, 5, 44, -85, - -179, -129, -192, -246, - -85, -110, -155, -44, - -27, 145, 138, 79, - 32, -148, -577, -634, - 191, 94, -9, -35, - -77, -84, -56, -171, - -298, -271, -243, -156, - -328, -235, -76, -128, - -121, 129, 13, -22, - 32, 45, -248, -65, - 193, -81, 299, 57, - -147, 192, -165, -354, - -334, -106, -156, -40, - -3, -68, 124, -257, - 78, 124, 170, 412, - 227, 105, -104, 12, - 154, 250, 274, 258, - 4, -27, 235, 152, - 51, 338, 300, 7, - -314, -411, 215, 170, - -9, -93, -77, 76, - 67, 54, 200, 315, - 163, 72, -91, -402, - 158, 187, -156, -91, - 290, 267, 167, 91, - 140, 171, 112, 9, - -42, -177, -440, 385, - 80, 15, 172, 129, - 41, -129, -372, -24, - -75, -30, -170, 10, - -118, 57, 78, -101, - 232, 161, 123, 256, - 277, 101, -192, -629, - -100, -60, -232, 66, - 13, -13, -80, -239, - 239, 37, 32, 89, - -319, -579, 450, 360, - 3, -29, -299, -89, - -54, -110, -246, -164, - 6, -188, 338, 176, - -92, 197, 137, 134, - 12, -2, 56, -183, - 114, -36, -131, -204, - 75, -25, -174, 191, - -15, -290, -429, -267, - 79, 37, 106, 23, - -384, 425, 70, -14, - 212, 105, 15, -2, - -42, -37, -123, 108, - 28, -48, 193, 197, - 173, -33, 37, 73, - -57, 256, 137, -58, - -430, -228, 217, -51, - -10, -58, -6, 22, - 104, 61, -119, 169, - 144, 16, -46, -394, - 60, 454, -80, -298, - -65, 25, 0, -24, - -65, -417, 465, 276, - -3, -194, -13, 130, - 19, -6, -21, -24, - -180, -53, -85, 20, - 118, 147, 113, -75, - -289, 226, -122, 227, - 270, 125, 109, 197, - 125, 138, 44, 60, - 25, -55, -167, -32, - -139, -193, -173, -316, - 287, -208, 253, 239, - 27, -80, -188, -28, - -182, -235, 156, -117, - 128, -48, -58, -226, - 172, 181, 167, 19, - 62, 10, 2, 181, - 151, 108, -16, -11, - -78, -331, 411, 133, - 17, 104, 64, -184, - 24, -30, -3, -283, - 121, 204, -8, -199, - -21, -80, -169, -157, - -191, -136, 81, 155, - 14, -131, 244, 74, - -57, -47, -280, 347, - 111, -77, -128, -142, - -194, -125, -6, -68, - 91, 1, 23, 14, - -154, -34, 23, -38, - -343, 503, 146, -38, - -46, -41, 58, 31, - 63, -48, -117, 45, - 28, 1, -89, -5, - -44, -29, -448, 487, - 204, 81, 46, -106, - -302, 380, 120, -38, - -12, -39, 70, -3, - 25, -65, 30, -11, - 34, -15, 22, -115, - 0, -79, -83, 45, - 114, 43, 150, 36, - 233, 149, 195, 5, - 25, -52, -475, 274, - 28, -39, -8, -66, - -255, 258, 56, 143, - -45, -190, 165, -60, - 20, 2, 125, -129, - 51, -8, -335, 288, - 38, 59, 25, -42, - 23, -118, -112, 11, - -55, -133, -109, 24, - -105, 78, -64, -245, - 202, -65, -127, 162, - 40, -94, 89, -85, - -119, -103, 97, 9, - -70, -28, 194, 86, - -112, -92, -114, 74, - -49, 46, -84, -178, - 113, 52, -205, 333, - 88, 222, 56, -55, - 13, 86, 4, -77, - 224, 114, -105, 112, - 125, -29, -18, -144, - 22, -58, -99, 28, - 114, -66, -32, -169, - -314, 285, 72, -74, - 179, 28, -79, -182, - 13, -55, 147, 13, - 12, -54, 31, -84, - -17, -75, -228, 83, - -375, 436, 110, -63, - -27, -136, 169, -56, - -8, -171, 184, -42, - 148, 68, 204, 235, - 110, -229, 91, 171, - -43, -3, -26, -99, - -111, 71, -170, 202, - -67, 181, -37, 109, - -120, 3, -55, -260, - -16, 152, 91, 142, - 42, 44, 134, 47, - 17, -35, 22, 79, - -169, 41, 46, 277, - -93, -49, -126, 37, - -103, -34, -22, -90, - -134, -205, 92, -9, - 1, -195, -239, 45, - 54, 18, -23, -1, - -80, -98, -20, -261, - 306, 72, 20, -89, - -217, 11, 6, -82, - 89, 13, -129, -89, - 83, -71, -55, 130, - -98, -146, -27, -57, - 53, 275, 17, 170, - -5, -54, 132, -64, - 72, 160, -125, -168, - 72, 40, 170, 78, - 248, 116, 20, 84, - 31, -34, 190, 38, - 13, -106, 225, 27, - -168, 24, -157, -122, - 165, 11, -161, -213, - -12, -51, -101, 42, - 101, 27, 55, 111, - 75, 71, -96, -1, - 65, -277, 393, -26, - -44, -68, -84, -66, - -95, 235, 179, -25, - -41, 27, -91, -128, - -222, 146, -72, -30, - -24, 55, -126, -68, - -58, -127, 13, -97, - -106, 174, -100, 155, - 101, -146, -21, 261, - 22, 38, -66, 65, - 4, 70, 64, 144, - 59, 213, 71, -337, - 303, -52, 51, -56, - 1, 10, -15, -5, - 34, 52, 228, 131, - 161, -127, -214, 238, - 123, 64, -147, -50, - -34, -127, 204, 162, - 85, 41, 5, -140, - 73, -150, 56, -96, - -66, -20, 2, -235, - 59, -22, -107, 150, - -16, -47, -4, 81, - -67, 167, 149, 149, - -157, 288, -156, -27, - -8, 18, 83, -24, - -41, -167, 158, -100, - 93, 53, 201, 15, - 42, 266, 278, -12, - -6, -37, 85, 6, - 20, -188, -271, 107, - -13, -80, 51, 202, - 173, -69, 78, -188, - 46, 4, 153, 12, - -138, 169, 5, -58, - -123, -108, -243, 150, - 10, -191, 246, -15, - 38, 25, -10, 14, - 61, 50, -206, -215, - -220, 90, 5, -149, - -219, 56, 142, 24, - -376, 77, -80, 75, - 6, 42, -101, 16, - 56, 14, -57, 3, - -17, 80, 57, -36, - 88, -59, -97, -19, - -148, 46, -219, 226, - 114, -4, -72, -15, - 37, -49, -28, 247, - 44, 123, 47, -122, - -38, 17, 4, -113, - -32, -224, 154, -134, - 196, 71, -267, -85, - 28, -70, 89, -120, - 99, -2, 64, 76, - -166, -48, 189, -35, - -92, -169, -123, 339, - 38, -25, 38, -35, - 225, -139, -50, -63, - 246, 60, -185, -109, - -49, -53, -167, 51, - 149, 60, -101, -33, - 25, -76, 120, 32, - -30, -83, 102, 91, - -186, -261, 131, -197 - }; - - static final SKP_Silk_NLSF_CBS[] SKP_Silk_NLSF_CB0_16_Stage_info = - { - new SKP_Silk_NLSF_CBS(128, SKP_Silk_NLSF_MSVQ_CB0_16_Q15, 16 * 0, SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5, 0), - new SKP_Silk_NLSF_CBS(16, SKP_Silk_NLSF_MSVQ_CB0_16_Q15, 16 * 128, SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5, 128), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB0_16_Q15, 16 * 144, SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5, 144), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB0_16_Q15, 16 * 152, SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5, 152), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB0_16_Q15, 16 * 160, SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5, 160), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB0_16_Q15, 16 * 168, SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5, 168), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB0_16_Q15, 16 * 176, SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5, 176), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB0_16_Q15, 16 * 184, SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5, 184), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB0_16_Q15, 16 * 192, SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5, 192), - new SKP_Silk_NLSF_CBS(16, SKP_Silk_NLSF_MSVQ_CB0_16_Q15, 16 * 200, SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5, 200), - }; - - static final SKP_Silk_NLSF_CB_struct SKP_Silk_NLSF_CB0_16 = - new SKP_Silk_NLSF_CB_struct - ( - NLSF_MSVQ_CB0_16_STAGES, - SKP_Silk_NLSF_CB0_16_Stage_info, - SKP_Silk_NLSF_MSVQ_CB0_16_ndelta_min_Q15, - SKP_Silk_NLSF_MSVQ_CB0_16_CDF, - SKP_Silk_NLSF_MSVQ_CB0_16_CDF_start_ptr, - SKP_Silk_NLSF_MSVQ_CB0_16_CDF_middle_idx - ); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB0_16_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB0_16_FLP.java deleted file mode 100644 index b0fc4c368..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB0_16_FLP.java +++ /dev/null @@ -1,1930 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * This file has been automatically generated. - * ROM usage: 14.76 kB. - * - * @author Dingxin Xu - */ -public class Silk_tables_NLSF_CB0_16_FLP -{ -// const SKP_float SKP_Silk_NLSF_MSVQ_CB0_16_rates[ NLSF_MSVQ_CB0_16_VECTORS ] = - static final float SKP_Silk_NLSF_MSVQ_CB0_16_rates[] = - { - 5.50000000000000000000f, 5.65625000000000000000f, - 5.68750000000000000000f, 5.71875000000000000000f, - 5.81250000000000000000f, 5.81250000000000000000f, - 5.96875000000000000000f, 5.96875000000000000000f, - 5.96875000000000000000f, 6.12500000000000000000f, - 6.15625000000000000000f, 6.28125000000000000000f, - 6.34375000000000000000f, 6.43750000000000000000f, - 6.43750000000000000000f, 6.43750000000000000000f, - 6.46875000000000000000f, 6.46875000000000000000f, - 6.53125000000000000000f, 6.53125000000000000000f, - 6.53125000000000000000f, 6.53125000000000000000f, - 6.56250000000000000000f, 6.56250000000000000000f, - 6.56250000000000000000f, 6.59375000000000000000f, - 6.59375000000000000000f, 6.59375000000000000000f, - 6.62500000000000000000f, 6.68750000000000000000f, - 6.75000000000000000000f, 6.75000000000000000000f, - 6.78125000000000000000f, 6.78125000000000000000f, - 6.78125000000000000000f, 6.78125000000000000000f, - 6.81250000000000000000f, 6.81250000000000000000f, - 6.84375000000000000000f, 6.84375000000000000000f, - 6.87500000000000000000f, 6.90625000000000000000f, - 6.93750000000000000000f, 6.96875000000000000000f, - 6.96875000000000000000f, 6.96875000000000000000f, - 6.96875000000000000000f, 7.00000000000000000000f, - 7.00000000000000000000f, 7.00000000000000000000f, - 7.03125000000000000000f, 7.03125000000000000000f, - 7.06250000000000000000f, 7.06250000000000000000f, - 7.06250000000000000000f, 7.06250000000000000000f, - 7.09375000000000000000f, 7.09375000000000000000f, - 7.09375000000000000000f, 7.09375000000000000000f, - 7.09375000000000000000f, 7.09375000000000000000f, - 7.12500000000000000000f, 7.12500000000000000000f, - 7.12500000000000000000f, 7.12500000000000000000f, - 7.15625000000000000000f, 7.15625000000000000000f, - 7.15625000000000000000f, 7.18750000000000000000f, - 7.18750000000000000000f, 7.18750000000000000000f, - 7.21875000000000000000f, 7.21875000000000000000f, - 7.21875000000000000000f, 7.21875000000000000000f, - 7.25000000000000000000f, 7.25000000000000000000f, - 7.25000000000000000000f, 7.25000000000000000000f, - 7.28125000000000000000f, 7.31250000000000000000f, - 7.34375000000000000000f, 7.34375000000000000000f, - 7.34375000000000000000f, 7.37500000000000000000f, - 7.37500000000000000000f, 7.37500000000000000000f, - 7.37500000000000000000f, 7.40625000000000000000f, - 7.40625000000000000000f, 7.40625000000000000000f, - 7.40625000000000000000f, 7.50000000000000000000f, - 7.50000000000000000000f, 7.50000000000000000000f, - 7.50000000000000000000f, 7.53125000000000000000f, - 7.56250000000000000000f, 7.59375000000000000000f, - 7.62500000000000000000f, 7.62500000000000000000f, - 7.71875000000000000000f, 7.71875000000000000000f, - 7.75000000000000000000f, 7.75000000000000000000f, - 7.75000000000000000000f, 7.78125000000000000000f, - 7.84375000000000000000f, 7.96875000000000000000f, - 7.96875000000000000000f, 8.00000000000000000000f, - 8.12500000000000000000f, 8.12500000000000000000f, - 8.15625000000000000000f, 8.25000000000000000000f, - 8.25000000000000000000f, 8.31250000000000000000f, - 8.31250000000000000000f, 8.37500000000000000000f, - 8.46875000000000000000f, 8.56250000000000000000f, - 8.62500000000000000000f, 8.71875000000000000000f, - 9.00000000000000000000f, 9.00000000000000000000f, - 9.00000000000000000000f, 9.00000000000000000000f, - 3.68750000000000000000f, 3.75000000000000000000f, - 3.78125000000000000000f, 3.78125000000000000000f, - 3.81250000000000000000f, 3.90625000000000000000f, - 3.90625000000000000000f, 4.03125000000000000000f, - 4.03125000000000000000f, 4.06250000000000000000f, - 4.09375000000000000000f, 4.12500000000000000000f, - 4.25000000000000000000f, 4.28125000000000000000f, - 4.31250000000000000000f, 4.53125000000000000000f, - 2.71875000000000000000f, 2.75000000000000000000f, - 2.84375000000000000000f, 3.03125000000000000000f, - 3.06250000000000000000f, 3.12500000000000000000f, - 3.28125000000000000000f, 3.31250000000000000000f, - 2.87500000000000000000f, 2.96875000000000000000f, - 2.96875000000000000000f, 3.00000000000000000000f, - 3.03125000000000000000f, 3.03125000000000000000f, - 3.06250000000000000000f, 3.09375000000000000000f, - 2.75000000000000000000f, 2.87500000000000000000f, - 2.96875000000000000000f, 2.96875000000000000000f, - 3.00000000000000000000f, 3.03125000000000000000f, - 3.06250000000000000000f, 3.40625000000000000000f, - 2.90625000000000000000f, 2.90625000000000000000f, - 2.90625000000000000000f, 3.00000000000000000000f, - 3.03125000000000000000f, 3.03125000000000000000f, - 3.09375000000000000000f, 3.15625000000000000000f, - 2.90625000000000000000f, 2.93750000000000000000f, - 2.93750000000000000000f, 2.96875000000000000000f, - 2.96875000000000000000f, 3.09375000000000000000f, - 3.09375000000000000000f, 3.09375000000000000000f, - 2.90625000000000000000f, 2.90625000000000000000f, - 2.90625000000000000000f, 3.00000000000000000000f, - 3.00000000000000000000f, 3.03125000000000000000f, - 3.12500000000000000000f, 3.18750000000000000000f, - 2.90625000000000000000f, 2.96875000000000000000f, - 2.96875000000000000000f, 3.00000000000000000000f, - 3.00000000000000000000f, 3.00000000000000000000f, - 3.06250000000000000000f, 3.09375000000000000000f, - 3.90625000000000000000f, 3.90625000000000000000f, - 3.96875000000000000000f, 3.96875000000000000000f, - 3.96875000000000000000f, 3.96875000000000000000f, - 4.00000000000000000000f, 4.00000000000000000000f, - 4.00000000000000000000f, 4.00000000000000000000f, - 4.00000000000000000000f, 4.00000000000000000000f, - 4.03125000000000000000f, 4.06250000000000000000f, - 4.09375000000000000000f, 4.12500000000000000000f - }; - -// const SKP_float SKP_Silk_NLSF_MSVQ_CB0_16_ndelta_min[ 16 + 1 ] = - static final float SKP_Silk_NLSF_MSVQ_CB0_16_ndelta_min[] = - { - 0.00811767578125000000f, - 0.00009155273437500000f, - 0.00122070312500000000f, - 0.00009155273437500000f, - 0.00009155273437500000f, - 0.00048828125000000000f, - 0.00238037109375000000f, - 0.00271606445312500000f, - 0.00326538085937500000f, - 0.00430297851562500000f, - 0.00573730468750000000f, - 0.00445556640625000000f, - 0.00830078125000000000f, - 0.00732421874999999910f, - 0.00717163085937500000f, - 0.00656127929687500000f, - 0.01928710937500000000f - }; - -// const SKP_float SKP_Silk_NLSF_MSVQ_CB0_16[ 16 * NLSF_MSVQ_CB0_16_VECTORS ] = - static final float SKP_Silk_NLSF_MSVQ_CB0_16[] = - { - 0.03570556640625000000f, 0.06951904296875000000f, - 0.11163330078125001000f, 0.16400146484375000000f, - 0.23394775390625000000f, 0.27810668945312500000f, - 0.34478759765624994000f, 0.40600585937500000000f, - 0.46908569335937500000f, 0.53555297851562500000f, - 0.59774780273437500000f, 0.65573120117187500000f, - 0.72625732421875000000f, 0.79461669921875000000f, - 0.86419677734375000000f, 0.92166137695312500000f, - 0.04968261718750000700f, 0.07122802734375000000f, - 0.12557983398437500000f, 0.18420410156250000000f, - 0.23858642578125000000f, 0.29125976562500000000f, - 0.35940551757812500000f, 0.42788696289062500000f, - 0.48178100585937500000f, 0.53125000000000000000f, - 0.59405517578125000000f, 0.64883422851562500000f, - 0.69842529296875000000f, 0.74966430664062500000f, - 0.81524658203125000000f, 0.85629272460937500000f, - 0.05261230468750000000f, 0.08148193359375000000f, - 0.12377929687500000000f, 0.19934082031250000000f, - 0.25503540039062500000f, 0.30880737304687500000f, - 0.36904907226562506000f, 0.42910766601562500000f, - 0.50326538085937500000f, 0.57357788085937500000f, - 0.62307739257812500000f, 0.68365478515625000000f, - 0.74008178710937511000f, 0.80029296875000011000f, - 0.86700439453125000000f, 0.91418457031250000000f, - 0.04556274414062500000f, 0.10458374023437501000f, - 0.14614868164062500000f, 0.19528198242187500000f, - 0.25741577148437500000f, 0.31030273437500000000f, - 0.36621093750000000000f, 0.42926025390625000000f, - 0.49526977539062500000f, 0.55572509765625000000f, - 0.61157226562500000000f, 0.67437744140625000000f, - 0.73709106445312500000f, 0.79635620117187500000f, - 0.86007690429687500000f, 0.91921997070312489000f, - 0.03414916992187500000f, 0.06375122070312500000f, - 0.13107299804687500000f, 0.19058227539062500000f, - 0.26522827148437500000f, 0.32778930664062500000f, - 0.38720703125000000000f, 0.45950317382812500000f, - 0.51965332031250000000f, 0.57348632812500000000f, - 0.63223266601562500000f, 0.68707275390625011000f, - 0.74758911132812500000f, 0.81018066406250000000f, - 0.87338256835937500000f, 0.93475341796875000000f, - 0.04159545898437500000f, 0.07376098632812500000f, - 0.11984252929687500000f, 0.16955566406249997000f, - 0.22650146484375000000f, 0.28427124023437500000f, - 0.36251831054687500000f, 0.42013549804687500000f, - 0.49264526367187500000f, 0.56518554687500000000f, - 0.62432861328125000000f, 0.68902587890625000000f, - 0.74887084960937500000f, 0.80676269531250000000f, - 0.86419677734375000000f, 0.92523193359375000000f, - 0.03424072265625000000f, 0.07638549804687500000f, - 0.15917968750000000000f, 0.21813964843750000000f, - 0.28411865234375000000f, 0.33807373046874994000f, - 0.40206909179687500000f, 0.45166015625000000000f, - 0.51464843750000000000f, 0.57067871093750000000f, - 0.62365722656250000000f, 0.68627929687499989000f, - 0.74987792968750011000f, 0.81182861328125000000f, - 0.87142944335937500000f, 0.92852783203125000000f, - 0.01831054687500000000f, 0.04019165039062500700f, - 0.09063720703125001400f, 0.17117309570312500000f, - 0.23480224609375000000f, 0.29858398437500000000f, - 0.37136840820312500000f, 0.42990112304687506000f, - 0.49984741210937494000f, 0.56085205078125000000f, - 0.62716674804687500000f, 0.69232177734375000000f, - 0.75497436523437489000f, 0.81472778320312500000f, - 0.87420654296875000000f, 0.92636108398437500000f, - 0.02871704101562500000f, 0.05743408203125000000f, - 0.13043212890625000000f, 0.16906738281250000000f, - 0.25885009765625000000f, 0.30084228515625000000f, - 0.36437988281250000000f, 0.43600463867187494000f, - 0.49105834960937506000f, 0.56460571289062500000f, - 0.62030029296875000000f, 0.69006347656250000000f, - 0.75411987304687511000f, 0.81292724609374989000f, - 0.87933349609375000000f, 0.92864990234375000000f, - 0.01937866210937500000f, 0.05184936523437500000f, - 0.13354492187500000000f, 0.18151855468750000000f, - 0.24710083007812500000f, 0.30868530273437500000f, - 0.37457275390625000000f, 0.43267822265625000000f, - 0.49166870117187500000f, 0.54360961914062500000f, - 0.60104370117187500000f, 0.66445922851562511000f, - 0.73019409179687500000f, 0.78936767578124989000f, - 0.85516357421875000000f, 0.91961669921875000000f, - 0.04296874999999999300f, 0.06781005859375000000f, - 0.10754394531250000000f, 0.17135620117187503000f, - 0.22415161132812497000f, 0.27005004882812500000f, - 0.33535766601562500000f, 0.38977050781250000000f, - 0.46850585937500000000f, 0.51959228515625000000f, - 0.57736206054687500000f, 0.64276123046875000000f, - 0.71194458007812500000f, 0.76950073242187500000f, - 0.83035278320312511000f, 0.88571166992187500000f, - 0.02139282226562500000f, 0.03988647460937500000f, - 0.10827636718750001000f, 0.19229125976562500000f, - 0.23632812500000000000f, 0.29217529296875000000f, - 0.34262084960937494000f, 0.39605712890625000000f, - 0.46295166015625000000f, 0.53604125976562500000f, - 0.60348510742187500000f, 0.67434692382812500000f, - 0.73944091796875000000f, 0.80368041992187500000f, - 0.86599731445312500000f, 0.92257690429687500000f, - 0.05346679687500000700f, 0.07214355468750000000f, - 0.14889526367187500000f, 0.20046997070312500000f, - 0.23843383789062500000f, 0.29895019531250000000f, - 0.34176635742187500000f, 0.43609619140625006000f, - 0.48202514648437500000f, 0.54931640625000000000f, - 0.62243652343750000000f, 0.68411254882812489000f, - 0.74182128906250011000f, 0.79724121093750000000f, - 0.86547851562500000000f, 0.93484497070312500000f, - 0.02749633789062500000f, 0.04971313476562500000f, - 0.10241699218749999000f, 0.14144897460937500000f, - 0.22143554687500000000f, 0.26754760742187500000f, - 0.30429077148437500000f, 0.35272216796875000000f, - 0.46432495117187500000f, 0.53540039062500000000f, - 0.59579467773437500000f, 0.66687011718750000000f, - 0.72937011718750000000f, 0.79278564453125000000f, - 0.85855102539062500000f, 0.92114257812500000000f, - 0.02993774414062500000f, 0.05093383789062500000f, - 0.10140991210937499000f, 0.14321899414062500000f, - 0.18960571289062500000f, 0.26525878906250000000f, - 0.32391357421875006000f, 0.39538574218750000000f, - 0.46420288085937506000f, 0.54049682617187500000f, - 0.60595703125000000000f, 0.67510986328124989000f, - 0.74291992187500000000f, 0.81152343750000000000f, - 0.87655639648437500000f, 0.93020629882812500000f, - 0.04904174804687500000f, 0.07864379882812500000f, - 0.12878417968750000000f, 0.16821289062499997000f, - 0.26037597656250000000f, 0.31701660156250000000f, - 0.35482788085937500000f, 0.41720581054687494000f, - 0.48071289062500000000f, 0.52487182617187500000f, - 0.60546875000000000000f, 0.66708374023437500000f, - 0.71697998046875000000f, 0.78692626953125000000f, - 0.85726928710937500000f, 0.91952514648437500000f, - 0.02474975585937500000f, 0.04489135742187500000f, - 0.09594726562500000000f, 0.15383911132812500000f, - 0.22674560546875000000f, 0.28652954101562500000f, - 0.34100341796875000000f, 0.40451049804687500000f, - 0.46255493164062494000f, 0.51089477539062500000f, - 0.59762573242187500000f, 0.67648315429687500000f, - 0.73593139648437511000f, 0.79779052734375000000f, - 0.86618041992187500000f, 0.92758178710937500000f, - 0.04708862304687499300f, 0.06542968750000000000f, - 0.11074829101562500000f, 0.19369506835937500000f, - 0.22378540039062503000f, 0.28500366210937500000f, - 0.32684326171875000000f, 0.41491699218750006000f, - 0.46078491210937506000f, 0.52917480468750000000f, - 0.61346435546875000000f, 0.66790771484375000000f, - 0.72424316406250000000f, 0.78237915039062500000f, - 0.84893798828125000000f, 0.91299438476562511000f, - 0.01501464843750000000f, 0.03616333007812500000f, - 0.08972167968750000000f, 0.16748046875000003000f, - 0.21652221679687500000f, 0.26705932617187500000f, - 0.35388183593749994000f, 0.41439819335937500000f, - 0.48965454101562500000f, 0.54977416992187500000f, - 0.61578369140625000000f, 0.67526245117187500000f, - 0.74050903320312489000f, 0.80584716796875000000f, - 0.86926269531250000000f, 0.92642211914062500000f, - 0.04721069335937500000f, 0.06964111328125000000f, - 0.11270141601562500000f, 0.19351196289062500000f, - 0.23675537109374997000f, 0.29318237304687500000f, - 0.36157226562500000000f, 0.40393066406250000000f, - 0.50549316406250000000f, 0.55142211914062500000f, - 0.60299682617187500000f, 0.65319824218750011000f, - 0.73577880859375000000f, 0.81195068359375000000f, - 0.87847900390625000000f, 0.93551635742187511000f, - 0.02090454101562500000f, 0.04083251953125000000f, - 0.10403442382812500000f, 0.16058349609375000000f, - 0.21209716796875000000f, 0.28143310546875000000f, - 0.34832763671875000000f, 0.44320678710937500000f, - 0.49856567382812500000f, 0.54605102539062500000f, - 0.59313964843750000000f, 0.64996337890625000000f, - 0.71084594726562500000f, 0.76846313476562500000f, - 0.85366821289062500000f, 0.93139648437500000000f, - 0.02706909179687500300f, 0.04824829101562500000f, - 0.09329223632812500000f, 0.13177490234375000000f, - 0.21948242187500000000f, 0.26296997070312500000f, - 0.30661010742187500000f, 0.39996337890625000000f, - 0.49636840820312500000f, 0.54605102539062500000f, - 0.61746215820312500000f, 0.68206787109375000000f, - 0.74398803710937511000f, 0.80517578125000000000f, - 0.86407470703125000000f, 0.92129516601562489000f, - 0.06973266601562500000f, 0.11428833007812500000f, - 0.17279052734375000000f, 0.23120117187500000000f, - 0.28451538085937500000f, 0.34545898437500000000f, - 0.40402221679687500000f, 0.46359252929687494000f, - 0.52413940429687500000f, 0.58670043945312500000f, - 0.64416503906250000000f, 0.70104980468750000000f, - 0.75747680664062500000f, 0.81344604492187489000f, - 0.87161254882812500000f, 0.92956542968750000000f, - 0.04565429687500000700f, 0.06433105468750000000f, - 0.10522460937500000000f, 0.21051025390625003000f, - 0.25415039062500000000f, 0.29467773437500000000f, - 0.34338378906250000000f, 0.39132690429687500000f, - 0.45712280273437500000f, 0.50299072265625000000f, - 0.55480957031250000000f, 0.61294555664062500000f, - 0.70074462890624989000f, 0.76782226562500000000f, - 0.84548950195312500000f, 0.90420532226562500000f, - 0.01754760742187500000f, 0.03848266601562500000f, - 0.11782836914062500000f, 0.20223999023437500000f, - 0.25311279296875000000f, 0.32986450195312500000f, - 0.38772583007812500000f, 0.45068359375000000000f, - 0.52111816406250000000f, 0.58126831054687500000f, - 0.64019775390624989000f, 0.70358276367187500000f, - 0.76208496093750011000f, 0.81491088867187500000f, - 0.87646484375000000000f, 0.92605590820312500000f, - 0.05133056640625000000f, 0.06753540039062500000f, - 0.11846923828125000000f, 0.19036865234374997000f, - 0.21997070312500000000f, 0.29437255859375000000f, - 0.33193969726562500000f, 0.40988159179687500000f, - 0.45181274414062494000f, 0.49478149414062506000f, - 0.54751586914062500000f, 0.63699340820312489000f, - 0.71868896484375011000f, 0.78628540039062500000f, - 0.84704589843750000000f, 0.89907836914062500000f, - 0.02709960937500000000f, 0.04931640625000000000f, - 0.11975097656250000000f, 0.15853881835937500000f, - 0.21990966796875003000f, 0.26388549804687500000f, - 0.30035400390625000000f, 0.35012817382812500000f, - 0.49032592773437500000f, 0.55606079101562500000f, - 0.62081909179687500000f, 0.69500732421875000000f, - 0.74777221679687500000f, 0.80603027343750000000f, - 0.85614013671875000000f, 0.90731811523437500000f, - 0.02456665039062500000f, 0.04437255859375000000f, - 0.08187866210937500000f, 0.13647460937500000000f, - 0.24218750000000000000f, 0.28564453125000000000f, - 0.34783935546875000000f, 0.43777465820312500000f, - 0.49453735351562500000f, 0.54418945312500000000f, - 0.59365844726562500000f, 0.66058349609375000000f, - 0.72933959960937489000f, 0.79125976562500000000f, - 0.86630249023437511000f, 0.92965698242187500000f, - 0.05004882812500000000f, 0.07272338867187500000f, - 0.10632324218750000000f, 0.15509033203125000000f, - 0.18408203125000000000f, 0.26263427734375000000f, - 0.35522460937499994000f, 0.39569091796875000000f, - 0.48345947265625000000f, 0.53002929687500000000f, - 0.59039306640625000000f, 0.64642333984375000000f, - 0.72137451171875011000f, 0.79006958007812511000f, - 0.86572265625000000000f, 0.92465209960937500000f, - 0.04980468750000000000f, 0.06726074218750000000f, - 0.13763427734375000000f, 0.23132324218750003000f, - 0.26605224609375000000f, 0.32080078125000000000f, - 0.36505126953125000000f, 0.43017578125000000000f, - 0.47729492187500000000f, 0.52471923828125000000f, - 0.58419799804687500000f, 0.67892456054687511000f, - 0.74960327148437489000f, 0.81057739257812500000f, - 0.87292480468750000000f, 0.93106079101562500000f, - 0.06234741210937500000f, 0.07971191406250001400f, - 0.12161254882812500000f, 0.20907592773437500000f, - 0.24530029296875000000f, 0.29034423828125000000f, - 0.33505249023437500000f, 0.39028930664062500000f, - 0.47076416015625000000f, 0.51049804687500000000f, - 0.57675170898437500000f, 0.61880493164062500000f, - 0.69891357421875000000f, 0.79983520507812500000f, - 0.87619018554687500000f, 0.93438720703125011000f, - 0.06787109375000000000f, 0.08538818359375000000f, - 0.13626098632812500000f, 0.16235351562500000000f, - 0.21691894531249997000f, 0.28796386718750000000f, - 0.33526611328125000000f, 0.40350341796875000000f, - 0.44552612304687500000f, 0.55899047851562500000f, - 0.61465454101562500000f, 0.66659545898437500000f, - 0.72024536132812511000f, 0.78430175781250000000f, - 0.86010742187500000000f, 0.93328857421875000000f, - 0.02548217773437500000f, 0.04702758789062500000f, - 0.12460327148437500000f, 0.17605590820312503000f, - 0.22540283203125000000f, 0.28683471679687500000f, - 0.33480834960937500000f, 0.38012695312500000000f, - 0.45840454101562500000f, 0.56890869140625000000f, - 0.63607788085937500000f, 0.70495605468750000000f, - 0.77185058593750000000f, 0.82293701171875000000f, - 0.88354492187500000000f, 0.92840576171875011000f, - 0.05477905273437500000f, 0.07150268554687500000f, - 0.14675903320312500000f, 0.17993164062500003000f, - 0.21905517578125000000f, 0.26077270507812500000f, - 0.31198120117187500000f, 0.40802001953125000000f, - 0.44573974609375000000f, 0.50259399414062500000f, - 0.55764770507812500000f, 0.63281250000000000000f, - 0.72158813476562500000f, 0.80130004882812500000f, - 0.86132812500000000000f, 0.92742919921875000000f, - 0.05291748046875000000f, 0.06878662109375000000f, - 0.12301635742187500000f, 0.15832519531250000000f, - 0.19854736328125000000f, 0.24023437500000000000f, - 0.29452514648437500000f, 0.39749145507812500000f, - 0.44003295898437494000f, 0.52810668945312500000f, - 0.59494018554687500000f, 0.67718505859374989000f, - 0.74472045898437500000f, 0.80267333984375000000f, - 0.86044311523437500000f, 0.92092895507812500000f, - 0.05618286132812500000f, 0.07168579101562500000f, - 0.12109375000000000000f, 0.14538574218750000000f, - 0.19458007812500000000f, 0.29983520507812500000f, - 0.33715820312500000000f, 0.40725708007812500000f, - 0.44805908203125000000f, 0.49597167968750000000f, - 0.55490112304687500000f, 0.65194702148437500000f, - 0.72991943359375000000f, 0.79821777343750000000f, - 0.85543823242187500000f, 0.91354370117187500000f, - 0.04370117187500000000f, 0.06246948242187500000f, - 0.17184448242187500000f, 0.21139526367187500000f, - 0.25018310546875000000f, 0.29525756835937500000f, - 0.34661865234375000000f, 0.41217041015625000000f, - 0.45172119140625000000f, 0.50106811523437500000f, - 0.55966186523437500000f, 0.67196655273437500000f, - 0.73620605468750000000f, 0.79885864257812500000f, - 0.85845947265625000000f, 0.93341064453125000000f, - 0.05279541015625000700f, 0.07080078125000000000f, - 0.11425781250000000000f, 0.14672851562500000000f, - 0.18331909179687500000f, 0.29498291015625000000f, - 0.33560180664062500000f, 0.41571044921875000000f, - 0.46490478515625000000f, 0.53390502929687500000f, - 0.61303710937500000000f, 0.67144775390625000000f, - 0.72030639648437500000f, 0.77514648437500000000f, - 0.83554077148437489000f, 0.89276123046875000000f, - 0.03866577148437500000f, 0.05844116210937500000f, - 0.16732788085937503000f, 0.20788574218750000000f, - 0.25112915039062500000f, 0.30270385742187500000f, - 0.35366821289062494000f, 0.40701293945312500000f, - 0.45004272460937506000f, 0.54824829101562500000f, - 0.62719726562500000000f, 0.67648315429687500000f, - 0.74826049804687500000f, 0.81845092773437500000f, - 0.88143920898437500000f, 0.93511962890625000000f, - 0.04656982421875000000f, 0.06802368164062500000f, - 0.12939453125000000000f, 0.22546386718750000000f, - 0.27322387695312500000f, 0.31890869140625000000f, - 0.36312866210937500000f, 0.41864013671875006000f, - 0.51455688476562500000f, 0.55917358398437500000f, - 0.62191772460937500000f, 0.69189453125000000000f, - 0.75674438476562500000f, 0.82110595703125000000f, - 0.88214111328124989000f, 0.93450927734375000000f, - 0.06637573242187500000f, 0.08517456054687500000f, - 0.12524414062500000000f, 0.20980834960937500000f, - 0.26281738281250000000f, 0.29901123046875000000f, - 0.37084960937500000000f, 0.41308593750000000000f, - 0.47677612304687500000f, 0.53961181640625000000f, - 0.58633422851562500000f, 0.64270019531250000000f, - 0.74407958984375000000f, 0.81665039062499989000f, - 0.87380981445312500000f, 0.92309570312500000000f, - 0.01385498046875000000f, 0.03756713867187500000f, - 0.13241577148437500000f, 0.17510986328125000000f, - 0.23040771484375000000f, 0.27484130859375000000f, - 0.31494140625000000000f, 0.41275024414062506000f, - 0.48843383789062500000f, 0.54470825195312500000f, - 0.61251831054687500000f, 0.67114257812500000000f, - 0.73086547851562500000f, 0.79476928710937500000f, - 0.86196899414062511000f, 0.92086791992187489000f, - 0.06866455078125000000f, 0.08517456054687500000f, - 0.12908935546875000000f, 0.16122436523437500000f, - 0.20635986328125000000f, 0.32369995117187506000f, - 0.36251831054687500000f, 0.42178344726562500000f, - 0.48208618164062494000f, 0.52685546875000000000f, - 0.61123657226562500000f, 0.67950439453125000000f, - 0.75036621093750000000f, 0.80679321289062500000f, - 0.86193847656250000000f, 0.92831420898437489000f, - 0.05175781250000000000f, 0.06762695312500000000f, - 0.13146972656250000000f, 0.25588989257812500000f, - 0.29803466796875000000f, 0.33660888671875000000f, - 0.38317871093750000000f, 0.43026733398437500000f, - 0.49810791015625000000f, 0.53833007812500000000f, - 0.58489990234375000000f, 0.62835693359375000000f, - 0.73141479492187489000f, 0.81964111328125000000f, - 0.87884521484375000000f, 0.93267822265625000000f, - 0.07482910156250000000f, 0.09875488281250000000f, - 0.13333129882812500000f, 0.18670654296875000000f, - 0.21838378906250000000f, 0.27474975585937500000f, - 0.35122680664062500000f, 0.39050292968750000000f, - 0.48062133789062506000f, 0.52767944335937500000f, - 0.59481811523437500000f, 0.67874145507812500000f, - 0.74859619140625000000f, 0.80792236328125000000f, - 0.86282348632812489000f, 0.91775512695312511000f, - 0.05526733398437500000f, 0.07754516601562500000f, - 0.10848999023437500000f, 0.16723632812500000000f, - 0.27841186523437500000f, 0.32125854492187500000f, - 0.36297607421875000000f, 0.41683959960937500000f, - 0.46575927734374994000f, 0.51571655273437500000f, - 0.59100341796875000000f, 0.64297485351562511000f, - 0.69256591796875000000f, 0.74200439453125000000f, - 0.83178710937500000000f, 0.91500854492187500000f, - 0.04739379882812500000f, 0.06854248046875000000f, - 0.13912963867187500000f, 0.16784667968749997000f, - 0.20611572265625003000f, 0.24029541015625000000f, - 0.35824584960937500000f, 0.41415405273437500000f, - 0.46350097656250000000f, 0.54562377929687500000f, - 0.61892700195312500000f, 0.68695068359375000000f, - 0.75115966796875000000f, 0.81326293945312500000f, - 0.87847900390625000000f, 0.93856811523437500000f, - 0.06048583984375000000f, 0.08447265625000000000f, - 0.11700439453125001000f, 0.18200683593750000000f, - 0.26647949218750000000f, 0.30236816406250000000f, - 0.36001586914062500000f, 0.45205688476562500000f, - 0.49777221679687506000f, 0.54766845703125000000f, - 0.64382934570312500000f, 0.69735717773437500000f, - 0.74633789062500000000f, 0.80273437500000000000f, - 0.85955810546875000000f, 0.90805053710937511000f, - 0.05566406250000000000f, 0.07717895507812500000f, - 0.11648559570312500000f, 0.16629028320312500000f, - 0.20916748046875003000f, 0.26593017578125000000f, - 0.31680297851562500000f, 0.37493896484375006000f, - 0.43316650390625000000f, 0.48138427734375000000f, - 0.59582519531250000000f, 0.65228271484375000000f, - 0.72311401367187500000f, 0.79556274414062500000f, - 0.85742187500000000000f, 0.92199707031250011000f, - 0.06750488281250000000f, 0.08709716796875001400f, - 0.12045288085937500000f, 0.17999267578125000000f, - 0.30303955078125000000f, 0.35266113281250000000f, - 0.39227294921875000000f, 0.45129394531249994000f, - 0.49829101562500006000f, 0.54016113281250000000f, - 0.62014770507812500000f, 0.67437744140625000000f, - 0.72241210937500011000f, 0.77182006835937500000f, - 0.82324218750000011000f, 0.87237548828125000000f, - 0.06173706054687500000f, 0.07931518554687500000f, - 0.12280273437500000000f, 0.15002441406250000000f, - 0.20181274414062500000f, 0.34024047851562494000f, - 0.38015747070312500000f, 0.44635009765625000000f, - 0.49804687500000000000f, 0.54388427734375000000f, - 0.60037231445312500000f, 0.64611816406250000000f, - 0.70541381835937500000f, 0.79501342773437500000f, - 0.87966918945312500000f, 0.93865966796875000000f, - 0.04968261718750000700f, 0.06732177734375000000f, - 0.10580444335937500000f, 0.13317871093750000000f, - 0.26486206054687500000f, 0.31045532226562500000f, - 0.36206054687500000000f, 0.41744995117187500000f, - 0.45770263671874994000f, 0.51690673828125000000f, - 0.58615112304687500000f, 0.65197753906249989000f, - 0.72784423828125000000f, 0.79696655273437500000f, - 0.85827636718750000000f, 0.92385864257812500000f, - 0.06146240234375000000f, 0.07943725585937500000f, - 0.12554931640625000000f, 0.22137451171875000000f, - 0.25988769531250000000f, 0.30648803710937500000f, - 0.36077880859375000000f, 0.41207885742187500000f, - 0.49832153320312500000f, 0.54400634765625000000f, - 0.60110473632812500000f, 0.64941406250000000000f, - 0.70651245117187500000f, 0.75259399414062500000f, - 0.81808471679687500000f, 0.92044067382812511000f, - 0.07250976562500000000f, 0.09094238281250000000f, - 0.13494873046875000000f, 0.17608642578125000000f, - 0.21411132812500000000f, 0.29672241210937500000f, - 0.33950805664062506000f, 0.41247558593750000000f, - 0.47256469726562506000f, 0.51834106445312500000f, - 0.58471679687500000000f, 0.62826538085937500000f, - 0.74465942382812500000f, 0.82946777343750000000f, - 0.88641357421875000000f, 0.93527221679687500000f, - 0.07489013671875000000f, 0.10687255859375000000f, - 0.14111328125000000000f, 0.18368530273437500000f, - 0.23291015625000000000f, 0.27005004882812500000f, - 0.32934570312500000000f, 0.42614746093750000000f, - 0.47372436523437500000f, 0.52139282226562500000f, - 0.59848022460937500000f, 0.64813232421875000000f, - 0.69750976562500000000f, 0.76623535156249989000f, - 0.85772705078125011000f, 0.91217041015625000000f, - 0.04800415039062500700f, 0.06939697265625000000f, - 0.10095214843750000000f, 0.18307495117187500000f, - 0.27395629882812500000f, 0.30834960937500000000f, - 0.38015747070312500000f, 0.43511962890625000000f, - 0.48062133789062506000f, 0.55480957031250000000f, - 0.60955810546875000000f, 0.64859008789062500000f, - 0.70327758789062500000f, 0.76470947265625000000f, - 0.84658813476562500000f, 0.92514038085937500000f, - 0.05929565429687500000f, 0.08331298828125000000f, - 0.12634277343750000000f, 0.18798828125000003000f, - 0.22860717773437500000f, 0.27423095703125000000f, - 0.34512329101562500000f, 0.38986206054687500000f, - 0.45227050781250000000f, 0.50531005859375000000f, - 0.54653930664062500000f, 0.60293579101562500000f, - 0.65649414062500011000f, 0.72036743164062500000f, - 0.83233642578124989000f, 0.90109252929687500000f, - 0.06167602539062500000f, 0.07879638671875000000f, - 0.13714599609375000000f, 0.17807006835937503000f, - 0.21340942382812497000f, 0.25161743164062500000f, - 0.29989624023437500000f, 0.44961547851562500000f, - 0.50238037109375000000f, 0.54608154296875000000f, - 0.59957885742187500000f, 0.64340209960937489000f, - 0.72521972656250000000f, 0.81381225585937500000f, - 0.88720703125000000000f, 0.94573974609375000000f, - 0.03210449218750000000f, 0.05416870117187500000f, - 0.09820556640624998600f, 0.13360595703125000000f, - 0.23394775390625000000f, 0.28695678710937500000f, - 0.34326171875000000000f, 0.40670776367187500000f, - 0.45690917968750000000f, 0.54815673828125000000f, - 0.63348388671875000000f, 0.68218994140625000000f, - 0.76510620117187500000f, 0.83035278320312511000f, - 0.88504028320312500000f, 0.93411254882812489000f, - 0.06768798828125000000f, 0.08746337890624998600f, - 0.12887573242187500000f, 0.16333007812500000000f, - 0.20083618164062500000f, 0.30456542968750000000f, - 0.35360717773437500000f, 0.40042114257812500000f, - 0.46365356445312500000f, 0.50607299804687500000f, - 0.56109619140625000000f, 0.61279296875000000000f, - 0.67178344726562500000f, 0.77261352539062500000f, - 0.85836791992187500000f, 0.91186523437500011000f, - 0.06549072265625000000f, 0.08666992187500000000f, - 0.13418579101562500000f, 0.17822265625000000000f, - 0.22732543945312500000f, 0.26614379882812500000f, - 0.32080078125000000000f, 0.36425781250000000000f, - 0.41488647460937500000f, 0.52651977539062500000f, - 0.58929443359375000000f, 0.63754272460937500000f, - 0.71463012695312500000f, 0.78207397460937500000f, - 0.84683227539062500000f, 0.92257690429687500000f, - 0.06018066406250000000f, 0.07992553710937500000f, - 0.11462402343750000000f, 0.19430541992187500000f, - 0.23318481445312503000f, 0.26898193359375000000f, - 0.37493896484375006000f, 0.42016601562500000000f, - 0.46719360351562506000f, 0.55041503906250000000f, - 0.59683227539062500000f, 0.63793945312500000000f, - 0.68914794921875011000f, 0.75915527343750000000f, - 0.84838867187500000000f, 0.92895507812500000000f, - 0.06118774414062500000f, 0.07864379882812500000f, - 0.13037109375000000000f, 0.22500610351562500000f, - 0.26116943359375000000f, 0.31198120117187500000f, - 0.35919189453125000000f, 0.40899658203125000000f, - 0.50360107421875000000f, 0.54931640625000000000f, - 0.59951782226562500000f, 0.64404296875000000000f, - 0.70159912109375000000f, 0.81805419921875000000f, - 0.90042114257812489000f, 0.94427490234375000000f, - 0.03518676757812500000f, 0.05560302734375000000f, - 0.11364746093750001000f, 0.16610717773437500000f, - 0.21331787109375000000f, 0.26556396484375000000f, - 0.31399536132812500000f, 0.36312866210937500000f, - 0.42285156250000000000f, 0.46737670898437500000f, - 0.53713989257812500000f, 0.64282226562500000000f, - 0.72302246093750011000f, 0.79598999023437500000f, - 0.87237548828125000000f, 0.93502807617187500000f, - 0.03979492187500000000f, 0.05703735351562500000f, - 0.10125732421875000000f, 0.21957397460937500000f, - 0.29336547851562500000f, 0.32754516601562500000f, - 0.37820434570312500000f, 0.41894531250000000000f, - 0.48284912109375000000f, 0.53326416015625000000f, - 0.57623291015625000000f, 0.63146972656250000000f, - 0.70538330078125000000f, 0.77941894531250000000f, - 0.84484863281250000000f, 0.89245605468750011000f, - 0.06387329101562500000f, 0.08212280273437500000f, - 0.12261962890625000000f, 0.20318603515625000000f, - 0.24252319335937500000f, 0.27914428710937500000f, - 0.32034301757812500000f, 0.36257934570312500000f, - 0.48486328125000006000f, 0.54385375976562500000f, - 0.58999633789062500000f, 0.64797973632812500000f, - 0.71322631835937489000f, 0.77008056640625000000f, - 0.84085083007812500000f, 0.91546630859375000000f, - 0.01754760742187500000f, 0.04061889648437499300f, - 0.16186523437500000000f, 0.21087646484374997000f, - 0.25711059570312500000f, 0.30780029296875000000f, - 0.35330200195312500000f, 0.41192626953125006000f, - 0.50183105468750000000f, 0.56539916992187500000f, - 0.62759399414062500000f, 0.69723510742187500000f, - 0.76031494140625000000f, 0.81457519531249989000f, - 0.87765502929687500000f, 0.92031860351562500000f, - 0.04379272460937500000f, 0.06176757812500000000f, - 0.10018920898437500000f, 0.12683105468750000000f, - 0.23226928710937500000f, 0.32324218750000000000f, - 0.36770629882812506000f, 0.42501831054687500000f, - 0.47177124023437500000f, 0.56192016601562500000f, - 0.62545776367187500000f, 0.67962646484375000000f, - 0.73919677734375000000f, 0.79629516601562489000f, - 0.85647583007812500000f, 0.91854858398437500000f, - 0.04980468750000000000f, 0.06616210937500000000f, - 0.16906738281250000000f, 0.22821044921875000000f, - 0.26336669921875000000f, 0.31710815429687500000f, - 0.35534667968750000000f, 0.43704223632812494000f, - 0.48037719726562500000f, 0.52969360351562500000f, - 0.57238769531250000000f, 0.62359619140625000000f, - 0.69577026367187500000f, 0.79528808593750000000f, - 0.87103271484375000000f, 0.93676757812500000000f, - 0.04293823242187500000f, 0.06851196289062500000f, - 0.10391235351562501000f, 0.17208862304687500000f, - 0.28744506835937500000f, 0.32608032226562506000f, - 0.36938476562500000000f, 0.41183471679687494000f, - 0.47409057617187500000f, 0.56021118164062500000f, - 0.61022949218750000000f, 0.66189575195312500000f, - 0.74313354492187500000f, 0.81024169921874989000f, - 0.88052368164062500000f, 0.93273925781250011000f, - 0.05111694335937500700f, 0.06793212890625000000f, - 0.12222290039062501000f, 0.25094604492187500000f, - 0.30441284179687500000f, 0.34042358398437500000f, - 0.39129638671875000000f, 0.43688964843750000000f, - 0.50366210937500000000f, 0.55349731445312500000f, - 0.59735107421875000000f, 0.64239501953125000000f, - 0.69454956054687500000f, 0.76025390625000000000f, - 0.86352539062500011000f, 0.93487548828125000000f, - 0.03295898437500000000f, 0.04925537109375000000f, - 0.11053466796875000000f, 0.23086547851562497000f, - 0.26696777343750000000f, 0.31442260742187500000f, - 0.35745239257812500000f, 0.42260742187500000000f, - 0.47708129882812500000f, 0.53204345703125000000f, - 0.60305786132812500000f, 0.66604614257812500000f, - 0.71932983398437500000f, 0.77493286132812500000f, - 0.83636474609375000000f, 0.88693237304687500000f, - 0.05166625976562500000f, 0.06802368164062500000f, - 0.10546875000000000000f, 0.13287353515625000000f, - 0.17303466796875000000f, 0.33233642578125000000f, - 0.38339233398437500000f, 0.43234252929687500000f, - 0.48458862304687500000f, 0.53030395507812500000f, - 0.60476684570312500000f, 0.67050170898437500000f, - 0.73529052734375000000f, 0.79745483398437500000f, - 0.86358642578125000000f, 0.91854858398437500000f, - 0.06231689453125000000f, 0.09030151367187501400f, - 0.12802124023437500000f, 0.17517089843750000000f, - 0.21685791015625000000f, 0.25228881835937500000f, - 0.33953857421875000000f, 0.45693969726562500000f, - 0.51617431640625000000f, 0.55831909179687500000f, - 0.62658691406250000000f, 0.67083740234375000000f, - 0.72360229492187500000f, 0.78640747070312500000f, - 0.84255981445312511000f, 0.89572143554687500000f, - 0.03002929687500000000f, 0.04919433593750000000f, - 0.11621093750000000000f, 0.16067504882812500000f, - 0.21011352539062500000f, 0.25668334960937500000f, - 0.29135131835937500000f, 0.33230590820312500000f, - 0.38214111328125000000f, 0.50415039062500000000f, - 0.59658813476562500000f, 0.66036987304687500000f, - 0.72467041015625011000f, 0.79522705078125000000f, - 0.86395263671874989000f, 0.92694091796875011000f, - 0.06213378906250000000f, 0.07745361328125000000f, - 0.12713623046875000000f, 0.23684692382812500000f, - 0.27911376953125000000f, 0.31774902343750000000f, - 0.37060546875000006000f, 0.41531372070312500000f, - 0.47570800781250000000f, 0.52395629882812500000f, - 0.56637573242187500000f, 0.61380004882812500000f, - 0.66589355468750000000f, 0.74197387695312500000f, - 0.85537719726562489000f, 0.93420410156249989000f, - 0.05709838867187500000f, 0.07186889648437500000f, - 0.12393188476562500000f, 0.15695190429687500000f, - 0.22778320312500000000f, 0.30911254882812500000f, - 0.36441040039062506000f, 0.45779418945312506000f, - 0.50903320312500000000f, 0.56011962890625000000f, - 0.60903930664062500000f, 0.67990112304687500000f, - 0.75869750976562489000f, 0.82006835937500000000f, - 0.88464355468750000000f, 0.93429565429687511000f, - 0.07830810546875000000f, 0.09646606445312500000f, - 0.14169311523437500000f, 0.19003295898437500000f, - 0.22601318359375000000f, 0.30426025390625000000f, - 0.35455322265625000000f, 0.40942382812500000000f, - 0.48489379882812500000f, 0.52990722656250000000f, - 0.58352661132812500000f, 0.63528442382812500000f, - 0.68945312500000000000f, 0.75439453125000000000f, - 0.87686157226562489000f, 0.94854736328125000000f, - 0.05187988281249999300f, 0.07101440429687500000f, - 0.14733886718750000000f, 0.18124389648437500000f, - 0.23092651367187500000f, 0.27935791015625000000f, - 0.33834838867187500000f, 0.38973999023437500000f, - 0.43362426757812506000f, 0.49197387695312500000f, - 0.61712646484375000000f, 0.69186401367187500000f, - 0.75219726562500000000f, 0.81347656250000000000f, - 0.87573242187499989000f, 0.93826293945312500000f, - 0.09671020507812500000f, 0.11819458007812501000f, - 0.15399169921875000000f, 0.20959472656250000000f, - 0.24975585937500000000f, 0.28930664062500000000f, - 0.37643432617187500000f, 0.42932128906250000000f, - 0.48138427734375000000f, 0.54843139648437500000f, - 0.61740112304687500000f, 0.66256713867187500000f, - 0.71777343750000000000f, 0.77041625976562500000f, - 0.82476806640625000000f, 0.87677001953124989000f, - 0.04772949218750000000f, 0.07296752929687500000f, - 0.12905883789062500000f, 0.20538330078125000000f, - 0.27175903320312500000f, 0.31918334960937500000f, - 0.39752197265625000000f, 0.45877075195312500000f, - 0.52688598632812500000f, 0.60452270507812500000f, - 0.66677856445312500000f, 0.72451782226562500000f, - 0.77789306640625000000f, 0.83349609375000000000f, - 0.88687133789062500000f, 0.93161010742187511000f, - 0.08740234375000000000f, 0.10861206054687501000f, - 0.14401245117187500000f, 0.19656372070312503000f, - 0.29272460937500000000f, 0.33737182617187500000f, - 0.38949584960937500000f, 0.45117187500000000000f, - 0.50134277343750000000f, 0.55432128906250000000f, - 0.62518310546875000000f, 0.67938232421875000000f, - 0.73800659179687511000f, 0.80148315429687500000f, - 0.86618041992187500000f, 0.92236328125000000000f, - 0.08157348632812498600f, 0.10525512695312501000f, - 0.13980102539062500000f, 0.18258666992187500000f, - 0.20944213867187500000f, 0.25363159179687500000f, - 0.38037109375000000000f, 0.42453002929687506000f, - 0.48028564453125000000f, 0.54293823242187500000f, - 0.59252929687500000000f, 0.64642333984375000000f, - 0.73318481445312500000f, 0.81057739257812500000f, - 0.87655639648437500000f, 0.92895507812500000000f, - 0.07382202148437500000f, 0.09304809570312500000f, - 0.13043212890625000000f, 0.19482421875000000000f, - 0.26135253906250000000f, 0.29483032226562500000f, - 0.34448242187499994000f, 0.38684082031250000000f, - 0.44088745117187500000f, 0.53643798828125000000f, - 0.60473632812500000000f, 0.64791870117187511000f, - 0.70492553710937500000f, 0.77117919921874989000f, - 0.82089233398437500000f, 0.88275146484374989000f, - 0.03900146484375000000f, 0.06106567382812500000f, - 0.09155273437500000000f, 0.16336059570312500000f, - 0.30502319335937500000f, 0.35940551757812500000f, - 0.39727783203125000000f, 0.44464111328125000000f, - 0.48980712890625000000f, 0.54205322265625000000f, - 0.60980224609375000000f, 0.65969848632812511000f, - 0.71322631835937489000f, 0.76547241210937500000f, - 0.84399414062500000000f, 0.92077636718749989000f, - 0.02844238281250000000f, 0.04956054687500000000f, - 0.08538818359375000000f, 0.13946533203125000000f, - 0.26220703125000000000f, 0.30480957031250000000f, - 0.35253906249999994000f, 0.39825439453125000000f, - 0.51638793945312500000f, 0.56997680664062500000f, - 0.62301635742187500000f, 0.69610595703125000000f, - 0.75735473632812500000f, 0.81845092773437500000f, - 0.87902832031250011000f, 0.92727661132812489000f, - 0.07092285156250000000f, 0.09072875976562500000f, - 0.12683105468750000000f, 0.17401123046875000000f, - 0.21115112304687500000f, 0.26873779296875000000f, - 0.31307983398437500000f, 0.38156127929687494000f, - 0.45822143554687494000f, 0.50558471679687500000f, - 0.59259033203125000000f, 0.65231323242187500000f, - 0.70016479492187500000f, 0.74920654296875000000f, - 0.82470703124999989000f, 0.91091918945312500000f, - 0.04772949218750000000f, 0.07241821289062500000f, - 0.10543823242187499000f, 0.14974975585937500000f, - 0.18234252929687500000f, 0.22692871093750000000f, - 0.35968017578125000000f, 0.44265747070312500000f, - 0.49154663085937500000f, 0.55383300781250000000f, - 0.61093139648437500000f, 0.66079711914062500000f, - 0.72448730468749989000f, 0.78778076171875000000f, - 0.87213134765625000000f, 0.92687988281250000000f, - 0.09231567382812501400f, 0.11380004882812500000f, - 0.14849853515625000000f, 0.19897460937500000000f, - 0.28952026367187500000f, 0.33395385742187500000f, - 0.37713623046875000000f, 0.43511962890625000000f, - 0.49359130859375000000f, 0.53408813476562500000f, - 0.59436035156250000000f, 0.65332031250000000000f, - 0.70883178710937500000f, 0.76007080078125000000f, - 0.83456420898437500000f, 0.89743041992187500000f, - 0.03875732421875000000f, 0.05996704101562500000f, - 0.20758056640625000000f, 0.24398803710937500000f, - 0.28088378906250000000f, 0.33044433593750000000f, - 0.38168334960937500000f, 0.43426513671875000000f, - 0.48092651367187500000f, 0.54504394531250000000f, - 0.62161254882812500000f, 0.68670654296875000000f, - 0.75173950195312500000f, 0.80914306640625000000f, - 0.87081909179687500000f, 0.93154907226562500000f, - 0.06744384765625000000f, 0.08389282226562500000f, - 0.13018798828125000000f, 0.22848510742187503000f, - 0.30145263671875000000f, 0.33624267578125000000f, - 0.39132690429687500000f, 0.44039916992187500000f, - 0.49581909179687494000f, 0.56842041015625000000f, - 0.62408447265625000000f, 0.67303466796875011000f, - 0.72445678710937500000f, 0.77182006835937500000f, - 0.82623291015625000000f, 0.89016723632812500000f, - 0.03890991210937500000f, 0.05877685546875000000f, - 0.13214111328125000000f, 0.20059204101562503000f, - 0.25759887695312500000f, 0.33325195312500000000f, - 0.40466308593750000000f, 0.45800781249999994000f, - 0.51657104492187500000f, 0.56680297851562500000f, - 0.63000488281250000000f, 0.67800903320312500000f, - 0.73190307617187500000f, 0.77740478515625000000f, - 0.83532714843750000000f, 0.87417602539062489000f, - 0.09201049804687500000f, 0.11199951171875000000f, - 0.15521240234375000000f, 0.19445800781250000000f, - 0.24072265625000000000f, 0.28408813476562500000f, - 0.33465576171875006000f, 0.38580322265624994000f, - 0.44235229492187500000f, 0.49353027343750000000f, - 0.55175781250000000000f, 0.60949707031250000000f, - 0.68524169921874989000f, 0.75985717773437500000f, - 0.83502197265624989000f, 0.91476440429687500000f, - 0.08795166015625001400f, 0.11392211914062500000f, - 0.15603637695312500000f, 0.19781494140625000000f, - 0.24795532226562503000f, 0.29556274414062500000f, - 0.35394287109375000000f, 0.40551757812500006000f, - 0.47012329101562500000f, 0.52465820312500000000f, - 0.61578369140625000000f, 0.68438720703125011000f, - 0.75686645507812500000f, 0.82440185546875000000f, - 0.89147949218750000000f, 0.94027709960937511000f, - 0.07019042968750000000f, 0.09057617187500000000f, - 0.12515258789062500000f, 0.16607666015625000000f, - 0.19308471679687500000f, 0.24139404296875000000f, - 0.38009643554687500000f, 0.42303466796875000000f, - 0.48056030273437500000f, 0.53421020507812500000f, - 0.58145141601562500000f, 0.63107299804687500000f, - 0.69015502929687500000f, 0.75250244140625000000f, - 0.83920288085937500000f, 0.91751098632812500000f, - 0.06887817382812500000f, 0.08972167968750000000f, - 0.13519287109375000000f, 0.18283081054687497000f, - 0.21490478515624997000f, 0.25524902343750000000f, - 0.28729248046875000000f, 0.34252929687500000000f, - 0.47982788085937500000f, 0.53161621093750000000f, - 0.58755493164062500000f, 0.65518188476562489000f, - 0.72982788085937500000f, 0.79507446289062500000f, - 0.86761474609375000000f, 0.92724609375000000000f, - 0.03744506835937500000f, 0.06240844726562500000f, - 0.11651611328124999000f, 0.15292358398437500000f, - 0.21331787109375000000f, 0.28170776367187500000f, - 0.33642578124999994000f, 0.39706420898437494000f, - 0.52920532226562500000f, 0.58035278320312500000f, - 0.62814331054687500000f, 0.69577026367187500000f, - 0.76889038085937500000f, 0.82019042968750000000f, - 0.89572143554687500000f, 0.94009399414062489000f, - 0.04132080078125000000f, 0.05871582031250000000f, - 0.11563110351562500000f, 0.24649047851562500000f, - 0.31900024414062500000f, 0.35519409179687500000f, - 0.40747070312500000000f, 0.45217895507812500000f, - 0.51095581054687500000f, 0.55508422851562500000f, - 0.61325073242187500000f, 0.67181396484374989000f, - 0.75051879882812500000f, 0.81411743164062500000f, - 0.87423706054687500000f, 0.92333984375000000000f, - 0.09588623046875000000f, 0.12356567382812501000f, - 0.18911743164062500000f, 0.22634887695312500000f, - 0.26712036132812500000f, 0.30993652343750000000f, - 0.35195922851562500000f, 0.40225219726562500000f, - 0.48666381835937500000f, 0.53878784179687500000f, - 0.59832763671875000000f, 0.65313720703125000000f, - 0.71676635742187500000f, 0.78305053710937511000f, - 0.85824584960937511000f, 0.92480468750000000000f, - 0.04019165039062500700f, 0.06906127929687500000f, - 0.14419555664062500000f, 0.23226928710937500000f, - 0.29501342773437500000f, 0.35504150390625000000f, - 0.43161010742187500000f, 0.49615478515625000000f, - 0.57141113281250000000f, 0.63165283203125000000f, - 0.68295288085937500000f, 0.73263549804687511000f, - 0.78659057617187489000f, 0.83163452148437500000f, - 0.88287353515625000000f, 0.93362426757812500000f, - 0.04791259765625000000f, 0.07089233398437500000f, - 0.11651611328124999000f, 0.18966674804687500000f, - 0.30191040039062500000f, 0.35266113281250000000f, - 0.39886474609375000000f, 0.44650268554687500000f, - 0.49291992187500006000f, 0.55816650390625000000f, - 0.65264892578125000000f, 0.71246337890625000000f, - 0.76641845703125011000f, 0.82162475585937500000f, - 0.87622070312500000000f, 0.92065429687500000000f, - 0.07009887695312500000f, 0.11917114257812500000f, - 0.19186401367187503000f, 0.26116943359375000000f, - 0.32556152343750006000f, 0.38958740234375000000f, - 0.45834350585937500000f, 0.52191162109375000000f, - 0.58093261718750000000f, 0.63101196289062500000f, - 0.68179321289062500000f, 0.72848510742187500000f, - 0.77752685546875000000f, 0.82656860351562500000f, - 0.88046264648437500000f, 0.93139648437500000000f, - 0.05844116210937500000f, 0.07650756835937500000f, - 0.12307739257812499000f, 0.17544555664062500000f, - 0.21542358398437497000f, 0.27072143554687500000f, - 0.32528686523437500000f, 0.37225341796875006000f, - 0.42532348632812500000f, 0.46945190429687500000f, - 0.51480102539062500000f, 0.57089233398437500000f, - 0.70724487304687489000f, 0.78790283203125011000f, - 0.87017822265625000000f, 0.93081665039062500000f, - 0.07336425781250000000f, 0.08905029296875000000f, - 0.15838623046875000000f, 0.19079589843750000000f, - 0.22662353515625003000f, 0.30172729492187500000f, - 0.37802124023437500000f, 0.45150756835937494000f, - 0.51129150390625000000f, 0.56054687500000000000f, - 0.62066650390625000000f, 0.67147827148437511000f, - 0.73962402343750000000f, 0.80737304687500000000f, - 0.86944580078125000000f, 0.92764282226562500000f, - 0.04946899414062500000f, 0.06796264648437500000f, - 0.10617065429687500000f, 0.15518188476562500000f, - 0.28762817382812500000f, 0.39343261718750006000f, - 0.43475341796875006000f, 0.47766113281250000000f, - 0.52505493164062500000f, 0.56988525390625000000f, - 0.62396240234375000000f, 0.67776489257812500000f, - 0.72564697265625000000f, 0.78939819335937500000f, - 0.85238647460937500000f, 0.91836547851562500000f, - 0.05703735351562500000f, 0.07293701171875000000f, - 0.12527465820312500000f, 0.21426391601562500000f, - 0.34243774414062500000f, 0.38986206054687500000f, - 0.42904663085937500000f, 0.47576904296875006000f, - 0.51953125000000000000f, 0.56787109375000000000f, - 0.62850952148437500000f, 0.67367553710937500000f, - 0.72171020507812489000f, 0.76763916015625000000f, - 0.82135009765625000000f, 0.87496948242187500000f, - 0.07785034179687500000f, 0.09924316406250000000f, - 0.14306640625000000000f, 0.20025634765625000000f, - 0.24014282226562500000f, 0.27847290039062500000f, - 0.31967163085937506000f, 0.36010742187500000000f, - 0.47003173828125000000f, 0.57312011718750000000f, - 0.64062500000000000000f, 0.68832397460937500000f, - 0.74124145507812500000f, 0.79248046874999989000f, - 0.83816528320312500000f, 0.89208984375000000000f, - 0.08255004882812500000f, 0.10659790039062501000f, - 0.14450073242187500000f, 0.19409179687500000000f, - 0.24124145507812503000f, 0.28540039062500000000f, - 0.35211181640625006000f, 0.40985107421875000000f, - 0.46505737304687500000f, 0.51632690429687500000f, - 0.56820678710937500000f, 0.61322021484375000000f, - 0.66528320312500000000f, 0.71234130859375000000f, - 0.76904296875000000000f, 0.89285278320312500000f, - 0.06610107421875000000f, 0.08517456054687500000f, - 0.12240600585937499000f, 0.15505981445312500000f, - 0.17993164062500003000f, 0.27581787109375000000f, - 0.40914916992187494000f, 0.44869995117187506000f, - 0.50485229492187500000f, 0.55508422851562500000f, - 0.60717773437500000000f, 0.66702270507812500000f, - 0.75903320312500000000f, 0.82308959960937500000f, - 0.88363647460937500000f, 0.93121337890625000000f, - 0.05691528320312499300f, 0.09219360351562500000f, - 0.14331054687500000000f, 0.19940185546875003000f, - 0.25460815429687500000f, 0.30255126953125000000f, - 0.39028930664062500000f, 0.43038940429687500000f, - 0.50454711914062500000f, 0.54104614257812500000f, - 0.65124511718750000000f, 0.68478393554687500000f, - 0.75906372070312500000f, 0.80352783203125000000f, - 0.86755371093750000000f, 0.92022705078125000000f, - 0.10281372070312500000f, 0.13259887695312500000f, - 0.20059204101562503000f, 0.26742553710937500000f, - 0.31460571289062500000f, 0.35745239257812500000f, - 0.40792846679687500000f, 0.45117187500000000000f, - 0.50302124023437500000f, 0.55374145507812500000f, - 0.60543823242187500000f, 0.64840698242187500000f, - 0.71081542968750000000f, 0.77749633789062489000f, - 0.84091186523437489000f, 0.89865112304687500000f, - 0.03860473632812500000f, 0.06665039062500000000f, - 0.16610717773437500000f, 0.24087524414062500000f, - 0.32321166992187500000f, 0.40097045898437506000f, - 0.46096801757812500000f, 0.50778198242187500000f, - 0.56158447265625000000f, 0.60504150390625000000f, - 0.65365600585937500000f, 0.70175170898437500000f, - 0.75436401367187500000f, 0.80679321289062500000f, - 0.86557006835937500000f, 0.91934204101562500000f, - 0.04833984375000000700f, 0.06115722656250000000f, - 0.10787963867187500000f, 0.13580322265625000000f, - 0.26434326171875000000f, 0.32849121093750000000f, - 0.39160156250000000000f, 0.45709228515625000000f, - 0.51794433593750000000f, 0.57354736328125000000f, - 0.63879394531250000000f, 0.68807983398437500000f, - 0.75183105468750000000f, 0.80935668945312500000f, - 0.87588500976562500000f, 0.93283081054687511000f, - 0.10433959960937500000f, 0.13818359375000000000f, - 0.20147705078124997000f, 0.24078369140624997000f, - 0.29016113281250000000f, 0.33187866210937494000f, - 0.38973999023437500000f, 0.43814086914062500000f, - 0.48983764648437500000f, 0.55938720703125000000f, - 0.62957763671875000000f, 0.68634033203125000000f, - 0.76507568359375000000f, 0.82202148437499989000f, - 0.88336181640625011000f, 0.93206787109375000000f, - 0.05267333984375000000f, 0.06872558593750000000f, - 0.14028930664062500000f, 0.21209716796875000000f, - 0.25570678710937500000f, 0.29977416992187500000f, - 0.34677124023437500000f, 0.39044189453125006000f, - 0.43658447265625000000f, 0.47229003906250000000f, - 0.51263427734375000000f, 0.54986572265625000000f, - 0.66134643554687511000f, 0.77972412109375000000f, - 0.85900878906249989000f, 0.92672729492187500000f, - 0.10330200195312500000f, 0.11810302734375000000f, - 0.16195678710937503000f, 0.19494628906250000000f, - 0.21792602539062500000f, 0.26501464843750000000f, - 0.38742065429687500000f, 0.45590209960937500000f, - 0.50292968750000000000f, 0.55776977539062500000f, - 0.62673950195312500000f, 0.67285156249999989000f, - 0.73080444335937489000f, 0.79238891601562500000f, - 0.86102294921875000000f, 0.91418457031250000000f, - 0.08456420898437500000f, 0.10089111328124999000f, - 0.13580322265625000000f, 0.16967773437500000000f, - 0.19692993164062497000f, 0.28970336914062500000f, - 0.41345214843750000000f, 0.45025634765625006000f, - 0.51095581054687500000f, 0.56295776367187500000f, - 0.61120605468750000000f, 0.66333007812499989000f, - 0.72467041015625011000f, 0.77371215820312500000f, - 0.82827758789062500000f, 0.88702392578125000000f, - 0.09240722656250000000f, 0.11901855468750001000f, - 0.20193481445312503000f, 0.24087524414062500000f, - 0.28109741210937500000f, 0.31982421875000000000f, - 0.36764526367187500000f, 0.41452026367187494000f, - 0.46331787109375000000f, 0.50848388671875000000f, - 0.56463623046875000000f, 0.61315917968750000000f, - 0.67718505859374989000f, 0.74334716796875000000f, - 0.80267333984375000000f, 0.88369750976562489000f, - 0.06103515624999999300f, 0.07781982421875000000f, - 0.12411499023437500000f, 0.20864868164062503000f, - 0.29382324218750000000f, 0.33575439453125000000f, - 0.38433837890625006000f, 0.43023681640625000000f, - 0.47573852539062500000f, 0.52474975585937500000f, - 0.57003784179687500000f, 0.61337280273437500000f, - 0.65704345703125000000f, 0.70449829101562500000f, - 0.75198364257812500000f, 0.88568115234375000000f, - 0.08679199218749998600f, 0.10076904296875000000f, - 0.15573120117187500000f, 0.18637084960937500000f, - 0.21090698242187500000f, 0.26239013671875000000f, - 0.37890625000000000000f, 0.42889404296875000000f, - 0.48907470703125000000f, 0.56661987304687500000f, - 0.63085937500000000000f, 0.67962646484375000000f, - 0.73095703125000000000f, 0.78646850585937500000f, - 0.84405517578125000000f, 0.91632080078125000000f, - 0.12338256835937500000f, 0.15716552734375000000f, - 0.22180175781250000000f, 0.27636718750000000000f, - 0.33312988281250000000f, 0.38568115234375006000f, - 0.44381713867187500000f, 0.49389648437500000000f, - 0.54772949218750000000f, 0.60092163085937500000f, - 0.65176391601562500000f, 0.70132446289062500000f, - 0.75759887695312500000f, 0.81149291992187500000f, - 0.86911010742187500000f, 0.92263793945312500000f, - 0.06436157226562500000f, 0.08010864257812500000f, - 0.13183593750000000000f, 0.16860961914062500000f, - 0.22747802734375000000f, 0.31188964843750000000f, - 0.39611816406250006000f, 0.44854736328125000000f, - 0.53793334960937500000f, 0.58786010742187500000f, - 0.62515258789062500000f, 0.68301391601562500000f, - 0.74093627929687500000f, 0.78665161132812500000f, - 0.84982299804687500000f, 0.92950439453125000000f, - 0.04730224609375000000f, 0.08139038085937501400f, - 0.19754028320312500000f, 0.28979492187500000000f, - 0.33523559570312500000f, 0.37695312500000000000f, - 0.42098999023437500000f, 0.46487426757812500000f, - 0.52182006835937500000f, 0.56890869140625000000f, - 0.62442016601562500000f, 0.67492675781250000000f, - 0.73843383789062489000f, 0.80233764648437500000f, - 0.86679077148437500000f, 0.91955566406250000000f, - 0.07357788085937500000f, 0.09411621093750000000f, - 0.12649536132812500000f, 0.16461181640625000000f, - 0.19430541992187500000f, 0.24884033203124997000f, - 0.40054321289062500000f, 0.48977661132812500000f, - 0.53591918945312500000f, 0.58364868164062500000f, - 0.64874267578125000000f, 0.69464111328125000000f, - 0.74642944335937500000f, 0.80313110351562500000f, - 0.86227416992187500000f, 0.90643310546875000000f, - 0.12692260742187500000f, 0.13781738281250000000f, - 0.18176269531250000000f, 0.23300170898437500000f, - 0.25189208984375000000f, 0.27404785156250000000f, - 0.34204101562500000000f, 0.43130493164062500000f, - 0.49468994140624994000f, 0.54550170898437500000f, - 0.61633300781250000000f, 0.66723632812500011000f, - 0.72753906250000000000f, 0.78573608398437511000f, - 0.85626220703125000000f, 0.91589355468750000000f, - 0.06182861328125000000f, 0.07418823242187500000f, - 0.08682250976562500000f, 0.11041259765625000000f, - 0.24261474609375000000f, 0.29913330078125000000f, - 0.38821411132812500000f, 0.44128417968750000000f, - 0.50585937500000000000f, 0.57934570312500000000f, - 0.65234375000000000000f, 0.71163940429687500000f, - 0.76174926757812500000f, 0.81536865234375000000f, - 0.88412475585937500000f, 0.93505859375000000000f, - 0.10464477539062500000f, 0.11697387695312500000f, - 0.13647460937500000000f, 0.14990234375000000000f, - 0.23568725585937500000f, 0.31695556640625000000f, - 0.39614868164062500000f, 0.46759033203125000000f, - 0.50961303710937500000f, 0.57394409179687500000f, - 0.63409423828125000000f, 0.68820190429687511000f, - 0.75155639648437500000f, 0.80853271484375000000f, - 0.86468505859375000000f, 0.93023681640625000000f, - 0.14465332031250000000f, 0.15774536132812500000f, - 0.17687988281250003000f, 0.19790649414062503000f, - 0.21356201171874997000f, 0.26947021484375000000f, - 0.35940551757812500000f, 0.43988037109375000000f, - 0.51364135742187500000f, 0.56192016601562500000f, - 0.63442993164062500000f, 0.68264770507812489000f, - 0.73962402343750000000f, 0.78842163085937511000f, - 0.84860229492187500000f, 0.91616821289062500000f, - 0.00457763671875000000f, 0.00512695312500000000f, - -0.00051879882812500000f, -0.00326538085937500000f, - -0.00433349609375000000f, -0.00698852539062499910f, - -0.00976562500000000000f, -0.01239013671875000000f, - -0.01535034179687500000f, -0.01892089843750000000f, - -0.02645874023437500000f, -0.02853393554687500000f, - -0.02752685546875000000f, -0.02075195312500000000f, - -0.01214599609375000000f, -0.00347900390625000000f, - -0.01214599609375000000f, -0.01083374023437500000f, - 0.00149536132812500000f, 0.00778198242187500000f, - 0.00347900390625000000f, 0.00793457031250000000f, - 0.01217651367187500000f, 0.00805664062500000000f, - 0.00967407226562500000f, 0.01315307617187500000f, - 0.01568603515625000000f, 0.01620483398437500000f, - 0.01327514648437500000f, 0.01086425781250000000f, - 0.00726318359375000000f, 0.00323486328125000000f, - -0.00131225585937500000f, -0.00109863281250000000f, - -0.00515747070312500000f, -0.00683593750000000000f, - -0.01193237304687500000f, -0.01931762695312500000f, - -0.02368164062500000000f, -0.02960205078125000000f, - -0.02575683593750000000f, -0.01388549804687500000f, - -0.00552368164062500000f, -0.00036621093750000000f, - 0.00259399414062500000f, 0.00259399414062500000f, - 0.00500488281250000000f, 0.00595092773437500000f, - 0.00372314453125000000f, 0.00259399414062500000f, - -0.00482177734375000000f, -0.01953125000000000000f, - -0.02755737304687500000f, 0.00027465820312500000f, - 0.00021362304687500000f, -0.00378417968750000000f, - 0.00454711914062500000f, 0.00097656250000000000f, - 0.00671386718750000000f, 0.01126098632812500000f, - 0.00738525390625000000f, 0.00350952148437500040f, - 0.00241088867187500000f, 0.00256347656250000000f, - -0.00445556640625000000f, -0.00659179687500000000f, - -0.00213623046875000000f, 0.03125000000000000000f, - 0.02291870117187500000f, 0.01751708984375000000f, - 0.01342773437500000000f, 0.01150512695312500000f, - 0.01074218749999999800f, 0.00619506835937500000f, - 0.00091552734374999989f, 0.00048828125000000000f, - -0.00009155273437500000f, 0.00247192382812500000f, - 0.00491333007812500000f, 0.00305175781250000000f, - -0.00451660156250000000f, -0.00537109374999999910f, - 0.02847290039062500000f, 0.02288818359375000000f, - 0.01232910156250000000f, 0.00521850585937500000f, - -0.00006103515625000000f, -0.00445556640625000000f, - -0.01254272460937500000f, -0.01348876953125000000f, - -0.01651000976562500000f, -0.01684570312500000000f, - -0.01348876953125000000f, -0.00820922851562500000f, - -0.00732421874999999910f, -0.00158691406250000020f, - 0.01840209960937500000f, 0.01937866210937500000f, - 0.01235961914062499800f, 0.00543212890625000000f, - 0.00656127929687500000f, 0.00057983398437500000f, - -0.00466918945312500000f, -0.00509643554687500000f, - -0.00885009765625000000f, -0.00668334960937500090f, - 0.00460815429687500000f, 0.00827026367187500000f, - 0.00460815429687500000f, 0.00363159179687500000f, - 0.00924682617187500000f, 0.00811767578125000000f, - 0.00305175781250000000f, 0.00210571289062500000f, - -0.00894165039062500000f, -0.02005004882812500000f, - 0.02865600585937500000f, 0.02011108398437500000f, - 0.01348876953125000000f, 0.01071166992187500000f, - 0.00402832031250000000f, 0.00299072265625000000f, - -0.00048828125000000000f, -0.00003051757812500000f, - -0.00411987304687500000f, -0.00610351562500000000f, - -0.00680541992187500000f, -0.00271606445312500000f, - 0.00509643554687500000f, 0.00469970703125000000f, - 0.00524902343750000000f, 0.00723266601562500000f, - -0.00137329101562500000f, -0.00558471679687500000f, - -0.00695800781250000000f, -0.01483154296875000000f, - 0.00802612304687500000f, 0.01855468750000000000f, - 0.00482177734375000000f, -0.00381469726562499960f, - -0.01190185546875000000f, -0.00692749023437500000f, - -0.00360107421875000000f, 0.00131225585937500000f, - -0.01394653320312500000f, -0.01196289062500000000f, - -0.02346801757812500000f, -0.02563476562500000000f, - 0.00061035156250000000f, -0.00357055664062500000f, - -0.00592041015625000000f, -0.00576782226562500000f, - -0.00527954101562500000f, -0.00527954101562500000f, - -0.00100708007812500000f, 0.00097656250000000000f, - 0.00531005859375000000f, 0.00439453125000000000f, - 0.00350952148437500040f, 0.00509643554687500000f, - 0.00173950195312500000f, 0.00134277343749999980f, - 0.00042724609375000000f, 0.00448608398437500000f, - 0.00292968750000000000f, -0.00164794921875000000f, - -0.00433349609375000000f, -0.00393676757812500000f, - -0.00775146484375000000f, -0.01010131835937500000f, - 0.00927734375000000000f, 0.00946044921875000000f, - -0.00158691406250000020f, -0.01278686523437500000f, - -0.02581787109375000000f, -0.03234863281250000000f, - -0.00268554687499999960f, -0.00375366210937500000f, - -0.00616455078125000000f, -0.01046752929687500200f, - -0.01690673828125000000f, -0.02932739257812500000f, - -0.02902221679687500000f, 0.00997924804687500000f, - 0.00485229492187500000f, 0.00247192382812500000f, - 0.00778198242187500000f, 0.00692749023437500000f, - 0.00366210937499999960f, 0.00619506835937500000f, - 0.00781250000000000000f, 0.00585937500000000000f, - 0.00500488281250000000f, 0.00683593750000000000f, - 0.00885009765625000000f, 0.00595092773437500000f, - 0.00659179687500000000f, 0.00637817382812500090f, - 0.00390625000000000000f, 0.02539062500000000300f, - 0.03137207031250000000f, 0.02713012695312500000f, - 0.02130126953125000000f, 0.01538085937500000000f, - 0.01245117187500000000f, 0.01083374023437500000f, - 0.00665283203124999910f, 0.00097656250000000000f, - -0.00350952148437500040f, -0.00256347656250000000f, - -0.00842285156250000000f, -0.00305175781250000000f, - -0.00952148437500000000f, -0.01477050781250000000f, - 0.02743530273437500000f, 0.02081298828124999700f, - 0.01419067382812500000f, 0.01391601562500000000f, - 0.00735473632812500090f, -0.00036621093750000000f, - -0.00839233398437500000f, -0.01296997070312499800f, - -0.01406860351562500000f, -0.01119995117187500000f, - -0.00100708007812500000f, -0.00085449218750000000f, - -0.00311279296875000000f, -0.00592041015625000000f, - -0.01608276367187500000f, 0.02633666992187500000f, - 0.02764892578125000000f, 0.01412963867187500000f, - 0.00747680664062500000f, 0.00039672851562500005f, - -0.00646972656250000000f, -0.00930786132812500000f, - -0.00320434570312500000f, 0.00497436523437500000f, - 0.00851440429687500000f, 0.00537109374999999910f, - 0.00283813476562499960f, 0.00204467773437500000f, - 0.00350952148437500040f, 0.00585937500000000000f, - 0.00186157226562500000f, -0.00152587890625000000f, - -0.00402832031250000000f, -0.00534057617187499910f, - -0.00683593750000000000f, -0.00827026367187500000f, - -0.01919555664062500000f, -0.00769042968750000000f, - 0.03533935546875000000f, 0.02966308593750000000f, - 0.01947021484375000000f, 0.00854492187500000000f, - 0.00915527343750000000f, 0.00994873046875000000f, - 0.00436401367187500000f, -0.00463867187500000000f, - -0.00653076171875000000f, -0.00875854492187500000f, - 0.00161743164062500000f, -0.00128173828125000000f, - -0.00720214843750000000f, -0.01074218749999999800f, - -0.01290893554687500000f, -0.00756835937500000000f, - -0.00393676757812500000f, -0.00497436523437500000f, - -0.00543212890625000000f, -0.00363159179687500000f, - 0.00259399414062500000f, 0.00173950195312500000f, - 0.01568603515625000000f, 0.01165771484375000000f, - 0.01141357421875000200f, 0.01226806640625000000f, - 0.01293945312500000000f, 0.01290893554687500000f, - 0.00827026367187500000f, 0.00601196289062499910f, - 0.00296020507812500000f, 0.00122070312500000000f, - 0.00119018554687500000f, -0.00296020507812500000f, - -0.00582885742187500000f, -0.00500488281250000000f, - -0.00701904296875000090f, -0.00781250000000000000f, - -0.01251220703125000000f, 0.01208496093750000200f, - 0.00997924804687500000f, 0.00387573242187500000f, - 0.00030517578125000000f, -0.00363159179687500000f, - -0.00509643554687500000f, -0.00888061523437500000f, - -0.00836181640625000000f, -0.00430297851562500000f, - -0.00302124023437500040f, -0.00689697265625000000f, - -0.00665283203124999910f, -0.00424194335937500000f, - -0.00683593750000000000f, -0.00637817382812500090f, - -0.00817871093750000000f, -0.01348876953125000000f, - -0.01260375976562500000f, 0.00677490234375000000f, - 0.00177001953125000000f, 0.01589965820312500000f, - 0.01049804687500000000f, 0.00787353515625000000f, - 0.00231933593750000000f, -0.00128173828125000000f, - -0.00433349609375000000f, -0.00503540039062499910f, - -0.00375366210937500000f, -0.00280761718750000000f, - 0.00143432617187500000f, 0.00024414062500000000f, - -0.00009155273437500000f, -0.00582885742187500000f, - -0.00033569335937499995f, -0.00500488281250000000f, - -0.00509643554687500000f, -0.01071166992187500000f, - -0.02258300781250000000f, 0.00949096679687500000f, - 0.01641845703125000000f, 0.00888061523437500000f, - 0.00561523437500000000f, 0.00088500976562500000f, - -0.00320434570312500000f, 0.00027465820312500000f, - -0.00091552734374999989f, -0.00164794921875000000f, - -0.00051879882812500000f, -0.00234985351562500000f, - -0.00827026367187500000f, -0.01257324218750000000f, - -0.01898193359375000000f, -0.01977539062500000000f, - 0.01452636718750000000f, 0.00567626953124999910f, - -0.00201416015625000000f, -0.00601196289062499910f, - -0.00222778320312500000f, -0.00286865234375000000f, - -0.00045776367187499995f, 0.00143432617187500000f, - 0.00085449218750000000f, 0.00341796875000000000f, - -0.00177001953125000000f, -0.00100708007812500000f, - 0.00198364257812500000f, 0.00057983398437500000f, - 0.00256347656250000000f, 0.00262451171875000000f, - 0.00842285156250000000f, 0.00347900390625000000f, - 0.01440429687500000000f, 0.02398681640625000000f, - 0.02438354492187499700f, 0.01907348632812500000f, - 0.01266479492187500000f, 0.00543212890625000000f, - -0.00106811523437500000f, -0.00079345703125000011f, - 0.00015258789062500000f, 0.00027465820312500000f, - 0.00253295898437500040f, 0.00119018554687500000f, - 0.00112915039062500000f, 0.00119018554687500000f, - -0.00561523437500000000f, -0.01141357421875000200f, - -0.00808715820312500000f, -0.01104736328125000000f, - -0.01528930664062500000f, 0.01028442382812500000f, - 0.02185058593750000000f, 0.01458740234374999800f, - -0.00183105468749999980f, -0.00381469726562499960f, - -0.00497436523437500000f, 0.01104736328125000000f, - 0.00051879882812500000f, -0.00372314453125000000f, - -0.00711059570312500000f, 0.00851440429687500000f, - 0.00421142578125000000f, 0.00479125976562500000f, - 0.00970458984375000000f, 0.00588989257812500000f, - 0.00576782226562500000f, 0.00637817382812500090f, - 0.00811767578125000000f, 0.00769042968750000000f, - -0.00140380859375000000f, -0.00170898437500000000f, - -0.00845336914062500000f, -0.01309204101562500000f, - 0.01416015625000000000f, 0.01177978515625000000f, - 0.00433349609375000000f, 0.00134277343749999980f, - -0.00131225585937500000f, 0.00201416015625000000f, - 0.00805664062500000000f, 0.00555419921875000000f, - 0.00143432617187500000f, 0.00042724609375000000f, - -0.00079345703125000011f, -0.00241088867187500000f, - 0.00149536132812500000f, 0.00045776367187499995f, - -0.00390625000000000000f, -0.00619506835937500000f, - -0.01220703125000000000f, -0.01458740234374999800f, - 0.00991821289062500000f, 0.00082397460937500000f, - 0.00714111328125000000f, 0.01254272460937500000f, - 0.00625610351562500000f, 0.00393676757812500000f, - 0.00036621093750000000f, 0.00177001953125000000f, - 0.00375366210937500000f, 0.00173950195312500000f, - 0.00521850585937500000f, 0.00418090820312500000f, - 0.00292968750000000000f, 0.00390625000000000000f, - -0.00097656250000000000f, 0.00408935546875000000f, - -0.00036621093750000000f, 0.00173950195312500000f, - 0.00363159179687500000f, 0.00079345703125000011f, - -0.00067138671874999989f, -0.00503540039062499910f, - -0.01525878906249999800f, -0.02139282226562500000f, - -0.01611328125000000000f, -0.00354003906250000000f, - 0.00195312500000000000f, -0.00024414062500000000f, - 0.00296020507812500000f, -0.00027465820312500000f, - -0.00494384765625000000f, -0.00201416015625000000f, - -0.00476074218750000000f, -0.00592041015625000000f, - -0.00924682617187500000f, -0.01666259765625000000f, - -0.01040649414062499800f, 0.01666259765625000000f, - 0.01092529296875000000f, 0.00289916992187500000f, - 0.00137329101562500000f, 0.00231933593750000000f, - 0.00823974609375000000f, 0.01229858398437500000f, - 0.00625610351562500000f, 0.00305175781250000000f, - 0.00375366210937500000f, 0.00152587890625000000f, - -0.00161743164062500000f, -0.00439453125000000000f, - -0.00335693359375000000f, -0.00039672851562500005f, - 0.00097656250000000000f, -0.00695800781250000000f, - -0.00396728515625000000f, 0.01077270507812500000f, - 0.00903320312500000000f, 0.00170898437500000000f, - -0.01135253906249999800f, -0.00772094726562500000f, - 0.01113891601562500000f, 0.00222778320312500000f, - 0.00030517578125000000f, -0.00103759765625000000f, - -0.00424194335937500000f, -0.00582885742187500000f, - -0.00292968750000000000f, 0.00015258789062500000f, - 0.00134277343749999980f, -0.00259399414062500000f, - -0.00546264648437500000f, -0.00393676757812500000f, - -0.00585937500000000000f, -0.00750732421875000000f, - -0.00259399414062500000f, -0.00335693359375000000f, - -0.00473022460937500000f, -0.00134277343749999980f, - -0.00082397460937500000f, 0.00442504882812500000f, - 0.00421142578125000000f, 0.00241088867187500000f, - 0.00097656250000000000f, -0.00451660156250000000f, - -0.01760864257812500000f, -0.01934814453125000000f, - 0.00582885742187500000f, 0.00286865234375000000f, - -0.00027465820312500000f, -0.00106811523437500000f, - -0.00234985351562500000f, -0.00256347656250000000f, - -0.00170898437500000000f, -0.00521850585937500000f, - -0.00909423828125000000f, -0.00827026367187500000f, - -0.00741577148437500000f, -0.00476074218750000000f, - -0.01000976562500000000f, -0.00717163085937500000f, - -0.00231933593750000000f, -0.00390625000000000000f, - -0.00369262695312500000f, 0.00393676757812500000f, - 0.00039672851562500005f, -0.00067138671874999989f, - 0.00097656250000000000f, 0.00137329101562500000f, - -0.00756835937500000000f, -0.00198364257812500000f, - 0.00588989257812500000f, -0.00247192382812500000f, - 0.00912475585937500000f, 0.00173950195312500000f, - -0.00448608398437500000f, 0.00585937500000000000f, - -0.00503540039062499910f, -0.01080322265625000200f, - -0.01019287109375000000f, -0.00323486328125000000f, - -0.00476074218750000000f, -0.00122070312500000000f, - -0.00009155273437500000f, -0.00207519531250000000f, - 0.00378417968750000000f, -0.00784301757812500000f, - 0.00238037109375000000f, 0.00378417968750000000f, - 0.00518798828125000000f, 0.01257324218750000000f, - 0.00692749023437500000f, 0.00320434570312500000f, - -0.00317382812500000040f, 0.00036621093750000000f, - 0.00469970703125000000f, 0.00762939453124999910f, - 0.00836181640625000000f, 0.00787353515625000000f, - 0.00012207031250000000f, -0.00082397460937500000f, - 0.00717163085937500000f, 0.00463867187500000000f, - 0.00155639648437500000f, 0.01031494140625000000f, - 0.00915527343750000000f, 0.00021362304687500000f, - -0.00958251953125000000f, -0.01254272460937500000f, - 0.00656127929687500000f, 0.00518798828125000000f, - -0.00027465820312500000f, -0.00283813476562499960f, - -0.00234985351562500000f, 0.00231933593750000000f, - 0.00204467773437500000f, 0.00164794921875000000f, - 0.00610351562500000000f, 0.00961303710937500000f, - 0.00497436523437500000f, 0.00219726562500000000f, - -0.00277709960937500000f, -0.01226806640625000000f, - 0.00482177734375000000f, 0.00570678710937500090f, - -0.00476074218750000000f, -0.00277709960937500000f, - 0.00885009765625000000f, 0.00814819335937500000f, - 0.00509643554687500000f, 0.00277709960937500000f, - 0.00427246093750000000f, 0.00521850585937500000f, - 0.00341796875000000000f, 0.00027465820312500000f, - -0.00128173828125000000f, -0.00540161132812500090f, - -0.01342773437500000000f, 0.01174926757812500200f, - 0.00244140625000000000f, 0.00045776367187499995f, - 0.00524902343750000000f, 0.00393676757812500000f, - 0.00125122070312500000f, -0.00393676757812500000f, - -0.01135253906249999800f, -0.00073242187500000000f, - -0.00228881835937500000f, -0.00091552734374999989f, - -0.00518798828125000000f, 0.00030517578125000000f, - -0.00360107421875000000f, 0.00173950195312500000f, - 0.00238037109375000000f, -0.00308227539062500000f, - 0.00708007812500000000f, 0.00491333007812500000f, - 0.00375366210937500000f, 0.00781250000000000000f, - 0.00845336914062500000f, 0.00308227539062500000f, - -0.00585937500000000000f, -0.01919555664062500000f, - -0.00305175781250000000f, -0.00183105468749999980f, - -0.00708007812500000000f, 0.00201416015625000000f, - 0.00039672851562500005f, -0.00039672851562500005f, - -0.00244140625000000000f, -0.00729370117187499910f, - 0.00729370117187499910f, 0.00112915039062500000f, - 0.00097656250000000000f, 0.00271606445312500000f, - -0.00973510742187500000f, -0.01766967773437500000f, - 0.01373291015625000000f, 0.01098632812500000000f, - 0.00009155273437500000f, -0.00088500976562500000f, - -0.00912475585937500000f, -0.00271606445312500000f, - -0.00164794921875000000f, -0.00335693359375000000f, - -0.00750732421875000000f, -0.00500488281250000000f, - 0.00018310546875000000f, -0.00573730468750000000f, - 0.01031494140625000000f, 0.00537109374999999910f, - -0.00280761718750000000f, 0.00601196289062499910f, - 0.00418090820312500000f, 0.00408935546875000000f, - 0.00036621093750000000f, -0.00006103515625000000f, - 0.00170898437500000000f, -0.00558471679687500000f, - 0.00347900390625000000f, -0.00109863281250000000f, - -0.00399780273437500000f, -0.00622558593750000000f, - 0.00228881835937500000f, -0.00076293945312500000f, - -0.00531005859375000000f, 0.00582885742187500000f, - -0.00045776367187499995f, -0.00885009765625000000f, - -0.01309204101562500000f, -0.00814819335937500000f, - 0.00241088867187500000f, 0.00112915039062500000f, - 0.00323486328125000000f, 0.00070190429687500000f, - -0.01171875000000000000f, 0.01296997070312499800f, - 0.00213623046875000000f, -0.00042724609375000000f, - 0.00646972656250000000f, 0.00320434570312500000f, - 0.00045776367187499995f, -0.00006103515625000000f, - -0.00128173828125000000f, -0.00112915039062500000f, - -0.00375366210937500000f, 0.00329589843750000000f, - 0.00085449218750000000f, -0.00146484375000000000f, - 0.00588989257812500000f, 0.00601196289062499910f, - 0.00527954101562500000f, -0.00100708007812500000f, - 0.00112915039062500000f, 0.00222778320312500000f, - -0.00173950195312500000f, 0.00781250000000000000f, - 0.00418090820312500000f, -0.00177001953125000000f, - -0.01312255859375000000f, -0.00695800781250000000f, - 0.00662231445312500000f, -0.00155639648437500000f, - -0.00030517578125000000f, -0.00177001953125000000f, - -0.00018310546875000000f, 0.00067138671874999989f, - 0.00317382812500000040f, 0.00186157226562500000f, - -0.00363159179687500000f, 0.00515747070312500000f, - 0.00439453125000000000f, 0.00048828125000000000f, - -0.00140380859375000000f, -0.01202392578124999800f, - 0.00183105468749999980f, 0.01385498046875000000f, - -0.00244140625000000000f, -0.00909423828125000000f, - -0.00198364257812500000f, 0.00076293945312500000f, - 0.00000000000000000000f, -0.00073242187500000000f, - -0.00198364257812500000f, -0.01272583007812500000f, - 0.01419067382812500000f, 0.00842285156250000000f, - -0.00009155273437500000f, -0.00592041015625000000f, - -0.00039672851562500005f, 0.00396728515625000000f, - 0.00057983398437500000f, -0.00018310546875000000f, - -0.00064086914062500000f, -0.00073242187500000000f, - -0.00549316406250000000f, -0.00161743164062500000f, - -0.00259399414062500000f, 0.00061035156250000000f, - 0.00360107421875000000f, 0.00448608398437500000f, - 0.00344848632812500000f, -0.00228881835937500000f, - -0.00881958007812500000f, 0.00689697265625000000f, - -0.00372314453125000000f, 0.00692749023437500000f, - 0.00823974609375000000f, 0.00381469726562499960f, - 0.00332641601562499960f, 0.00601196289062499910f, - 0.00381469726562499960f, 0.00421142578125000000f, - 0.00134277343749999980f, 0.00183105468749999980f, - 0.00076293945312500000f, -0.00167846679687500000f, - -0.00509643554687500000f, -0.00097656250000000000f, - -0.00424194335937500000f, -0.00588989257812500000f, - -0.00527954101562500000f, -0.00964355468750000000f, - 0.00875854492187500000f, -0.00634765625000000090f, - 0.00772094726562500000f, 0.00729370117187499910f, - 0.00082397460937500000f, -0.00244140625000000000f, - -0.00573730468750000000f, -0.00085449218750000000f, - -0.00555419921875000000f, -0.00717163085937500000f, - 0.00476074218750000000f, -0.00357055664062500000f, - 0.00390625000000000000f, -0.00146484375000000000f, - -0.00177001953125000000f, -0.00689697265625000000f, - 0.00524902343750000000f, 0.00552368164062500000f, - 0.00509643554687500000f, 0.00057983398437500000f, - 0.00189208984375000000f, 0.00030517578125000000f, - 0.00006103515625000000f, 0.00552368164062500000f, - 0.00460815429687500000f, 0.00329589843750000000f, - -0.00048828125000000000f, -0.00033569335937499995f, - -0.00238037109375000000f, -0.01010131835937500000f, - 0.01254272460937500000f, 0.00405883789062500000f, - 0.00051879882812500000f, 0.00317382812500000040f, - 0.00195312500000000000f, -0.00561523437500000000f, - 0.00073242187500000000f, -0.00091552734374999989f, - -0.00009155273437500000f, -0.00863647460937500000f, - 0.00369262695312500000f, 0.00622558593750000000f, - -0.00024414062500000000f, -0.00607299804687500000f, - -0.00064086914062500000f, -0.00244140625000000000f, - -0.00515747070312500000f, -0.00479125976562500000f, - -0.00582885742187500000f, -0.00415039062500000000f, - 0.00247192382812500000f, 0.00473022460937500000f, - 0.00042724609375000000f, -0.00399780273437500000f, - 0.00744628906250000000f, 0.00225830078125000000f, - -0.00173950195312500000f, -0.00143432617187500000f, - -0.00854492187500000000f, 0.01058959960937500000f, - 0.00338745117187500000f, -0.00234985351562500000f, - -0.00390625000000000000f, -0.00433349609375000000f, - -0.00592041015625000000f, -0.00381469726562499960f, - -0.00018310546875000000f, -0.00207519531250000000f, - 0.00277709960937500000f, 0.00003051757812500000f, - 0.00070190429687500000f, 0.00042724609375000000f, - -0.00469970703125000000f, -0.00103759765625000000f, - 0.00070190429687500000f, -0.00115966796875000000f, - -0.01046752929687500200f, 0.01535034179687500000f, - 0.00445556640625000000f, -0.00115966796875000000f, - -0.00140380859375000000f, -0.00125122070312500000f, - 0.00177001953125000000f, 0.00094604492187500000f, - 0.00192260742187500000f, -0.00146484375000000000f, - -0.00357055664062500000f, 0.00137329101562500000f, - 0.00085449218750000000f, 0.00003051757812500000f, - -0.00271606445312500000f, -0.00015258789062500000f, - -0.00134277343749999980f, -0.00088500976562500000f, - -0.01367187500000000000f, 0.01486206054687500000f, - 0.00622558593750000000f, 0.00247192382812500000f, - 0.00140380859375000000f, -0.00323486328125000000f, - -0.00921630859375000000f, 0.01159667968750000000f, - 0.00366210937499999960f, -0.00115966796875000000f, - -0.00036621093750000000f, -0.00119018554687500000f, - 0.00213623046875000000f, -0.00009155273437500000f, - 0.00076293945312500000f, -0.00198364257812500000f, - 0.00091552734374999989f, -0.00033569335937499995f, - 0.00103759765625000000f, -0.00045776367187499995f, - 0.00067138671874999989f, -0.00350952148437500040f, - 0.00000000000000000000f, -0.00241088867187500000f, - -0.00253295898437500040f, 0.00137329101562500000f, - 0.00347900390625000000f, 0.00131225585937500000f, - 0.00457763671875000000f, 0.00109863281250000000f, - 0.00711059570312500000f, 0.00454711914062500000f, - 0.00595092773437500000f, 0.00015258789062500000f, - 0.00076293945312500000f, -0.00158691406250000020f, - -0.01449584960937500000f, 0.00836181640625000000f, - 0.00085449218750000000f, -0.00119018554687500000f, - -0.00024414062500000000f, -0.00201416015625000000f, - -0.00778198242187500000f, 0.00787353515625000000f, - 0.00170898437500000000f, 0.00436401367187500000f, - -0.00137329101562500000f, -0.00579833984375000000f, - 0.00503540039062499910f, -0.00183105468749999980f, - 0.00061035156250000000f, 0.00006103515625000000f, - 0.00381469726562499960f, -0.00393676757812500000f, - 0.00155639648437500000f, -0.00024414062500000000f, - -0.01022338867187500000f, 0.00878906250000000000f, - 0.00115966796875000000f, 0.00180053710937500000f, - 0.00076293945312500000f, -0.00128173828125000000f, - 0.00070190429687500000f, -0.00360107421875000000f, - -0.00341796875000000000f, 0.00033569335937499995f, - -0.00167846679687500000f, -0.00405883789062500000f, - -0.00332641601562499960f, 0.00073242187500000000f, - -0.00320434570312500000f, 0.00238037109375000000f, - -0.00195312500000000000f, -0.00747680664062500000f, - 0.00616455078125000000f, -0.00198364257812500000f, - -0.00387573242187500000f, 0.00494384765625000000f, - 0.00122070312500000000f, -0.00286865234375000000f, - 0.00271606445312500000f, -0.00259399414062500000f, - -0.00363159179687500000f, -0.00314331054687500000f, - 0.00296020507812500000f, 0.00027465820312500000f, - -0.00213623046875000000f, -0.00085449218750000000f, - 0.00592041015625000000f, 0.00262451171875000000f, - -0.00341796875000000000f, -0.00280761718750000000f, - -0.00347900390625000000f, 0.00225830078125000000f, - -0.00149536132812500000f, 0.00140380859375000000f, - -0.00256347656250000000f, -0.00543212890625000000f, - 0.00344848632812500000f, 0.00158691406250000020f, - -0.00625610351562500000f, 0.01016235351562500000f, - 0.00268554687499999960f, 0.00677490234375000000f, - 0.00170898437500000000f, -0.00167846679687500000f, - 0.00039672851562500005f, 0.00262451171875000000f, - 0.00012207031250000000f, -0.00234985351562500000f, - 0.00683593750000000000f, 0.00347900390625000000f, - -0.00320434570312500000f, 0.00341796875000000000f, - 0.00381469726562499960f, -0.00088500976562500000f, - -0.00054931640625000000f, -0.00439453125000000000f, - 0.00067138671874999989f, -0.00177001953125000000f, - -0.00302124023437500040f, 0.00085449218750000000f, - 0.00347900390625000000f, -0.00201416015625000000f, - -0.00097656250000000000f, -0.00515747070312500000f, - -0.00958251953125000000f, 0.00869750976562500000f, - 0.00219726562500000000f, -0.00225830078125000000f, - 0.00546264648437500000f, 0.00085449218750000000f, - -0.00241088867187500000f, -0.00555419921875000000f, - 0.00039672851562500005f, -0.00167846679687500000f, - 0.00448608398437500000f, 0.00039672851562500005f, - 0.00036621093750000000f, -0.00164794921875000000f, - 0.00094604492187500000f, -0.00256347656250000000f, - -0.00051879882812500000f, -0.00228881835937500000f, - -0.00695800781250000000f, 0.00253295898437500040f, - -0.01144409179687500000f, 0.01330566406249999800f, - 0.00335693359375000000f, -0.00192260742187500000f, - -0.00082397460937500000f, -0.00415039062500000000f, - 0.00515747070312500000f, -0.00170898437500000000f, - -0.00024414062500000000f, -0.00521850585937500000f, - 0.00561523437500000000f, -0.00128173828125000000f, - 0.00451660156250000000f, 0.00207519531250000000f, - 0.00622558593750000000f, 0.00717163085937500000f, - 0.00335693359375000000f, -0.00698852539062499910f, - 0.00277709960937500000f, 0.00521850585937500000f, - -0.00131225585937500000f, -0.00009155273437500000f, - -0.00079345703125000011f, -0.00302124023437500040f, - -0.00338745117187500000f, 0.00216674804687500000f, - -0.00518798828125000000f, 0.00616455078125000000f, - -0.00204467773437500000f, 0.00552368164062500000f, - -0.00112915039062500000f, 0.00332641601562499960f, - -0.00366210937499999960f, 0.00009155273437500000f, - -0.00167846679687500000f, -0.00793457031250000000f, - -0.00048828125000000000f, 0.00463867187500000000f, - 0.00277709960937500000f, 0.00433349609375000000f, - 0.00128173828125000000f, 0.00134277343749999980f, - 0.00408935546875000000f, 0.00143432617187500000f, - 0.00051879882812500000f, -0.00106811523437500000f, - 0.00067138671874999989f, 0.00241088867187500000f, - -0.00515747070312500000f, 0.00125122070312500000f, - 0.00140380859375000000f, 0.00845336914062500000f, - -0.00283813476562499960f, -0.00149536132812500000f, - -0.00384521484375000000f, 0.00112915039062500000f, - -0.00314331054687500000f, -0.00103759765625000000f, - -0.00067138671874999989f, -0.00274658203125000000f, - -0.00408935546875000000f, -0.00625610351562500000f, - 0.00280761718750000000f, -0.00027465820312500000f, - 0.00003051757812500000f, -0.00595092773437500000f, - -0.00729370117187499910f, 0.00137329101562500000f, - 0.00164794921875000000f, 0.00054931640625000000f, - -0.00070190429687500000f, -0.00003051757812500000f, - -0.00244140625000000000f, -0.00299072265625000000f, - -0.00061035156250000000f, -0.00796508789062500000f, - 0.00933837890625000000f, 0.00219726562500000000f, - 0.00061035156250000000f, -0.00271606445312500000f, - -0.00662231445312500000f, 0.00033569335937499995f, - 0.00018310546875000000f, -0.00250244140625000000f, - 0.00271606445312500000f, 0.00039672851562500005f, - -0.00393676757812500000f, -0.00271606445312500000f, - 0.00253295898437500040f, -0.00216674804687500000f, - -0.00167846679687500000f, 0.00396728515625000000f, - -0.00299072265625000000f, -0.00445556640625000000f, - -0.00082397460937500000f, -0.00173950195312500000f, - 0.00161743164062500000f, 0.00839233398437500000f, - 0.00051879882812500000f, 0.00518798828125000000f, - -0.00015258789062500000f, -0.00164794921875000000f, - 0.00402832031250000000f, -0.00195312500000000000f, - 0.00219726562500000000f, 0.00488281250000000000f, - -0.00381469726562499960f, -0.00512695312500000000f, - 0.00219726562500000000f, 0.00122070312500000000f, - 0.00518798828125000000f, 0.00238037109375000000f, - 0.00756835937500000000f, 0.00354003906250000000f, - 0.00061035156250000000f, 0.00256347656250000000f, - 0.00094604492187500000f, -0.00103759765625000000f, - 0.00579833984375000000f, 0.00115966796875000000f, - 0.00039672851562500005f, -0.00323486328125000000f, - 0.00686645507812500000f, 0.00082397460937500000f, - -0.00512695312500000000f, 0.00073242187500000000f, - -0.00479125976562500000f, -0.00372314453125000000f, - 0.00503540039062499910f, 0.00033569335937499995f, - -0.00491333007812500000f, -0.00650024414062500000f, - -0.00036621093750000000f, -0.00155639648437500000f, - -0.00308227539062500000f, 0.00128173828125000000f, - 0.00308227539062500000f, 0.00082397460937500000f, - 0.00167846679687500000f, 0.00338745117187500000f, - 0.00228881835937500000f, 0.00216674804687500000f, - -0.00292968750000000000f, -0.00003051757812500000f, - 0.00198364257812500000f, -0.00845336914062500000f, - 0.01199340820312500000f, -0.00079345703125000011f, - -0.00134277343749999980f, -0.00207519531250000000f, - -0.00256347656250000000f, -0.00201416015625000000f, - -0.00289916992187500000f, 0.00717163085937500000f, - 0.00546264648437500000f, -0.00076293945312500000f, - -0.00125122070312500000f, 0.00082397460937500000f, - -0.00277709960937500000f, -0.00390625000000000000f, - -0.00677490234375000000f, 0.00445556640625000000f, - -0.00219726562500000000f, -0.00091552734374999989f, - -0.00073242187500000000f, 0.00167846679687500000f, - -0.00384521484375000000f, -0.00207519531250000000f, - -0.00177001953125000000f, -0.00387573242187500000f, - 0.00039672851562500005f, -0.00296020507812500000f, - -0.00323486328125000000f, 0.00531005859375000000f, - -0.00305175781250000000f, 0.00473022460937500000f, - 0.00308227539062500000f, -0.00445556640625000000f, - -0.00064086914062500000f, 0.00796508789062500000f, - 0.00067138671874999989f, 0.00115966796875000000f, - -0.00201416015625000000f, 0.00198364257812500000f, - 0.00012207031250000000f, 0.00213623046875000000f, - 0.00195312500000000000f, 0.00439453125000000000f, - 0.00180053710937500000f, 0.00650024414062500000f, - 0.00216674804687500000f, -0.01028442382812500000f, - 0.00924682617187500000f, -0.00158691406250000020f, - 0.00155639648437500000f, -0.00170898437500000000f, - 0.00003051757812500000f, 0.00030517578125000000f, - -0.00045776367187499995f, -0.00015258789062500000f, - 0.00103759765625000000f, 0.00158691406250000020f, - 0.00695800781250000000f, 0.00399780273437500000f, - 0.00491333007812500000f, -0.00387573242187500000f, - -0.00653076171875000000f, 0.00726318359375000000f, - 0.00375366210937500000f, 0.00195312500000000000f, - -0.00448608398437500000f, -0.00152587890625000000f, - -0.00103759765625000000f, -0.00387573242187500000f, - 0.00622558593750000000f, 0.00494384765625000000f, - 0.00259399414062500000f, 0.00125122070312500000f, - 0.00015258789062500000f, -0.00427246093750000000f, - 0.00222778320312500000f, -0.00457763671875000000f, - 0.00170898437500000000f, -0.00292968750000000000f, - -0.00201416015625000000f, -0.00061035156250000000f, - 0.00006103515625000000f, -0.00717163085937500000f, - 0.00180053710937500000f, -0.00067138671874999989f, - -0.00326538085937500000f, 0.00457763671875000000f, - -0.00048828125000000000f, -0.00143432617187500000f, - -0.00012207031250000000f, 0.00247192382812500000f, - -0.00204467773437500000f, 0.00509643554687500000f, - 0.00454711914062500000f, 0.00454711914062500000f, - -0.00479125976562500000f, 0.00878906250000000000f, - -0.00476074218750000000f, -0.00082397460937500000f, - -0.00024414062500000000f, 0.00054931640625000000f, - 0.00253295898437500040f, -0.00073242187500000000f, - -0.00125122070312500000f, -0.00509643554687500000f, - 0.00482177734375000000f, -0.00305175781250000000f, - 0.00283813476562499960f, 0.00161743164062500000f, - 0.00613403320312500000f, 0.00045776367187499995f, - 0.00128173828125000000f, 0.00811767578125000000f, - 0.00848388671875000000f, -0.00036621093750000000f, - -0.00018310546875000000f, -0.00112915039062500000f, - 0.00259399414062500000f, 0.00018310546875000000f, - 0.00061035156250000000f, -0.00573730468750000000f, - -0.00827026367187500000f, 0.00326538085937500000f, - -0.00039672851562500005f, -0.00244140625000000000f, - 0.00155639648437500000f, 0.00616455078125000000f, - 0.00527954101562500000f, -0.00210571289062500000f, - 0.00238037109375000000f, -0.00573730468750000000f, - 0.00140380859375000000f, 0.00012207031250000000f, - 0.00466918945312500000f, 0.00036621093750000000f, - -0.00421142578125000000f, 0.00515747070312500000f, - 0.00015258789062500000f, -0.00177001953125000000f, - -0.00375366210937500000f, -0.00329589843750000000f, - -0.00741577148437500000f, 0.00457763671875000000f, - 0.00030517578125000000f, -0.00582885742187500000f, - 0.00750732421875000000f, -0.00045776367187499995f, - 0.00115966796875000000f, 0.00076293945312500000f, - -0.00030517578125000000f, 0.00042724609375000000f, - 0.00186157226562500000f, 0.00152587890625000000f, - -0.00628662109375000000f, -0.00656127929687500000f, - -0.00671386718750000000f, 0.00274658203125000000f, - 0.00015258789062500000f, -0.00454711914062500000f, - -0.00668334960937500090f, 0.00170898437500000000f, - 0.00433349609375000000f, 0.00073242187500000000f, - -0.01147460937500000000f, 0.00234985351562500000f, - -0.00244140625000000000f, 0.00228881835937500000f, - 0.00018310546875000000f, 0.00128173828125000000f, - -0.00308227539062500000f, 0.00048828125000000000f, - 0.00170898437500000000f, 0.00042724609375000000f, - -0.00173950195312500000f, 0.00009155273437500000f, - -0.00051879882812500000f, 0.00244140625000000000f, - 0.00173950195312500000f, -0.00109863281250000000f, - 0.00268554687499999960f, -0.00180053710937500000f, - -0.00296020507812500000f, -0.00057983398437500000f, - -0.00451660156250000000f, 0.00140380859375000000f, - -0.00668334960937500090f, 0.00689697265625000000f, - 0.00347900390625000000f, -0.00012207031250000000f, - -0.00219726562500000000f, -0.00045776367187499995f, - 0.00112915039062500000f, -0.00149536132812500000f, - -0.00085449218750000000f, 0.00753784179687500000f, - 0.00134277343749999980f, 0.00375366210937500000f, - 0.00143432617187500000f, -0.00372314453125000000f, - -0.00115966796875000000f, 0.00051879882812500000f, - 0.00012207031250000000f, -0.00344848632812500000f, - -0.00097656250000000000f, -0.00683593750000000000f, - 0.00469970703125000000f, -0.00408935546875000000f, - 0.00598144531250000000f, 0.00216674804687500000f, - -0.00814819335937500000f, -0.00259399414062500000f, - 0.00085449218750000000f, -0.00213623046875000000f, - 0.00271606445312500000f, -0.00366210937499999960f, - 0.00302124023437500040f, -0.00006103515625000000f, - 0.00195312500000000000f, 0.00231933593750000000f, - -0.00506591796875000090f, -0.00146484375000000000f, - 0.00576782226562500000f, -0.00106811523437500000f, - -0.00280761718750000000f, -0.00515747070312500000f, - -0.00375366210937500000f, 0.01034545898437500000f, - 0.00115966796875000000f, -0.00076293945312500000f, - 0.00115966796875000000f, -0.00106811523437500000f, - 0.00686645507812500000f, -0.00424194335937500000f, - -0.00152587890625000000f, -0.00192260742187500000f, - 0.00750732421875000000f, 0.00183105468749999980f, - -0.00564575195312500000f, -0.00332641601562499960f, - -0.00149536132812500000f, -0.00161743164062500000f, - -0.00509643554687500000f, 0.00155639648437500000f, - 0.00454711914062500000f, 0.00183105468749999980f, - -0.00308227539062500000f, -0.00100708007812500000f, - 0.00076293945312500000f, -0.00231933593750000000f, - 0.00366210937499999960f, 0.00097656250000000000f, - -0.00091552734374999989f, -0.00253295898437500040f, - 0.00311279296875000000f, 0.00277709960937500000f, - -0.00567626953124999910f, -0.00796508789062500000f, - 0.00399780273437500000f, -0.00601196289062499910f - }; -// const SKP_Silk_NLSF_CBS_FLP SKP_Silk_NLSF_CB0_16_Stage_info_FLP[ NLSF_MSVQ_CB0_16_STAGES ] = -// { -// { 128, &SKP_Silk_NLSF_MSVQ_CB0_16[ 16 * 0 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates[ 0 ] }, -// { 16, &SKP_Silk_NLSF_MSVQ_CB0_16[ 16 * 128 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates[ 128 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB0_16[ 16 * 144 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates[ 144 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB0_16[ 16 * 152 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates[ 152 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB0_16[ 16 * 160 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates[ 160 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB0_16[ 16 * 168 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates[ 168 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB0_16[ 16 * 176 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates[ 176 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB0_16[ 16 * 184 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates[ 184 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB0_16[ 16 * 192 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates[ 192 ] }, -// { 16, &SKP_Silk_NLSF_MSVQ_CB0_16[ 16 * 200 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates[ 200 ] } -// }; - static final SKP_Silk_NLSF_CBS_FLP SKP_Silk_NLSF_CB0_16_Stage_info_FLP[] = - { - new SKP_Silk_NLSF_CBS_FLP(128, SKP_Silk_NLSF_MSVQ_CB0_16, 16*0, SKP_Silk_NLSF_MSVQ_CB0_16_rates, 0), - new SKP_Silk_NLSF_CBS_FLP(16, SKP_Silk_NLSF_MSVQ_CB0_16, 16*128, SKP_Silk_NLSF_MSVQ_CB0_16_rates, 128), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB0_16, 16*144, SKP_Silk_NLSF_MSVQ_CB0_16_rates, 144), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB0_16, 16*152, SKP_Silk_NLSF_MSVQ_CB0_16_rates, 152), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB0_16, 16*160, SKP_Silk_NLSF_MSVQ_CB0_16_rates, 160), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB0_16, 16*168, SKP_Silk_NLSF_MSVQ_CB0_16_rates, 168), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB0_16, 16*176, SKP_Silk_NLSF_MSVQ_CB0_16_rates, 176), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB0_16, 16*184, SKP_Silk_NLSF_MSVQ_CB0_16_rates, 184), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB0_16, 16*192, SKP_Silk_NLSF_MSVQ_CB0_16_rates, 192), - new SKP_Silk_NLSF_CBS_FLP(16, SKP_Silk_NLSF_MSVQ_CB0_16, 16*200, SKP_Silk_NLSF_MSVQ_CB0_16_rates, 200), - }; - -// const SKP_Silk_NLSF_CB_FLP SKP_Silk_NLSF_CB0_16_FLP = -// { -// NLSF_MSVQ_CB0_16_STAGES, -// SKP_Silk_NLSF_CB0_16_Stage_info_FLP, -// SKP_Silk_NLSF_MSVQ_CB0_16_ndelta_min, -// SKP_Silk_NLSF_MSVQ_CB0_16_CDF, -// SKP_Silk_NLSF_MSVQ_CB0_16_CDF_start_ptr, -// SKP_Silk_NLSF_MSVQ_CB0_16_CDF_middle_idx -// }; - - static final SKP_Silk_NLSF_CB_FLP SKP_Silk_NLSF_CB0_16_FLP = - new SKP_Silk_NLSF_CB_FLP( - Silk_tables_NLSF_CB0_16.NLSF_MSVQ_CB0_16_STAGES, - SKP_Silk_NLSF_CB0_16_Stage_info_FLP, - SKP_Silk_NLSF_MSVQ_CB0_16_ndelta_min, - Silk_tables_NLSF_CB0_16.SKP_Silk_NLSF_MSVQ_CB0_16_CDF, - Silk_tables_NLSF_CB0_16.SKP_Silk_NLSF_MSVQ_CB0_16_CDF_start_ptr, - Silk_tables_NLSF_CB0_16.SKP_Silk_NLSF_MSVQ_CB0_16_CDF_middle_idx - ); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB1_10.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB1_10.java deleted file mode 100644 index a4b52b1b3..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB1_10.java +++ /dev/null @@ -1,576 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * This file has been automatically generated - * ROM usage: 0.19 + 1.61 kB. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_tables_NLSF_CB1_10 -{ - static final int NLSF_MSVQ_CB1_10_STAGES = 6; - static final int NLSF_MSVQ_CB1_10_VECTORS = 72; - - static final int[] SKP_Silk_NLSF_MSVQ_CB1_10_CDF = - { - 0, - 17096, - 24130, - 28997, - 33179, - 36696, - 40213, - 42493, - 44252, - 45973, - 47551, - 49095, - 50542, - 51898, - 53196, - 54495, - 55685, - 56851, - 57749, - 58628, - 59435, - 60207, - 60741, - 61220, - 61700, - 62179, - 62659, - 63138, - 63617, - 64097, - 64576, - 65056, - 65535, - 0, - 20378, - 33032, - 40395, - 46721, - 51707, - 56585, - 61157, - 65535, - 0, - 15055, - 25472, - 35447, - 42501, - 48969, - 54773, - 60212, - 65535, - 0, - 12069, - 22440, - 32812, - 40145, - 46870, - 53595, - 59630, - 65535, - 0, - 10839, - 19954, - 27957, - 35961, - 43965, - 51465, - 58805, - 65535, - 0, - 8933, - 17674, - 26415, - 34785, - 42977, - 50820, - 58496, - 65535 - }; - - static private int [] SKP_Silk_NLSF_MSVQ_CB1_10_CDF_0 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB1_10_CDF, 0, SKP_Silk_NLSF_MSVQ_CB1_10_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB1_10_CDF_33 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB1_10_CDF, 33, SKP_Silk_NLSF_MSVQ_CB1_10_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB1_10_CDF_42 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB1_10_CDF, 42, SKP_Silk_NLSF_MSVQ_CB1_10_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB1_10_CDF_51 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB1_10_CDF, 51, SKP_Silk_NLSF_MSVQ_CB1_10_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB1_10_CDF_60 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB1_10_CDF, 60, SKP_Silk_NLSF_MSVQ_CB1_10_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB1_10_CDF_69 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB1_10_CDF, 69, SKP_Silk_NLSF_MSVQ_CB1_10_CDF.length); - - static final int[][] SKP_Silk_NLSF_MSVQ_CB1_10_CDF_start_ptr = - { - SKP_Silk_NLSF_MSVQ_CB1_10_CDF_0, - SKP_Silk_NLSF_MSVQ_CB1_10_CDF_33, - SKP_Silk_NLSF_MSVQ_CB1_10_CDF_42, - SKP_Silk_NLSF_MSVQ_CB1_10_CDF_51, - SKP_Silk_NLSF_MSVQ_CB1_10_CDF_60, - SKP_Silk_NLSF_MSVQ_CB1_10_CDF_69 - - }; - - static final int[] SKP_Silk_NLSF_MSVQ_CB1_10_CDF_middle_idx = - { - 5, - 3, - 4, - 4, - 5, - 5 - }; - - static final short[] SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5 = - { - 62, 103, - 120, 127, - 135, 135, - 155, 167, - 168, 172, - 173, 176, - 179, 181, - 181, 185, - 186, 198, - 199, 203, - 205, 222, - 227, 227, - 227, 227, - 227, 227, - 227, 227, - 227, 227, - 54, 76, - 101, 108, - 119, 120, - 123, 125, - 68, 85, - 87, 103, - 107, 112, - 115, 116, - 78, 85, - 85, 101, - 105, 105, - 110, 111, - 83, 91, - 97, 97, - 97, 100, - 101, 105, - 92, 93, - 93, 95, - 96, 98, - 99, 103 - }; - - static final int[] SKP_Silk_NLSF_MSVQ_CB1_10_ndelta_min_Q15 = - { - 462, - 3, - 64, - 74, - 98, - 50, - 97, - 68, - 120, - 53, - 639 - }; - - static final short[ ] SKP_Silk_NLSF_MSVQ_CB1_10_Q15 = - { - 1877, 4646, - 7712, 10745, - 13964, 17028, - 20239, 23182, - 26471, 29287, - 1612, 3278, - 7086, 9975, - 13228, 16264, - 19596, 22690, - 26037, 28965, - 2169, 3830, - 6460, 8958, - 11960, 14750, - 18408, 21659, - 25018, 28043, - 3680, 6024, - 8986, 12256, - 15201, 18188, - 21741, 24460, - 27484, 30059, - 2584, 5187, - 7799, 10902, - 13179, 15765, - 19017, 22431, - 25891, 28698, - 3731, 5751, - 8650, 11742, - 15090, 17407, - 20391, 23421, - 26228, 29247, - 2107, 6323, - 8915, 12226, - 14775, 17791, - 20664, 23679, - 26829, 29353, - 1677, 2870, - 5386, 8077, - 11817, 15176, - 18657, 22006, - 25513, 28689, - 2111, 3625, - 7027, 10588, - 14059, 17193, - 21137, 24260, - 27577, 30036, - 2428, 4010, - 5765, 9376, - 13805, 15821, - 19444, 22389, - 25295, 29310, - 2256, 4628, - 8377, 12441, - 15283, 19462, - 22257, 25551, - 28432, 30304, - 2352, 3675, - 6129, 11868, - 14551, 16655, - 19624, 21883, - 26526, 28849, - 5243, 7248, - 10558, 13269, - 15651, 17919, - 21141, 23827, - 27102, 29519, - 4422, 6725, - 10449, 13273, - 16124, 19921, - 22826, 26061, - 28763, 30583, - 4508, 6291, - 9504, 11809, - 13827, 15950, - 19077, 22084, - 25740, 28658, - 2540, 4297, - 8579, 13578, - 16634, 19101, - 21547, 23887, - 26777, 29146, - 3377, 6358, - 10224, 14518, - 17905, 21056, - 23637, 25784, - 28161, 30109, - 4177, 5942, - 8159, 10108, - 12130, 15470, - 20191, 23326, - 26782, 29359, - 2492, 3801, - 6144, 9825, - 16000, 18671, - 20893, 23663, - 25899, 28974, - 3011, 4727, - 6834, 10505, - 12465, 14496, - 17065, 20052, - 25265, 28057, - 4149, 7197, - 12338, 15076, - 18002, 20190, - 22187, 24723, - 27083, 29125, - 2975, 4578, - 6448, 8378, - 9671, 13225, - 19502, 22277, - 26058, 28850, - 4102, 5760, - 7744, 9484, - 10744, 12308, - 14677, 19607, - 24841, 28381, - 4931, 9287, - 12477, 13395, - 13712, 14351, - 16048, 19867, - 24188, 28994, - 4141, 7867, - 13140, 17720, - 20064, 21108, - 21692, 22722, - 23736, 27449, - 4011, 8720, - 13234, 16206, - 17601, 18289, - 18524, 19689, - 23234, 27882, - 3420, 5995, - 11230, 15117, - 15907, 16783, - 17762, 23347, - 26898, 29946, - 3080, 6786, - 10465, 13676, - 18059, 23615, - 27058, 29082, - 29563, 29905, - 3038, 5620, - 9266, 12870, - 18803, 19610, - 20010, 20802, - 23882, 29306, - 3314, 6420, - 9046, 13262, - 15869, 23117, - 23667, 24215, - 24487, 25915, - 3469, 6963, - 10103, 15282, - 20531, 23240, - 25024, 26021, - 26736, 27255, - 3041, 6459, - 9777, 12896, - 16315, 19410, - 24070, 29353, - 31795, 32075, - -200, -134, - -113, -204, - -347, -440, - -352, -211, - -418, -172, - -313, 59, - 495, 772, - 721, 614, - 334, 444, - 225, 242, - 161, 16, - 274, 564, - -73, -188, - -395, -171, - 777, 508, - 1340, 1145, - 699, 196, - 223, 173, - 90, 25, - -26, 18, - 133, -105, - -360, -277, - 859, 634, - 41, -557, - -768, -926, - -601, -1021, - -1189, -365, - 225, 107, - 374, -50, - 433, 417, - 156, 39, - -597, -1397, - -1594, -592, - -485, -292, - 253, 87, - -0, -6, - -25, -345, - -240, 120, - 1261, 946, - 166, -277, - 241, 167, - 170, 429, - 518, 714, - 602, 254, - 134, 92, - -152, -324, - -394, 49, - -151, -304, - -724, -657, - -162, -369, - -35, 3, - -2, -312, - -200, -92, - -227, 242, - 628, 565, - -124, 1056, - 770, 101, - -84, -33, - 4, -192, - -272, 5, - -627, -977, - 419, 472, - 53, -103, - 145, 322, - -95, -31, - -100, -303, - -560, -1067, - -413, 714, - 283, 2, - -223, -367, - 523, 360, - -38, -115, - 378, -591, - -718, 448, - -481, -274, - 180, -88, - -581, -157, - -696, -1265, - 394, -479, - -23, 124, - -43, 19, - -113, -236, - -412, -659, - -200, 2, - -69, -342, - 199, 55, - 58, -36, - -51, -62, - 507, 507, - 427, 442, - 36, 601, - -141, 68, - 274, 274, - 68, -12, - -4, 71, - -193, -464, - -425, -383, - 408, 203, - -337, 236, - 410, -59, - -25, -341, - -449, 28, - -9, 90, - 332, -14, - -905, 96, - -540, -242, - 679, -59, - 192, -24, - 60, -217, - 5, -37, - 179, -20, - 311, 519, - 274, 72, - -326, -1030, - -262, 213, - 380, 82, - 328, 411, - -540, 574, - -283, 151, - 181, -402, - -278, -240, - -110, -227, - -264, -89, - -250, -259, - -27, 106, - -239, -98, - -390, 118, - 61, 104, - 294, 532, - 92, -13, - 60, -233, - 335, 541, - 307, -26, - -110, -91, - -231, -460, - 170, 201, - 96, -372, - 132, 435, - -302, 216, - -279, -41, - 74, 190, - 368, 273, - -186, -608, - -157, 159, - 12, 278, - 245, 307, - 25, -187, - -16, 55, - 30, -163, - 548, -307, - 106, -5, - 27, 330, - -416, 475, - 438, -235, - 104, 137, - 21, -5, - -300, -468, - 521, -347, - 170, -200, - -219, 308, - -122, -133, - 219, -16, - 359, 412, - -89, -111, - 48, 322, - 142, 177, - -286, -127, - -39, -63, - -42, -451, - 160, 308, - -57, 193, - -48, 74, - -346, 59, - -27, 27, - -469, -277, - -344, 282, - 262, 122, - 171, -249, - 27, 258, - 188, -3, - 67, -206, - -284, 291, - -117, -88, - -477, 375, - 50, 106, - 99, -182, - 438, -376, - -401, -49, - 119, -23, - -10, -48, - -116, -200, - -310, 121, - 73, 7, - 237, -226, - 139, -456, - 397, 35, - 3, -108, - 323, -75, - 332, 198, - -99, -21 - }; - - static final SKP_Silk_NLSF_CBS[] SKP_Silk_NLSF_CB1_10_Stage_info = - { - new SKP_Silk_NLSF_CBS(32,SKP_Silk_NLSF_MSVQ_CB1_10_Q15, 0, SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5, 0 ), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB1_10_Q15, 10 * 32, SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5, 32 ), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB1_10_Q15, 10 * 40, SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5, 40 ), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB1_10_Q15, 10 * 48, SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5, 48 ), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB1_10_Q15, 10 * 56, SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5, 56 ), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB1_10_Q15, 10 * 64, SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5, 64 ), - }; - - static final SKP_Silk_NLSF_CB_struct SKP_Silk_NLSF_CB1_10 = - new SKP_Silk_NLSF_CB_struct - ( - NLSF_MSVQ_CB1_10_STAGES, - SKP_Silk_NLSF_CB1_10_Stage_info, - SKP_Silk_NLSF_MSVQ_CB1_10_ndelta_min_Q15, - SKP_Silk_NLSF_MSVQ_CB1_10_CDF, - SKP_Silk_NLSF_MSVQ_CB1_10_CDF_start_ptr, - SKP_Silk_NLSF_MSVQ_CB1_10_CDF_middle_idx - ); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB1_10_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB1_10_FLP.java deleted file mode 100644 index e1994094d..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB1_10_FLP.java +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * This file has been automatically generated. - * ROM usage: 3.21 kB. - * - * @author Dingxin Xu - */ -public class Silk_tables_NLSF_CB1_10_FLP -{ -// const SKP_float SKP_Silk_NLSF_MSVQ_CB1_10_rates[ NLSF_MSVQ_CB1_10_VECTORS ] = - static final float SKP_Silk_NLSF_MSVQ_CB1_10_rates[] = - { - 1.93750000000000000000f, 3.21875000000000000000f, - 3.75000000000000000000f, 3.96875000000000000000f, - 4.21875000000000000000f, 4.21875000000000000000f, - 4.84375000000000000000f, 5.21875000000000000000f, - 5.25000000000000000000f, 5.37500000000000000000f, - 5.40625000000000000000f, 5.50000000000000000000f, - 5.59375000000000000000f, 5.65625000000000000000f, - 5.65625000000000000000f, 5.78125000000000000000f, - 5.81250000000000000000f, 6.18750000000000000000f, - 6.21875000000000000000f, 6.34375000000000000000f, - 6.40625000000000000000f, 6.93750000000000000000f, - 7.09375000000000000000f, 7.09375000000000000000f, - 7.09375000000000000000f, 7.09375000000000000000f, - 7.09375000000000000000f, 7.09375000000000000000f, - 7.09375000000000000000f, 7.09375000000000000000f, - 7.09375000000000000000f, 7.09375000000000000000f, - 1.68750000000000000000f, 2.37500000000000000000f, - 3.15625000000000000000f, 3.37500000000000000000f, - 3.71875000000000000000f, 3.75000000000000000000f, - 3.84375000000000000000f, 3.90625000000000000000f, - 2.12500000000000000000f, 2.65625000000000000000f, - 2.71875000000000000000f, 3.21875000000000000000f, - 3.34375000000000000000f, 3.50000000000000000000f, - 3.59375000000000000000f, 3.62500000000000000000f, - 2.43750000000000000000f, 2.65625000000000000000f, - 2.65625000000000000000f, 3.15625000000000000000f, - 3.28125000000000000000f, 3.28125000000000000000f, - 3.43750000000000000000f, 3.46875000000000000000f, - 2.59375000000000000000f, 2.84375000000000000000f, - 3.03125000000000000000f, 3.03125000000000000000f, - 3.03125000000000000000f, 3.12500000000000000000f, - 3.15625000000000000000f, 3.28125000000000000000f, - 2.87500000000000000000f, 2.90625000000000000000f, - 2.90625000000000000000f, 2.96875000000000000000f, - 3.00000000000000000000f, 3.06250000000000000000f, - 3.09375000000000000000f, 3.21875000000000000000f - }; - -// const SKP_float SKP_Silk_NLSF_MSVQ_CB1_10_ndelta_min[ 10 + 1 ] = - static final float SKP_Silk_NLSF_MSVQ_CB1_10_ndelta_min[] = - { - 0.01409912109375000000f, - 0.00009155273437500000f, - 0.00195312500000000000f, - 0.00225830078125000000f, - 0.00299072265625000000f, - 0.00152587890625000000f, - 0.00296020507812500000f, - 0.00207519531250000000f, - 0.00366210937499999960f, - 0.00161743164062500000f, - 0.01950073242187500000f - }; - -// const SKP_float SKP_Silk_NLSF_MSVQ_CB1_10[ 10 * NLSF_MSVQ_CB1_10_VECTORS ] = - static final float SKP_Silk_NLSF_MSVQ_CB1_10[] = - { - 0.05728149414062500000f, 0.14178466796875000000f, - 0.23535156250000003000f, 0.32791137695312500000f, - 0.42614746093750000000f, 0.51965332031250000000f, - 0.61764526367187500000f, 0.70745849609375000000f, - 0.80783081054687511000f, 0.89376831054687500000f, - 0.04919433593750000000f, 0.10003662109375001000f, - 0.21624755859374997000f, 0.30441284179687500000f, - 0.40368652343750000000f, 0.49633789062499994000f, - 0.59802246093750000000f, 0.69244384765625011000f, - 0.79458618164062500000f, 0.88394165039062500000f, - 0.06619262695312500000f, 0.11688232421875000000f, - 0.19714355468750000000f, 0.27337646484375000000f, - 0.36499023437500000000f, 0.45013427734375000000f, - 0.56176757812500000000f, 0.66098022460937500000f, - 0.76348876953125000000f, 0.85580444335937489000f, - 0.11230468750000001000f, 0.18383789062500000000f, - 0.27423095703125000000f, 0.37402343749999994000f, - 0.46389770507812494000f, 0.55505371093750000000f, - 0.66348266601562500000f, 0.74645996093750000000f, - 0.83874511718749989000f, 0.91732788085937500000f, - 0.07885742187500000000f, 0.15829467773437500000f, - 0.23800659179687500000f, 0.33270263671874994000f, - 0.40219116210937500000f, 0.48110961914062500000f, - 0.58035278320312500000f, 0.68453979492187500000f, - 0.79013061523437500000f, 0.87579345703125000000f, - 0.11386108398437500000f, 0.17550659179687500000f, - 0.26397705078125000000f, 0.35833740234375000000f, - 0.46051025390625000000f, 0.53121948242187500000f, - 0.62228393554687500000f, 0.71475219726562500000f, - 0.80041503906250000000f, 0.89254760742187511000f, - 0.06430053710937500000f, 0.19296264648437500000f, - 0.27206420898437500000f, 0.37310791015625000000f, - 0.45089721679687500000f, 0.54293823242187500000f, - 0.63061523437500000000f, 0.72262573242187500000f, - 0.81875610351562500000f, 0.89578247070312500000f, - 0.05117797851562500000f, 0.08758544921875000000f, - 0.16436767578125000000f, 0.24649047851562500000f, - 0.36062622070312500000f, 0.46313476562500000000f, - 0.56936645507812500000f, 0.67156982421875011000f, - 0.77859497070312500000f, 0.87551879882812500000f, - 0.06442260742187500000f, 0.11062622070312501000f, - 0.21444702148437500000f, 0.32312011718750000000f, - 0.42904663085937500000f, 0.52468872070312500000f, - 0.64505004882812489000f, 0.74035644531250000000f, - 0.84158325195312500000f, 0.91662597656250011000f, - 0.07409667968750000000f, 0.12237548828125000000f, - 0.17593383789062500000f, 0.28613281250000000000f, - 0.42129516601562500000f, 0.48281860351562500000f, - 0.59338378906250000000f, 0.68325805664062511000f, - 0.77194213867187500000f, 0.89447021484375000000f, - 0.06884765625000000000f, 0.14123535156250000000f, - 0.25564575195312500000f, 0.37966918945312500000f, - 0.46640014648437500000f, 0.59393310546875000000f, - 0.67922973632812500000f, 0.77975463867187489000f, - 0.86767578124999989000f, 0.92480468750000000000f, - 0.07177734375000000000f, 0.11215209960937499000f, - 0.18704223632812500000f, 0.36218261718750000000f, - 0.44406127929687494000f, 0.50827026367187500000f, - 0.59887695312500000000f, 0.66781616210937500000f, - 0.80950927734375000000f, 0.88040161132812500000f, - 0.16000366210937500000f, 0.22119140625000000000f, - 0.32220458984375000000f, 0.40493774414062500000f, - 0.47763061523437506000f, 0.54684448242187500000f, - 0.64517211914062500000f, 0.72714233398437500000f, - 0.82708740234375000000f, 0.90084838867187489000f, - 0.13494873046875000000f, 0.20523071289062500000f, - 0.31887817382812500000f, 0.40505981445312500000f, - 0.49206542968750000000f, 0.60794067382812500000f, - 0.69659423828124989000f, 0.79531860351562500000f, - 0.87777709960937500000f, 0.93331909179687500000f, - 0.13757324218750000000f, 0.19198608398437500000f, - 0.29003906250000000000f, 0.36038208007812506000f, - 0.42196655273437500000f, 0.48675537109375000000f, - 0.58218383789062500000f, 0.67395019531250000000f, - 0.78552246093750000000f, 0.87457275390625000000f, - 0.07751464843750000000f, 0.13113403320312500000f, - 0.26181030273437500000f, 0.41436767578125000000f, - 0.50762939453125000000f, 0.58291625976562500000f, - 0.65756225585937500000f, 0.72897338867187500000f, - 0.81716918945312489000f, 0.88946533203125000000f, - 0.10305786132812501000f, 0.19403076171875003000f, - 0.31201171875000000000f, 0.44305419921875000000f, - 0.54641723632812500000f, 0.64257812500000000000f, - 0.72134399414062500000f, 0.78686523437500011000f, - 0.85940551757812500000f, 0.91885375976562500000f, - 0.12747192382812500000f, 0.18133544921875000000f, - 0.24899291992187497000f, 0.30847167968750000000f, - 0.37017822265625000000f, 0.47210693359375000000f, - 0.61618041992187500000f, 0.71185302734375000000f, - 0.81732177734375000000f, 0.89596557617187500000f, - 0.07604980468750000000f, 0.11599731445312501000f, - 0.18750000000000000000f, 0.29983520507812500000f, - 0.48828124999999994000f, 0.56979370117187500000f, - 0.63760375976562489000f, 0.72213745117187500000f, - 0.79037475585937500000f, 0.88421630859374989000f, - 0.09188842773437500000f, 0.14425659179687500000f, - 0.20855712890625000000f, 0.32058715820312500000f, - 0.38040161132812500000f, 0.44238281250000000000f, - 0.52078247070312500000f, 0.61193847656250000000f, - 0.77102661132812500000f, 0.85623168945312500000f, - 0.12661743164062500000f, 0.21963500976562500000f, - 0.37652587890625000000f, 0.46008300781249994000f, - 0.54937744140625000000f, 0.61614990234375000000f, - 0.67709350585937500000f, 0.75448608398437500000f, - 0.82650756835937500000f, 0.88882446289062511000f, - 0.09078979492187500000f, 0.13970947265625000000f, - 0.19677734375000000000f, 0.25567626953125000000f, - 0.29513549804687500000f, 0.40359497070312500000f, - 0.59515380859375000000f, 0.67984008789062500000f, - 0.79522705078125000000f, 0.88043212890625000000f, - 0.12518310546875000000f, 0.17578125000000000000f, - 0.23632812500000000000f, 0.28942871093750000000f, - 0.32788085937500000000f, 0.37561035156250000000f, - 0.44790649414062500000f, 0.59835815429687500000f, - 0.75808715820312500000f, 0.86611938476562489000f, - 0.15048217773437500000f, 0.28341674804687500000f, - 0.38076782226562500000f, 0.40878295898437500000f, - 0.41845703125000000000f, 0.43795776367187506000f, - 0.48974609375000000000f, 0.60629272460937500000f, - 0.73815917968750000000f, 0.88482666015624989000f, - 0.12637329101562500000f, 0.24008178710937500000f, - 0.40100097656250000000f, 0.54077148437500000000f, - 0.61230468750000000000f, 0.64416503906250000000f, - 0.66198730468750000000f, 0.69342041015625000000f, - 0.72436523437500000000f, 0.83767700195312500000f, - 0.12240600585937499000f, 0.26611328125000000000f, - 0.40386962890625006000f, 0.49456787109375006000f, - 0.53713989257812500000f, 0.55813598632812500000f, - 0.56530761718750000000f, 0.60086059570312500000f, - 0.70904541015625000000f, 0.85089111328125000000f, - 0.10437011718750000000f, 0.18295288085937500000f, - 0.34271240234375006000f, 0.46133422851562500000f, - 0.48544311523437500000f, 0.51217651367187500000f, - 0.54205322265625000000f, 0.71249389648437500000f, - 0.82086181640625000000f, 0.91387939453125000000f, - 0.09399414062500001400f, 0.20709228515625000000f, - 0.31936645507812506000f, 0.41735839843750000000f, - 0.55111694335937500000f, 0.72067260742187489000f, - 0.82574462890624989000f, 0.88751220703124989000f, - 0.90219116210937500000f, 0.91262817382812500000f, - 0.09271240234375000000f, 0.17150878906250003000f, - 0.28277587890625000000f, 0.39276123046875000000f, - 0.57382202148437500000f, 0.59844970703125000000f, - 0.61065673828125000000f, 0.63482666015625000000f, - 0.72882080078125011000f, 0.89434814453125000000f, - 0.10113525390625000000f, 0.19592285156250000000f, - 0.27606201171875000000f, 0.40472412109375000000f, - 0.48428344726562500000f, 0.70547485351562500000f, - 0.72225952148437500000f, 0.73898315429687500000f, - 0.74728393554687500000f, 0.79086303710937500000f, - 0.10586547851562500000f, 0.21249389648437500000f, - 0.30831909179687500000f, 0.46636962890625006000f, - 0.62655639648437500000f, 0.70922851562500000000f, - 0.76367187500000000000f, 0.79409790039062500000f, - 0.81591796875000000000f, 0.83175659179687500000f, - 0.09280395507812500000f, 0.19711303710937500000f, - 0.29837036132812500000f, 0.39355468750000000000f, - 0.49789428710937500000f, 0.59234619140625000000f, - 0.73455810546875000000f, 0.89578247070312500000f, - 0.97030639648437500000f, 0.97885131835937500000f, - -0.00610351562500000000f, -0.00408935546875000000f, - -0.00344848632812500000f, -0.00622558593750000000f, - -0.01058959960937500000f, -0.01342773437500000000f, - -0.01074218749999999800f, -0.00643920898437500000f, - -0.01275634765625000200f, -0.00524902343750000000f, - -0.00955200195312500000f, 0.00180053710937500000f, - 0.01510620117187500000f, 0.02355957031250000000f, - 0.02200317382812500000f, 0.01873779296875000000f, - 0.01019287109375000000f, 0.01354980468750000000f, - 0.00686645507812500000f, 0.00738525390625000000f, - 0.00491333007812500000f, 0.00048828125000000000f, - 0.00836181640625000000f, 0.01721191406250000000f, - -0.00222778320312500000f, -0.00573730468750000000f, - -0.01205444335937500000f, -0.00521850585937500000f, - 0.02371215820312499700f, 0.01550292968750000000f, - 0.04089355468750000000f, 0.03494262695312500000f, - 0.02133178710937500000f, 0.00598144531250000000f, - 0.00680541992187500000f, 0.00527954101562500000f, - 0.00274658203125000000f, 0.00076293945312500000f, - -0.00079345703125000011f, 0.00054931640625000000f, - 0.00405883789062500000f, -0.00320434570312500000f, - -0.01098632812500000000f, -0.00845336914062500000f, - 0.02621459960937500000f, 0.01934814453125000000f, - 0.00125122070312500000f, -0.01699829101562500000f, - -0.02343750000000000000f, -0.02825927734375000000f, - -0.01834106445312500000f, -0.03115844726562500000f, - -0.03628540039062500000f, -0.01113891601562500000f, - 0.00686645507812500000f, 0.00326538085937500000f, - 0.01141357421875000200f, -0.00152587890625000000f, - 0.01321411132812500000f, 0.01272583007812500000f, - 0.00476074218750000000f, 0.00119018554687500000f, - -0.01821899414062500000f, -0.04263305664062499300f, - -0.04864501953125000000f, -0.01806640625000000000f, - -0.01480102539062500000f, -0.00891113281250000000f, - 0.00772094726562500000f, 0.00265502929687500000f, - -0.00000000000000000000f, -0.00018310546875000000f, - -0.00076293945312500000f, -0.01052856445312500000f, - -0.00732421874999999910f, 0.00366210937499999960f, - 0.03848266601562500000f, 0.02886962890625000000f, - 0.00506591796875000090f, -0.00845336914062500000f, - 0.00735473632812500090f, 0.00509643554687500000f, - 0.00518798828125000000f, 0.01309204101562500000f, - 0.01580810546875000000f, 0.02178955078125000000f, - 0.01837158203125000000f, 0.00775146484375000000f, - 0.00408935546875000000f, 0.00280761718750000000f, - -0.00463867187500000000f, -0.00988769531250000000f, - -0.01202392578124999800f, 0.00149536132812500000f, - -0.00460815429687500000f, -0.00927734375000000000f, - -0.02209472656250000000f, -0.02005004882812500000f, - -0.00494384765625000000f, -0.01126098632812500000f, - -0.00106811523437500000f, 0.00009155273437500000f, - -0.00006103515625000000f, -0.00952148437500000000f, - -0.00610351562500000000f, -0.00280761718750000000f, - -0.00692749023437500000f, 0.00738525390625000000f, - 0.01916503906250000000f, 0.01724243164062500000f, - -0.00378417968750000000f, 0.03222656250000000000f, - 0.02349853515625000300f, 0.00308227539062500000f, - -0.00256347656250000000f, -0.00100708007812500000f, - 0.00012207031250000000f, -0.00585937500000000000f, - -0.00830078125000000000f, 0.00015258789062500000f, - -0.01913452148437500000f, -0.02981567382812500000f, - 0.01278686523437500000f, 0.01440429687500000000f, - 0.00161743164062500000f, -0.00314331054687500000f, - 0.00442504882812500000f, 0.00982666015625000000f, - -0.00289916992187500000f, -0.00094604492187500000f, - -0.00305175781250000000f, -0.00924682617187500000f, - -0.01708984375000000000f, -0.03256225585937500000f, - -0.01260375976562500000f, 0.02178955078125000000f, - 0.00863647460937500000f, 0.00006103515625000000f, - -0.00680541992187500000f, -0.01119995117187500000f, - 0.01596069335937500000f, 0.01098632812500000000f, - -0.00115966796875000000f, -0.00350952148437500040f, - 0.01153564453125000000f, -0.01803588867187500000f, - -0.02191162109375000000f, 0.01367187500000000000f, - -0.01467895507812500000f, -0.00836181640625000000f, - 0.00549316406250000000f, -0.00268554687499999960f, - -0.01773071289062500000f, -0.00479125976562500000f, - -0.02124023437500000000f, -0.03860473632812500000f, - 0.01202392578124999800f, -0.01461791992187500000f, - -0.00070190429687500000f, 0.00378417968750000000f, - -0.00131225585937500000f, 0.00057983398437500000f, - -0.00344848632812500000f, -0.00720214843750000000f, - -0.01257324218750000000f, -0.02011108398437500000f, - -0.00610351562500000000f, 0.00006103515625000000f, - -0.00210571289062500000f, -0.01043701171875000000f, - 0.00607299804687500000f, 0.00167846679687500000f, - 0.00177001953125000000f, -0.00109863281250000000f, - -0.00155639648437500000f, -0.00189208984375000000f, - 0.01547241210937500000f, 0.01547241210937500000f, - 0.01303100585937500200f, 0.01348876953125000000f, - 0.00109863281250000000f, 0.01834106445312500000f, - -0.00430297851562500000f, 0.00207519531250000000f, - 0.00836181640625000000f, 0.00836181640625000000f, - 0.00207519531250000000f, -0.00036621093750000000f, - -0.00012207031250000000f, 0.00216674804687500000f, - -0.00588989257812500000f, -0.01416015625000000000f, - -0.01296997070312499800f, -0.01168823242187499800f, - 0.01245117187500000000f, 0.00619506835937500000f, - -0.01028442382812500000f, 0.00720214843750000000f, - 0.01251220703125000000f, -0.00180053710937500000f, - -0.00076293945312500000f, -0.01040649414062499800f, - -0.01370239257812500200f, 0.00085449218750000000f, - -0.00027465820312500000f, 0.00274658203125000000f, - 0.01013183593750000200f, -0.00042724609375000000f, - -0.02761840820312499700f, 0.00292968750000000000f, - -0.01647949218750000000f, -0.00738525390625000000f, - 0.02072143554687500000f, -0.00180053710937500000f, - 0.00585937500000000000f, -0.00073242187500000000f, - 0.00183105468749999980f, -0.00662231445312500000f, - 0.00015258789062500000f, -0.00112915039062500000f, - 0.00546264648437500000f, -0.00061035156250000000f, - 0.00949096679687500000f, 0.01583862304687500000f, - 0.00836181640625000000f, 0.00219726562500000000f, - -0.00994873046875000000f, -0.03143310546875000000f, - -0.00799560546875000000f, 0.00650024414062500000f, - 0.01159667968750000000f, 0.00250244140625000000f, - 0.01000976562500000000f, 0.01254272460937500000f, - -0.01647949218750000000f, 0.01751708984375000000f, - -0.00863647460937500000f, 0.00460815429687500000f, - 0.00552368164062500000f, -0.01226806640625000000f, - -0.00848388671875000000f, -0.00732421874999999910f, - -0.00335693359375000000f, -0.00692749023437500000f, - -0.00805664062500000000f, -0.00271606445312500000f, - -0.00762939453124999910f, -0.00790405273437500000f, - -0.00082397460937500000f, 0.00323486328125000000f, - -0.00729370117187499910f, -0.00299072265625000000f, - -0.01190185546875000000f, 0.00360107421875000000f, - 0.00186157226562500000f, 0.00317382812500000040f, - 0.00897216796875000000f, 0.01623535156250000000f, - 0.00280761718750000000f, -0.00039672851562500005f, - 0.00183105468749999980f, -0.00711059570312500000f, - 0.01022338867187500000f, 0.01651000976562500000f, - 0.00936889648437500000f, -0.00079345703125000011f, - -0.00335693359375000000f, -0.00277709960937500000f, - -0.00704956054687500000f, -0.01403808593750000200f, - 0.00518798828125000000f, 0.00613403320312500000f, - 0.00292968750000000000f, -0.01135253906249999800f, - 0.00402832031250000000f, 0.01327514648437500000f, - -0.00921630859375000000f, 0.00659179687500000000f, - -0.00851440429687500000f, -0.00125122070312500000f, - 0.00225830078125000000f, 0.00579833984375000000f, - 0.01123046875000000000f, 0.00833129882812500000f, - -0.00567626953124999910f, -0.01855468750000000000f, - -0.00479125976562500000f, 0.00485229492187500000f, - 0.00036621093750000000f, 0.00848388671875000000f, - 0.00747680664062500000f, 0.00936889648437500000f, - 0.00076293945312500000f, -0.00570678710937500090f, - -0.00048828125000000000f, 0.00167846679687500000f, - 0.00091552734374999989f, -0.00497436523437500000f, - 0.01672363281250000000f, -0.00936889648437500000f, - 0.00323486328125000000f, -0.00015258789062500000f, - 0.00082397460937500000f, 0.01007080078124999800f, - -0.01269531250000000200f, 0.01449584960937500000f, - 0.01336669921875000200f, -0.00717163085937500000f, - 0.00317382812500000040f, 0.00418090820312500000f, - 0.00064086914062500000f, -0.00015258789062500000f, - -0.00915527343750000000f, -0.01428222656250000000f, - 0.01589965820312500000f, -0.01058959960937500000f, - 0.00518798828125000000f, -0.00610351562500000000f, - -0.00668334960937500090f, 0.00939941406250000000f, - -0.00372314453125000000f, -0.00405883789062500000f, - 0.00668334960937500090f, -0.00048828125000000000f, - 0.01095581054687500000f, 0.01257324218750000000f, - -0.00271606445312500000f, -0.00338745117187500000f, - 0.00146484375000000000f, 0.00982666015625000000f, - 0.00433349609375000000f, 0.00540161132812500090f, - -0.00872802734375000000f, -0.00387573242187500000f, - -0.00119018554687500000f, -0.00192260742187500000f, - -0.00128173828125000000f, -0.01376342773437500000f, - 0.00488281250000000000f, 0.00939941406250000000f, - -0.00173950195312500000f, 0.00588989257812500000f, - -0.00146484375000000000f, 0.00225830078125000000f, - -0.01055908203125000000f, 0.00180053710937500000f, - -0.00082397460937500000f, 0.00082397460937500000f, - -0.01431274414062499800f, -0.00845336914062500000f, - -0.01049804687500000000f, 0.00860595703125000000f, - 0.00799560546875000000f, 0.00372314453125000000f, - 0.00521850585937500000f, -0.00759887695312500000f, - 0.00082397460937500000f, 0.00787353515625000000f, - 0.00573730468750000000f, -0.00009155273437500000f, - 0.00204467773437500000f, -0.00628662109375000000f, - -0.00866699218750000000f, 0.00888061523437500000f, - -0.00357055664062500000f, -0.00268554687499999960f, - -0.01455688476562500000f, 0.01144409179687500000f, - 0.00152587890625000000f, 0.00323486328125000000f, - 0.00302124023437500040f, -0.00555419921875000000f, - 0.01336669921875000200f, -0.01147460937500000000f, - -0.01223754882812500000f, -0.00149536132812500000f, - 0.00363159179687500000f, -0.00070190429687500000f, - -0.00030517578125000000f, -0.00146484375000000000f, - -0.00354003906250000000f, -0.00610351562500000000f, - -0.00946044921875000000f, 0.00369262695312500000f, - 0.00222778320312500000f, 0.00021362304687500000f, - 0.00723266601562500000f, -0.00689697265625000000f, - 0.00424194335937500000f, -0.01391601562500000000f, - 0.01211547851562500000f, 0.00106811523437500000f, - 0.00009155273437500000f, -0.00329589843750000000f, - 0.00985717773437500000f, -0.00228881835937500000f, - 0.01013183593750000200f, 0.00604248046875000090f, - -0.00302124023437500040f, -0.00064086914062500000f - }; - -// const SKP_Silk_NLSF_CBS_FLP SKP_Silk_NLSF_CB1_10_Stage_info_FLP[ NLSF_MSVQ_CB1_10_STAGES ] = -// { -// { 32, &SKP_Silk_NLSF_MSVQ_CB1_10[ 10 * 0 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates[ 0 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB1_10[ 10 * 32 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates[ 32 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB1_10[ 10 * 40 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates[ 40 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB1_10[ 10 * 48 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates[ 48 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB1_10[ 10 * 56 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates[ 56 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB1_10[ 10 * 64 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates[ 64 ] } -// }; - static final SKP_Silk_NLSF_CBS_FLP SKP_Silk_NLSF_CB1_10_Stage_info_FLP[] = - { - new SKP_Silk_NLSF_CBS_FLP(32, SKP_Silk_NLSF_MSVQ_CB1_10, 10*0, SKP_Silk_NLSF_MSVQ_CB1_10_rates, 0), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB1_10, 10*32, SKP_Silk_NLSF_MSVQ_CB1_10_rates, 32), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB1_10, 10*40, SKP_Silk_NLSF_MSVQ_CB1_10_rates, 40), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB1_10, 10*48, SKP_Silk_NLSF_MSVQ_CB1_10_rates, 48), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB1_10, 10*56, SKP_Silk_NLSF_MSVQ_CB1_10_rates, 56), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB1_10, 10*64, SKP_Silk_NLSF_MSVQ_CB1_10_rates, 64), - }; - -// const SKP_Silk_NLSF_CB_FLP SKP_Silk_NLSF_CB1_10_FLP = -// { -// NLSF_MSVQ_CB1_10_STAGES, -// SKP_Silk_NLSF_CB1_10_Stage_info_FLP, -// SKP_Silk_NLSF_MSVQ_CB1_10_ndelta_min, -// SKP_Silk_NLSF_MSVQ_CB1_10_CDF, -// SKP_Silk_NLSF_MSVQ_CB1_10_CDF_start_ptr, -// SKP_Silk_NLSF_MSVQ_CB1_10_CDF_middle_idx -// }; - static final SKP_Silk_NLSF_CB_FLP SKP_Silk_NLSF_CB1_10_FLP = - new SKP_Silk_NLSF_CB_FLP( - Silk_tables_NLSF_CB1_10.NLSF_MSVQ_CB1_10_STAGES, - SKP_Silk_NLSF_CB1_10_Stage_info_FLP, - SKP_Silk_NLSF_MSVQ_CB1_10_ndelta_min, - Silk_tables_NLSF_CB1_10.SKP_Silk_NLSF_MSVQ_CB1_10_CDF, - Silk_tables_NLSF_CB1_10.SKP_Silk_NLSF_MSVQ_CB1_10_CDF_start_ptr, - Silk_tables_NLSF_CB1_10.SKP_Silk_NLSF_MSVQ_CB1_10_CDF_middle_idx - ); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB1_16.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB1_16.java deleted file mode 100644 index 12fedaf43..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB1_16.java +++ /dev/null @@ -1,708 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * This file has been automatically generated - * ROM usage: 0.29 + 3.57 kB. - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_tables_NLSF_CB1_16 -{ - static final int NLSF_MSVQ_CB1_16_STAGES = 10; - static final int NLSF_MSVQ_CB1_16_VECTORS = 104; - - static final int[] SKP_Silk_NLSF_MSVQ_CB1_16_CDF = - { - 0, - 19099, - 26957, - 30639, - 34242, - 37546, - 40447, - 43287, - 46005, - 48445, - 49865, - 51284, - 52673, - 53975, - 55221, - 56441, - 57267, - 58025, - 58648, - 59232, - 59768, - 60248, - 60729, - 61210, - 61690, - 62171, - 62651, - 63132, - 63613, - 64093, - 64574, - 65054, - 65535, - 0, - 28808, - 38775, - 46801, - 51785, - 55886, - 59410, - 62572, - 65535, - 0, - 27376, - 38639, - 45052, - 51465, - 55448, - 59021, - 62594, - 65535, - 0, - 33403, - 39569, - 45102, - 49961, - 54047, - 57959, - 61788, - 65535, - 0, - 25851, - 43356, - 47828, - 52204, - 55964, - 59413, - 62507, - 65535, - 0, - 34277, - 40337, - 45432, - 50311, - 54326, - 58171, - 61853, - 65535, - 0, - 33538, - 39865, - 45302, - 50076, - 54549, - 58478, - 62159, - 65535, - 0, - 27445, - 35258, - 40665, - 46072, - 51362, - 56540, - 61086, - 65535, - 0, - 22080, - 30779, - 37065, - 43085, - 48849, - 54613, - 60133, - 65535, - 0, - 13417, - 21748, - 30078, - 38231, - 46383, - 53091, - 59515, - 65535 - }; - static private int [] SKP_Silk_NLSF_MSVQ_CB1_16_CDF_0 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB1_16_CDF, 0, SKP_Silk_NLSF_MSVQ_CB1_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB1_16_CDF_33 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB1_16_CDF, 33, SKP_Silk_NLSF_MSVQ_CB1_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB1_16_CDF_42 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB1_16_CDF, 42, SKP_Silk_NLSF_MSVQ_CB1_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB1_16_CDF_51 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB1_16_CDF, 51, SKP_Silk_NLSF_MSVQ_CB1_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB1_16_CDF_60 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB1_16_CDF, 60, SKP_Silk_NLSF_MSVQ_CB1_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB1_16_CDF_69 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB1_16_CDF, 69, SKP_Silk_NLSF_MSVQ_CB1_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB1_16_CDF_78 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB1_16_CDF, 78, SKP_Silk_NLSF_MSVQ_CB1_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB1_16_CDF_87 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB1_16_CDF, 87, SKP_Silk_NLSF_MSVQ_CB1_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB1_16_CDF_96 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB1_16_CDF, 96, SKP_Silk_NLSF_MSVQ_CB1_16_CDF.length); - static private int [] SKP_Silk_NLSF_MSVQ_CB1_16_CDF_105 - = Silk_tables.copyOfRange(SKP_Silk_NLSF_MSVQ_CB1_16_CDF, 105, SKP_Silk_NLSF_MSVQ_CB1_16_CDF.length); - - static final int[][] SKP_Silk_NLSF_MSVQ_CB1_16_CDF_start_ptr = - { - SKP_Silk_NLSF_MSVQ_CB1_16_CDF_0 , - SKP_Silk_NLSF_MSVQ_CB1_16_CDF_33 , - SKP_Silk_NLSF_MSVQ_CB1_16_CDF_42 , - SKP_Silk_NLSF_MSVQ_CB1_16_CDF_51 , - SKP_Silk_NLSF_MSVQ_CB1_16_CDF_60 , - SKP_Silk_NLSF_MSVQ_CB1_16_CDF_69 , - SKP_Silk_NLSF_MSVQ_CB1_16_CDF_78 , - SKP_Silk_NLSF_MSVQ_CB1_16_CDF_87 , - SKP_Silk_NLSF_MSVQ_CB1_16_CDF_96 , - SKP_Silk_NLSF_MSVQ_CB1_16_CDF_105 - }; - - static final int[] SKP_Silk_NLSF_MSVQ_CB1_16_CDF_middle_idx = - { - 5, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 3, - 4 - }; - - static final short[] SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5 = - { - 57, 98, - 133, 134, - 138, 144, - 145, 147, - 152, 177, - 177, 178, - 181, 183, - 184, 202, - 206, 215, - 218, 222, - 227, 227, - 227, 227, - 227, 227, - 227, 227, - 227, 227, - 227, 227, - 38, 87, - 97, 119, - 128, 135, - 140, 143, - 40, 81, - 107, 107, - 129, 134, - 134, 143, - 31, 109, - 114, 120, - 128, 130, - 131, 132, - 43, 61, - 124, 125, - 132, 136, - 141, 142, - 30, 110, - 118, 120, - 129, 131, - 133, 133, - 31, 108, - 115, 121, - 124, 130, - 133, 137, - 40, 98, - 115, 115, - 116, 117, - 123, 124, - 50, 93, - 108, 110, - 112, 112, - 114, 115, - 73, 95, - 95, 96, - 96, 105, - 107, 110 - }; - - static final int[] SKP_Silk_NLSF_MSVQ_CB1_16_ndelta_min_Q15 = - { - 148, - 3, - 60, - 68, - 117, - 86, - 121, - 124, - 152, - 153, - 207, - 151, - 225, - 239, - 126, - 183, - 792 - }; - - static final short[] SKP_Silk_NLSF_MSVQ_CB1_16_Q15 = - { - 1309, 3060, 5071, 6996, - 9028, 10938, 12934, 14891, - 16933, 18854, 20792, 22764, - 24753, 26659, 28626, 30501, - 1264, 2745, 4610, 6408, - 8286, 10043, 12084, 14108, - 16118, 18163, 20095, 22164, - 24264, 26316, 28329, 30251, - 1044, 2080, 3672, 5179, - 7140, 9100, 11070, 13065, - 15423, 17790, 19931, 22101, - 24290, 26361, 28499, 30418, - 1131, 2476, 4478, 6149, - 7902, 9875, 11938, 13809, - 15869, 17730, 19948, 21707, - 23761, 25535, 27426, 28917, - 1040, 2004, 4026, 6100, - 8432, 10494, 12610, 14694, - 16797, 18775, 20799, 22782, - 24772, 26682, 28631, 30516, - 2310, 3812, 5913, 7933, - 10033, 11881, 13885, 15798, - 17751, 19576, 21482, 23276, - 25157, 27010, 28833, 30623, - 1254, 2847, 5013, 6781, - 8626, 10370, 12726, 14633, - 16281, 17852, 19870, 21472, - 23002, 24629, 26710, 27960, - 1468, 3059, 4987, 7026, - 8741, 10412, 12281, 14020, - 15970, 17723, 19640, 21522, - 23472, 25661, 27986, 30225, - 2171, 3566, 5605, 7384, - 9404, 11220, 13030, 14758, - 16687, 18417, 20346, 22091, - 24055, 26212, 28356, 30397, - 2409, 4676, 7543, 9786, - 11419, 12935, 14368, 15653, - 17366, 18943, 20762, 22477, - 24440, 26327, 28284, 30242, - 2354, 4222, 6820, 9107, - 11596, 13934, 15973, 17682, - 19158, 20517, 21991, 23420, - 25178, 26936, 28794, 30527, - 1323, 2414, 4184, 6039, - 7534, 9398, 11099, 13097, - 14799, 16451, 18434, 20887, - 23490, 25838, 28046, 30225, - 1361, 3243, 6048, 8511, - 11001, 13145, 15073, 16608, - 18126, 19381, 20912, 22607, - 24660, 26668, 28663, 30566, - 1216, 2648, 5901, 8422, - 10037, 11425, 12973, 14603, - 16686, 18600, 20555, 22415, - 24450, 26280, 28206, 30077, - 2417, 4048, 6316, 8433, - 10510, 12757, 15072, 17295, - 19573, 21503, 23329, 24782, - 26235, 27689, 29214, 30819, - 1012, 2345, 4991, 7377, - 9465, 11916, 14296, 16566, - 18672, 20544, 22292, 23838, - 25415, 27050, 28848, 30551, - 1937, 3693, 6267, 8019, - 10372, 12194, 14287, 15657, - 17431, 18864, 20769, 22206, - 24037, 25463, 27383, 28602, - 1969, 3305, 5017, 6726, - 8375, 9993, 11634, 13280, - 15078, 16751, 18464, 20119, - 21959, 23858, 26224, 29298, - 1198, 2647, 5428, 7423, - 9775, 12155, 14665, 16344, - 18121, 19790, 21557, 22847, - 24484, 25742, 27639, 28711, - 1636, 3353, 5447, 7597, - 9837, 11647, 13964, 16019, - 17862, 20116, 22319, 24037, - 25966, 28086, 29914, 31294, - 2676, 4105, 6378, 8223, - 10058, 11549, 13072, 14453, - 15956, 17355, 18931, 20402, - 22183, 23884, 25717, 27723, - 1373, 2593, 4449, 5633, - 7300, 8425, 9474, 10818, - 12769, 15722, 19002, 21429, - 23682, 25924, 28135, 30333, - 1596, 3183, 5378, 7164, - 8670, 10105, 11470, 12834, - 13991, 15042, 16642, 17903, - 20759, 25283, 27770, 30240, - 2037, 3987, 6237, 8117, - 9954, 12245, 14217, 15892, - 17775, 20114, 22314, 25942, - 26305, 26483, 26796, 28561, - 2181, 3858, 5760, 7924, - 10041, 11577, 13769, 15700, - 17429, 19879, 23583, 24538, - 25212, 25693, 28688, 30507, - 1992, 3882, 6474, 7883, - 9381, 12672, 14340, 15701, - 16658, 17832, 20850, 22885, - 24677, 26457, 28491, 30460, - 2391, 3988, 5448, 7432, - 11014, 12579, 13140, 14146, - 15898, 18592, 21104, 22993, - 24673, 27186, 28142, 29612, - 1713, 5102, 6989, 7798, - 8670, 10110, 12746, 14881, - 16709, 18407, 20126, 22107, - 24181, 26198, 28237, 30137, - 1612, 3617, 6148, 8359, - 9576, 11528, 14936, 17809, - 18287, 18729, 19001, 21111, - 24631, 26596, 28740, 30643, - 2266, 4168, 7862, 9546, - 9618, 9703, 10134, 13897, - 16265, 18432, 20587, 22605, - 24754, 26994, 29125, 30840, - 1840, 3917, 6272, 7809, - 9714, 11438, 13767, 15799, - 19244, 21972, 22980, 23180, - 23723, 25650, 29117, 31085, - 1458, 3612, 6008, 7488, - 9827, 11893, 14086, 15734, - 17440, 19535, 22424, 24767, - 29246, 29928, 30516, 30947, - -102, -121, -31, -6, - 5, -2, 8, -18, - -4, 6, 14, -2, - -12, -16, -12, -60, - -126, -353, -574, -677, - -657, -617, -498, -393, - -348, -277, -225, -164, - -102, -70, -31, 33, - 4, 379, 387, 551, - 605, 620, 532, 482, - 442, 454, 385, 347, - 322, 299, 266, 200, - 1168, 951, 672, 246, - 60, -161, -259, -234, - -253, -282, -203, -187, - -155, -176, -198, -178, - 10, 170, 393, 609, - 555, 208, -330, -571, - -769, -633, -319, -43, - 95, 105, 106, 116, - -152, -140, -125, 5, - 173, 274, 264, 331, - -37, -293, -609, -786, - -959, -814, -645, -238, - -91, 36, -11, -101, - -279, -227, -40, 90, - 530, 677, 890, 1104, - 999, 835, 564, 295, - -280, -364, -340, -331, - -284, 288, 761, 880, - 988, 627, 146, -226, - -203, -181, -142, 39, - 24, -26, -107, -92, - -161, -135, -131, -88, - -160, -156, -75, -43, - -36, -6, -33, 33, - -324, -415, -108, 124, - 157, 191, 203, 197, - 144, 109, 152, 176, - 190, 122, 101, 159, - 663, 668, 480, 400, - 379, 444, 446, 458, - 343, 351, 310, 228, - 133, 44, 75, 63, - -84, 39, -29, 35, - -94, -233, -261, -354, - 77, 262, -24, -145, - -333, -409, -404, -597, - -488, -300, 910, 592, - 412, 120, 130, -51, - -37, -77, -172, -181, - -159, -148, -72, -62, - 510, 516, 113, -585, - -1075, -957, -417, -195, - 9, 7, -88, -173, - -91, 54, 98, 95, - -28, 197, -527, -621, - 157, 122, -168, 147, - 309, 300, 336, 315, - 396, 408, 376, 106, - -162, -170, -315, 98, - 821, 908, 570, -33, - -312, -568, -572, -378, - -107, 23, 156, 93, - -129, -87, 20, -72, - -37, 40, 21, 27, - 48, 75, 77, 65, - 46, 71, 66, 47, - 136, 344, 236, 322, - 170, 283, 269, 291, - 162, -43, -204, -259, - -240, -305, -350, -312, - 447, 348, 345, 257, - 71, -131, -77, -190, - -202, -40, 35, 133, - 261, 365, 438, 303, - -8, 22, 140, 137, - -300, -641, -764, -268, - -23, -25, 73, -162, - -150, -212, -72, 6, - 39, 78, 104, -93, - -308, -136, 117, -71, - -513, -820, -700, -450, - -161, -23, 29, 78, - 337, 106, -406, -782, - -112, 233, 383, 62, - -126, 6, -77, -29, - -146, -123, -51, -27, - -27, -381, -641, 402, - 539, 8, -207, -366, - -36, -27, -204, -227, - -237, -189, -64, 51, - -92, -137, -281, 62, - 233, 92, 148, 294, - 363, 416, 564, 625, - 370, -36, -469, -462, - 102, 168, 32, 117, - -21, 97, 139, 89, - 104, 35, 4, 82, - 66, 58, 73, 93, - -76, -320, -236, -189, - -203, -142, -27, -73, - 9, -9, -25, 12, - -15, 4, 4, -50, - 314, 180, 162, -49, - 199, -108, -227, -66, - -447, -67, -264, -394, - 5, 55, -133, -176, - -116, -241, 272, 109, - 282, 262, 192, -64, - -392, -514, 156, 203, - 154, 72, -34, -160, - -73, 3, -33, -431, - 321, 18, -567, -590, - -108, 88, 66, 51, - -31, -193, -46, 65, - -29, -23, 215, -31, - 101, -113, 32, 304, - 88, 320, 448, 5, - -439, -562, -508, -135, - -13, -171, -8, 182, - -99, -181, -149, 376, - 476, 64, -396, -652, - -150, 176, 222, 65, - -590, 719, 271, 399, - 245, 72, -156, -152, - -176, 59, 94, 125, - -9, -7, 9, 1, - -61, -116, -82, 1, - 79, 22, -44, -15, - -48, -65, -62, -101, - -102, -54, -70, -78, - -80, -25, 398, 71, - 139, 38, 90, 194, - 222, 249, 165, 94, - 221, 262, 163, 91, - -206, 573, 200, -287, - -147, 5, -18, -85, - -74, -125, -87, 85, - 141, 4, -4, 28, - 234, 48, -150, -111, - -506, 237, -209, 345, - 94, -124, 77, 121, - 143, 12, -80, -48, - 191, 144, -93, -65, - -151, -643, 435, 106, - 87, 7, 65, 102, - 94, 68, 5, 99, - 222, 93, 94, 355, - -13, -89, -228, -503, - 287, 109, 108, 449, - 253, -29, -109, -116, - 15, -73, -20, 131, - -147, 72, 59, -150, - -594, 273, 316, 132, - 199, 106, 198, 212, - 220, 82, 45, -13, - 223, 137, 270, 38, - 252, 135, -177, -207, - -360, -102, 403, 406, - -14, 83, 64, 51, - -7, -99, -97, -88, - -124, -65, 42, 32, - 28, 29, 12, 20, - 119, -26, -212, -201, - 373, 251, 141, 103, - 36, -52, 66, 18, - -6, -95, -196, 5, - 98, -85, -108, 218, - -164, 20, 356, 172, - 37, 266, 23, 112, - -24, -99, -92, -178, - 29, -278, 388, -60, - -220, 300, -13, 154, - 191, 15, -37, -110, - -153, -150, -114, -7, - -94, -31, -62, -177, - 4, -70, 35, 453, - 147, -247, -328, 101, - 20, -114, 147, 108, - -119, -109, -102, -238, - 55, -102, 173, -89, - 129, 138, -330, -160, - 485, 154, -59, -170, - -20, -34, -261, -40, - -129, 77, -84, 69, - 83, 160, 169, 63, - -516, 30, 336, 52, - -0, -52, -124, 158, - 19, 197, -10, -375, - 405, 285, 114, -395, - -47, 196, 62, 87, - -106, -65, -75, -69, - -13, 34, 99, 59, - 83, 98, 44, 0, - 24, 18, 17, 70, - -22, 194, 208, 144, - -79, -15, 32, -104, - -28, -105, -186, -212, - -228, -79, -76, 51, - -71, 72, 118, -34, - -3, -171, 5, 2, - -108, -125, 62, -58, - 58, -121, 73, -466, - 92, 63, -94, -78, - -76, 212, 36, -225, - -71, -354, 152, 143, - -79, -246, -51, -31, - -6, -270, 240, 210, - 30, -157, -231, 74, - -146, 88, -273, 156, - 92, 56, 71, 2, - 318, 164, 32, -110, - -35, -41, -95, -106, - 11, 132, -68, 55, - 123, -83, -149, 212, - 132, 0, -194, 55, - 206, -108, -353, 289, - -195, 1, 233, -22, - -60, 20, 26, 68, - 166, 27, -58, 130, - 112, 107, 27, -165, - 115, -93, -37, 38, - 83, 483, 65, -229, - -13, 157, 85, 50, - 136, 10, 32, 83, - 82, 55, 5, -9, - -52, -78, -81, -51, - 40, 18, -127, -224, - -41, 53, -210, -113, - 24, -17, -187, -89, - 8, 121, 83, 77, - 91, -74, -35, -112, - -161, -173, 102, 132, - -125, -61, 103, -260, - 52, 166, -32, -156, - -87, -56, 60, -70, - -124, 242, 114, -251, - -166, 201, 127, 28, - -11, 23, -80, -115, - -20, -51, -348, 340, - -34, 133, 13, 92, - -124, -136, -120, -26, - -6, 17, 28, 21, - 120, -168, 160, -35, - 115, 28, 9, 7, - -56, 39, 156, 256, - -18, 1, 277, 82, - -70, -144, -88, -13, - -59, -157, 8, -134, - 21, -40, 58, -21, - 194, -276, 97, 279, - -56, -140, 125, 57, - -184, -204, -70, -2, - 128, -202, -78, 230, - -23, 161, -102, 1, - 1, 180, -31, -86, - -167, -57, -60, 27, - -13, 99, 108, 111, - 76, 69, 34, -21, - 53, 38, 34, 78, - 73, 219, 51, 15, - -72, -103, -207, 30, - 213, -14, 31, -94, - -40, -144, 67, 4, - 105, 59, -240, 25, - 244, 69, 58, 23, - -24, -5, -15, -133, - -71, -67, 181, 29, - -45, 121, 96, 51, - -72, -53, 56, -153, - -27, 85, 183, 211, - 105, -34, -46, 43, - -72, -93, 36, -128, - 29, 111, -95, -156, - -179, -235, 21, -39, - -71, -33, -61, -252, - 230, -131, 157, -21, - -85, -28, -123, 80, - -160, 63, 47, -6, - -49, -96, -19, 17, - -58, 17, -0, -13, - -170, 25, -35, 59, - 10, -31, -413, 81, - 62, 18, -164, 245, - 92, -165, 42, 26, - 126, -248, 193, -55, - 16, 39, 14, 50 - }; - - static final SKP_Silk_NLSF_CBS[] SKP_Silk_NLSF_CB1_16_Stage_info = - { - new SKP_Silk_NLSF_CBS(32, SKP_Silk_NLSF_MSVQ_CB1_16_Q15, 16 * 0, SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5, 0), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB1_16_Q15, 16 * 32, SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5, 32), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB1_16_Q15, 16 * 40, SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5, 40), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB1_16_Q15, 16 * 48, SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5, 48), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB1_16_Q15, 16 * 56, SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5, 56), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB1_16_Q15, 16 * 64, SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5, 64), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB1_16_Q15, 16 * 72, SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5, 72), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB1_16_Q15, 16 * 80, SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5, 80), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB1_16_Q15, 16 * 88, SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5, 88), - new SKP_Silk_NLSF_CBS(8, SKP_Silk_NLSF_MSVQ_CB1_16_Q15, 16 * 96, SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5, 96), - }; - - static final SKP_Silk_NLSF_CB_struct SKP_Silk_NLSF_CB1_16 = - new SKP_Silk_NLSF_CB_struct - ( - NLSF_MSVQ_CB1_16_STAGES, - SKP_Silk_NLSF_CB1_16_Stage_info, - SKP_Silk_NLSF_MSVQ_CB1_16_ndelta_min_Q15, - SKP_Silk_NLSF_MSVQ_CB1_16_CDF, - SKP_Silk_NLSF_MSVQ_CB1_16_CDF_start_ptr, - SKP_Silk_NLSF_MSVQ_CB1_16_CDF_middle_idx - ); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB1_16_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB1_16_FLP.java deleted file mode 100644 index 089d98bc7..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_NLSF_CB1_16_FLP.java +++ /dev/null @@ -1,979 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * This file has been automatically generated. - * ROM usage: 7.14 kB - * - * @author Dingxin Xu - */ -public class Silk_tables_NLSF_CB1_16_FLP -{ -// const SKP_float SKP_Silk_NLSF_MSVQ_CB1_16_rates[ NLSF_MSVQ_CB1_16_VECTORS ] = - static final float SKP_Silk_NLSF_MSVQ_CB1_16_rates[] = - { - 1.78125000000000000000f, 3.06250000000000000000f, - 4.15625000000000000000f, 4.18750000000000000000f, - 4.31250000000000000000f, 4.50000000000000000000f, - 4.53125000000000000000f, 4.59375000000000000000f, - 4.75000000000000000000f, 5.53125000000000000000f, - 5.53125000000000000000f, 5.56250000000000000000f, - 5.65625000000000000000f, 5.71875000000000000000f, - 5.75000000000000000000f, 6.31250000000000000000f, - 6.43750000000000000000f, 6.71875000000000000000f, - 6.81250000000000000000f, 6.93750000000000000000f, - 7.09375000000000000000f, 7.09375000000000000000f, - 7.09375000000000000000f, 7.09375000000000000000f, - 7.09375000000000000000f, 7.09375000000000000000f, - 7.09375000000000000000f, 7.09375000000000000000f, - 7.09375000000000000000f, 7.09375000000000000000f, - 7.09375000000000000000f, 7.09375000000000000000f, - 1.18750000000000000000f, 2.71875000000000000000f, - 3.03125000000000000000f, 3.71875000000000000000f, - 4.00000000000000000000f, 4.21875000000000000000f, - 4.37500000000000000000f, 4.46875000000000000000f, - 1.25000000000000000000f, 2.53125000000000000000f, - 3.34375000000000000000f, 3.34375000000000000000f, - 4.03125000000000000000f, 4.18750000000000000000f, - 4.18750000000000000000f, 4.46875000000000000000f, - 0.96875000000000000000f, 3.40625000000000000000f, - 3.56250000000000000000f, 3.75000000000000000000f, - 4.00000000000000000000f, 4.06250000000000000000f, - 4.09375000000000000000f, 4.12500000000000000000f, - 1.34375000000000000000f, 1.90625000000000000000f, - 3.87500000000000000000f, 3.90625000000000000000f, - 4.12500000000000000000f, 4.25000000000000000000f, - 4.40625000000000000000f, 4.43750000000000000000f, - 0.93750000000000000000f, 3.43750000000000000000f, - 3.68750000000000000000f, 3.75000000000000000000f, - 4.03125000000000000000f, 4.09375000000000000000f, - 4.15625000000000000000f, 4.15625000000000000000f, - 0.96875000000000000000f, 3.37500000000000000000f, - 3.59375000000000000000f, 3.78125000000000000000f, - 3.87500000000000000000f, 4.06250000000000000000f, - 4.15625000000000000000f, 4.28125000000000000000f, - 1.25000000000000000000f, 3.06250000000000000000f, - 3.59375000000000000000f, 3.59375000000000000000f, - 3.62500000000000000000f, 3.65625000000000000000f, - 3.84375000000000000000f, 3.87500000000000000000f, - 1.56250000000000000000f, 2.90625000000000000000f, - 3.37500000000000000000f, 3.43750000000000000000f, - 3.50000000000000000000f, 3.50000000000000000000f, - 3.56250000000000000000f, 3.59375000000000000000f, - 2.28125000000000000000f, 2.96875000000000000000f, - 2.96875000000000000000f, 3.00000000000000000000f, - 3.00000000000000000000f, 3.28125000000000000000f, - 3.34375000000000000000f, 3.43750000000000000000f - }; - -// const SKP_float SKP_Silk_NLSF_MSVQ_CB1_16_ndelta_min[ 16 + 1 ] = - static final float SKP_Silk_NLSF_MSVQ_CB1_16_ndelta_min[] = - { - 0.00451660156250000000f, - 0.00009155273437500000f, - 0.00183105468749999980f, - 0.00207519531250000000f, - 0.00357055664062500000f, - 0.00262451171875000000f, - 0.00369262695312500000f, - 0.00378417968750000000f, - 0.00463867187500000000f, - 0.00466918945312500000f, - 0.00631713867187499910f, - 0.00460815429687500000f, - 0.00686645507812500000f, - 0.00729370117187499910f, - 0.00384521484375000000f, - 0.00558471679687500000f, - 0.02416992187500000300f - }; - -// const SKP_float SKP_Silk_NLSF_MSVQ_CB1_16[ 16 * NLSF_MSVQ_CB1_16_VECTORS ] = - static final float SKP_Silk_NLSF_MSVQ_CB1_16[] = - { - 0.03994750976562499300f, 0.09338378906250000000f, - 0.15475463867187500000f, 0.21350097656250000000f, - 0.27551269531250000000f, 0.33380126953125000000f, - 0.39471435546875000000f, 0.45443725585937500000f, - 0.51675415039062500000f, 0.57537841796875000000f, - 0.63452148437500000000f, 0.69470214843750000000f, - 0.75540161132812500000f, 0.81356811523437500000f, - 0.87359619140625000000f, 0.93081665039062500000f, - 0.03857421875000000000f, 0.08377075195312498600f, - 0.14068603515625000000f, 0.19555664062500000000f, - 0.25286865234375000000f, 0.30648803710937500000f, - 0.36877441406250000000f, 0.43054199218750000000f, - 0.49188232421875006000f, 0.55429077148437500000f, - 0.61325073242187500000f, 0.67639160156250000000f, - 0.74047851562500000000f, 0.80310058593750000000f, - 0.86453247070312500000f, 0.92318725585937500000f, - 0.03186035156250000000f, 0.06347656250000000000f, - 0.11206054687500000000f, 0.15805053710937500000f, - 0.21789550781250003000f, 0.27770996093750000000f, - 0.33782958984375000000f, 0.39871215820312494000f, - 0.47067260742187500000f, 0.54290771484375000000f, - 0.60824584960937500000f, 0.67446899414062500000f, - 0.74127197265625000000f, 0.80447387695312500000f, - 0.86972045898437500000f, 0.92828369140625000000f, - 0.03451538085937500000f, 0.07556152343750000000f, - 0.13665771484375000000f, 0.18765258789062500000f, - 0.24114990234375000000f, 0.30136108398437500000f, - 0.36431884765624994000f, 0.42141723632812500000f, - 0.48428344726562500000f, 0.54107666015625000000f, - 0.60876464843750000000f, 0.66244506835937500000f, - 0.72512817382812500000f, 0.77926635742187500000f, - 0.83697509765625000000f, 0.88247680664062500000f, - 0.03173828125000000000f, 0.06115722656250000000f, - 0.12286376953125000000f, 0.18615722656250000000f, - 0.25732421875000000000f, 0.32025146484375000000f, - 0.38482666015625000000f, 0.44842529296875000000f, - 0.51260375976562500000f, 0.57296752929687500000f, - 0.63473510742187500000f, 0.69525146484375000000f, - 0.75598144531250000000f, 0.81427001953125000000f, - 0.87374877929687511000f, 0.93127441406250000000f, - 0.07049560546875000000f, 0.11633300781250001000f, - 0.18045043945312497000f, 0.24209594726562500000f, - 0.30618286132812500000f, 0.36257934570312500000f, - 0.42373657226562500000f, 0.48211669921875000000f, - 0.54171752929687500000f, 0.59741210937500000000f, - 0.65557861328125000000f, 0.71032714843750000000f, - 0.76773071289062500000f, 0.82427978515624989000f, - 0.87991333007812500000f, 0.93453979492187500000f, - 0.03826904296875000000f, 0.08688354492187500000f, - 0.15298461914062500000f, 0.20693969726562500000f, - 0.26324462890625000000f, 0.31646728515625000000f, - 0.38836669921875000000f, 0.44656372070312500000f, - 0.49685668945312494000f, 0.54479980468750000000f, - 0.60638427734375000000f, 0.65527343749999989000f, - 0.70196533203124989000f, 0.75161743164062500000f, - 0.81512451171875000000f, 0.85327148437500000000f, - 0.04479980468750000000f, 0.09335327148437500000f, - 0.15219116210937500000f, 0.21441650390625000000f, - 0.26675415039062500000f, 0.31774902343750000000f, - 0.37478637695312500000f, 0.42785644531250000000f, - 0.48736572265625000000f, 0.54086303710937500000f, - 0.59936523437500000000f, 0.65679931640625000000f, - 0.71630859375000000000f, 0.78311157226562500000f, - 0.85406494140625000000f, 0.92239379882812500000f, - 0.06625366210937500000f, 0.10882568359375000000f, - 0.17105102539062497000f, 0.22534179687500000000f, - 0.28698730468750000000f, 0.34240722656249994000f, - 0.39764404296875000000f, 0.45037841796875000000f, - 0.50924682617187500000f, 0.56204223632812500000f, - 0.62091064453125000000f, 0.67416381835937511000f, - 0.73410034179687489000f, 0.79992675781250000000f, - 0.86535644531250000000f, 0.92764282226562500000f, - 0.07351684570312500000f, 0.14270019531250000000f, - 0.23019409179687497000f, 0.29864501953125000000f, - 0.34848022460937500000f, 0.39474487304687500000f, - 0.43847656250000006000f, 0.47769165039062500000f, - 0.52996826171875000000f, 0.57809448242187500000f, - 0.63360595703125000000f, 0.68594360351562511000f, - 0.74584960937500000000f, 0.80343627929687500000f, - 0.86315917968750000000f, 0.92291259765625000000f, - 0.07183837890625000000f, 0.12884521484375000000f, - 0.20812988281250003000f, 0.27792358398437500000f, - 0.35388183593749994000f, 0.42523193359375000000f, - 0.48745727539062494000f, 0.53961181640625000000f, - 0.58465576171875000000f, 0.62612915039062500000f, - 0.67111206054687500000f, 0.71472167968750000000f, - 0.76837158203125000000f, 0.82202148437499989000f, - 0.87872314453125000000f, 0.93161010742187511000f, - 0.04037475585937500000f, 0.07366943359375000000f, - 0.12768554687500000000f, 0.18429565429687500000f, - 0.22991943359375000000f, 0.28680419921875000000f, - 0.33871459960937500000f, 0.39968872070312500000f, - 0.45162963867187500000f, 0.50204467773437500000f, - 0.56256103515625000000f, 0.63742065429687500000f, - 0.71685791015624989000f, 0.78851318359375011000f, - 0.85589599609374989000f, 0.92239379882812500000f, - 0.04153442382812500700f, 0.09896850585937500000f, - 0.18457031250000000000f, 0.25973510742187500000f, - 0.33572387695312500000f, 0.40115356445312500000f, - 0.45999145507812500000f, 0.50683593750000000000f, - 0.55316162109375000000f, 0.59146118164062500000f, - 0.63818359375000000000f, 0.68991088867187500000f, - 0.75256347656250011000f, 0.81384277343750000000f, - 0.87472534179687500000f, 0.93280029296875000000f, - 0.03710937500000000000f, 0.08081054687500000000f, - 0.18008422851562503000f, 0.25701904296875000000f, - 0.30630493164062500000f, 0.34866333007812500000f, - 0.39590454101562500000f, 0.44564819335937500000f, - 0.50921630859375000000f, 0.56762695312500000000f, - 0.62728881835937500000f, 0.68405151367187500000f, - 0.74615478515625000000f, 0.80200195312500000000f, - 0.86077880859375000000f, 0.91787719726562500000f, - 0.07376098632812500000f, 0.12353515625000000000f, - 0.19274902343750000000f, 0.25735473632812500000f, - 0.32073974609375000000f, 0.38931274414062494000f, - 0.45996093750000006000f, 0.52780151367187500000f, - 0.59732055664062500000f, 0.65621948242187489000f, - 0.71194458007812500000f, 0.75628662109375011000f, - 0.80062866210937489000f, 0.84500122070312500000f, - 0.89154052734375000000f, 0.94052124023437500000f, - 0.03088378906250000000f, 0.07156372070312500000f, - 0.15231323242187500000f, 0.22512817382812503000f, - 0.28884887695312500000f, 0.36364746093750000000f, - 0.43627929687500000000f, 0.50555419921875000000f, - 0.56982421875000000000f, 0.62695312500000000000f, - 0.68029785156250000000f, 0.72747802734375000000f, - 0.77560424804687511000f, 0.82550048828125011000f, - 0.88037109375000000000f, 0.93234252929687500000f, - 0.05911254882812500000f, 0.11270141601562500000f, - 0.19125366210937500000f, 0.24472045898437500000f, - 0.31652832031250000000f, 0.37213134765625000000f, - 0.43600463867187494000f, 0.47781372070312500000f, - 0.53195190429687500000f, 0.57568359375000000000f, - 0.63381958007812500000f, 0.67767333984375000000f, - 0.73355102539062500000f, 0.77706909179687489000f, - 0.83566284179687500000f, 0.87286376953125000000f, - 0.06008911132812500000f, 0.10086059570312500000f, - 0.15310668945312500000f, 0.20526123046875000000f, - 0.25558471679687500000f, 0.30496215820312500000f, - 0.35504150390625000000f, 0.40527343750000000000f, - 0.46014404296875000000f, 0.51119995117187500000f, - 0.56347656250000000000f, 0.61398315429687500000f, - 0.67013549804687500000f, 0.72808837890625000000f, - 0.80029296875000011000f, 0.89410400390625011000f, - 0.03656005859375000000f, 0.08078002929687500000f, - 0.16564941406250000000f, 0.22653198242187500000f, - 0.29830932617187500000f, 0.37094116210937500000f, - 0.44754028320312500000f, 0.49877929687500000000f, - 0.55300903320312500000f, 0.60394287109375000000f, - 0.65786743164062489000f, 0.69723510742187500000f, - 0.74719238281250011000f, 0.78558349609375000000f, - 0.84347534179687500000f, 0.87619018554687500000f, - 0.04992675781250000000f, 0.10232543945312500000f, - 0.16622924804687500000f, 0.23184204101562503000f, - 0.30020141601562500000f, 0.35543823242187500000f, - 0.42614746093750000000f, 0.48886108398437500000f, - 0.54510498046875000000f, 0.61389160156250000000f, - 0.68112182617187500000f, 0.73355102539062500000f, - 0.79241943359375000000f, 0.85711669921875011000f, - 0.91290283203125011000f, 0.95501708984375000000f, - 0.08166503906250000000f, 0.12527465820312500000f, - 0.19464111328125000000f, 0.25094604492187500000f, - 0.30694580078125000000f, 0.35244750976562500000f, - 0.39892578124999994000f, 0.44107055664062494000f, - 0.48693847656249994000f, 0.52963256835937500000f, - 0.57772827148437500000f, 0.62261962890625000000f, - 0.67697143554687500000f, 0.72888183593750000000f, - 0.78482055664062500000f, 0.84603881835937500000f, - 0.04190063476562500000f, 0.07913208007812500000f, - 0.13577270507812500000f, 0.17190551757812500000f, - 0.22277832031250000000f, 0.25711059570312500000f, - 0.28912353515625000000f, 0.33013916015625000000f, - 0.38967895507812500000f, 0.47979736328125006000f, - 0.57989501953125000000f, 0.65396118164062500000f, - 0.72271728515625000000f, 0.79113769531250000000f, - 0.85861206054687500000f, 0.92568969726562500000f, - 0.04870605468750000000f, 0.09713745117187500000f, - 0.16412353515625003000f, 0.21862792968750000000f, - 0.26458740234375000000f, 0.30838012695312500000f, - 0.35003662109375000000f, 0.39166259765625000000f, - 0.42697143554687500000f, 0.45904541015624994000f, - 0.50787353515625000000f, 0.54635620117187500000f, - 0.63351440429687500000f, 0.77157592773437500000f, - 0.84747314453125000000f, 0.92285156249999989000f, - 0.06216430664062500000f, 0.12167358398437500000f, - 0.19033813476562500000f, 0.24771118164062500000f, - 0.30377197265625000000f, 0.37368774414062500000f, - 0.43386840820312500000f, 0.48498535156250000000f, - 0.54244995117187500000f, 0.61383056640625000000f, - 0.68096923828125000000f, 0.79168701171875000000f, - 0.80276489257812500000f, 0.80819702148437500000f, - 0.81774902343750000000f, 0.87161254882812500000f, - 0.06655883789062500000f, 0.11773681640625000000f, - 0.17578125000000000000f, 0.24182128906250000000f, - 0.30642700195312500000f, 0.35330200195312500000f, - 0.42019653320312494000f, 0.47912597656250000000f, - 0.53189086914062500000f, 0.60665893554687500000f, - 0.71969604492187500000f, 0.74884033203125000000f, - 0.76940917968750000000f, 0.78408813476562511000f, - 0.87548828125000000000f, 0.93099975585937489000f, - 0.06079101562500000000f, 0.11846923828125000000f, - 0.19757080078125000000f, 0.24057006835937503000f, - 0.28628540039062500000f, 0.38671875000000006000f, - 0.43762207031250000000f, 0.47915649414062500000f, - 0.50836181640625000000f, 0.54418945312500000000f, - 0.63629150390625000000f, 0.69839477539062500000f, - 0.75308227539062511000f, 0.80740356445312500000f, - 0.86947631835937500000f, 0.92956542968750000000f, - 0.07296752929687500000f, 0.12170410156250000000f, - 0.16625976562500000000f, 0.22680664062500000000f, - 0.33612060546875000000f, 0.38388061523437500000f, - 0.40100097656250000000f, 0.43170166015625000000f, - 0.48516845703125006000f, 0.56738281250000000000f, - 0.64404296875000000000f, 0.70169067382812500000f, - 0.75296020507812500000f, 0.82965087890624989000f, - 0.85882568359375000000f, 0.90368652343750000000f, - 0.05227661132812500000f, 0.15570068359375000000f, - 0.21328735351562500000f, 0.23797607421875000000f, - 0.26458740234375000000f, 0.30853271484375000000f, - 0.38897705078125000000f, 0.45413208007812500000f, - 0.50991821289062500000f, 0.56173706054687500000f, - 0.61419677734375000000f, 0.67465209960937500000f, - 0.73794555664062500000f, 0.79949951171874989000f, - 0.86172485351562500000f, 0.91970825195312500000f, - 0.04919433593750000000f, 0.11038208007812500000f, - 0.18762207031250000000f, 0.25509643554687500000f, - 0.29223632812500000000f, 0.35180664062500006000f, - 0.45581054687500000000f, 0.54348754882812500000f, - 0.55807495117187500000f, 0.57156372070312500000f, - 0.57986450195312500000f, 0.64425659179687500000f, - 0.75167846679687500000f, 0.81164550781250000000f, - 0.87707519531250000000f, 0.93515014648437500000f, - 0.06915283203125000000f, 0.12719726562500000000f, - 0.23992919921875000000f, 0.29132080078125000000f, - 0.29351806640625000000f, 0.29611206054687500000f, - 0.30926513671875000000f, 0.42410278320312500000f, - 0.49636840820312500000f, 0.56250000000000000000f, - 0.62826538085937500000f, 0.68984985351562500000f, - 0.75543212890625000000f, 0.82379150390625000000f, - 0.88882446289062511000f, 0.94116210937500000000f, - 0.05615234375000000700f, 0.11953735351562501000f, - 0.19140625000000000000f, 0.23831176757812500000f, - 0.29644775390625000000f, 0.34906005859375000000f, - 0.42013549804687500000f, 0.48214721679687500000f, - 0.58728027343750000000f, 0.67053222656250000000f, - 0.70129394531250000000f, 0.70739746093750000000f, - 0.72396850585937489000f, 0.78277587890625000000f, - 0.88858032226562500000f, 0.94863891601562500000f, - 0.04449462890625000000f, 0.11022949218750000000f, - 0.18334960937500000000f, 0.22851562500000000000f, - 0.29989624023437500000f, 0.36294555664062500000f, - 0.42987060546875000000f, 0.48016357421875000000f, - 0.53222656250000000000f, 0.59616088867187500000f, - 0.68432617187500000000f, 0.75582885742187500000f, - 0.89251708984375000000f, 0.91333007812499989000f, - 0.93127441406250000000f, 0.94442749023437489000f, - -0.00311279296875000000f, -0.00369262695312500000f, - -0.00094604492187500000f, -0.00018310546875000000f, - 0.00015258789062500000f, -0.00006103515625000000f, - 0.00024414062500000000f, -0.00054931640625000000f, - -0.00012207031250000000f, 0.00018310546875000000f, - 0.00042724609375000000f, -0.00006103515625000000f, - -0.00036621093750000000f, -0.00048828125000000000f, - -0.00036621093750000000f, -0.00183105468749999980f, - -0.00384521484375000000f, -0.01077270507812500000f, - -0.01751708984375000000f, -0.02066040039062500000f, - -0.02005004882812500000f, -0.01882934570312500000f, - -0.01519775390625000000f, -0.01199340820312500000f, - -0.01062011718750000000f, -0.00845336914062500000f, - -0.00686645507812500000f, -0.00500488281250000000f, - -0.00311279296875000000f, -0.00213623046875000000f, - -0.00094604492187500000f, 0.00100708007812500000f, - 0.00012207031250000000f, 0.01156616210937500000f, - 0.01181030273437500000f, 0.01681518554687500000f, - 0.01846313476562500000f, 0.01892089843750000000f, - 0.01623535156250000000f, 0.01470947265625000200f, - 0.01348876953125000000f, 0.01385498046875000000f, - 0.01174926757812500200f, 0.01058959960937500000f, - 0.00982666015625000000f, 0.00912475585937500000f, - 0.00811767578125000000f, 0.00610351562500000000f, - 0.03564453125000000000f, 0.02902221679687500000f, - 0.02050781250000000000f, 0.00750732421875000000f, - 0.00183105468749999980f, -0.00491333007812500000f, - -0.00790405273437500000f, -0.00714111328125000000f, - -0.00772094726562500000f, -0.00860595703125000000f, - -0.00619506835937500000f, -0.00570678710937500090f, - -0.00473022460937500000f, -0.00537109374999999910f, - -0.00604248046875000090f, -0.00543212890625000000f, - 0.00030517578125000000f, 0.00518798828125000000f, - 0.01199340820312500000f, 0.01858520507812500000f, - 0.01693725585937500000f, 0.00634765625000000090f, - -0.01007080078124999800f, -0.01742553710937500000f, - -0.02346801757812500000f, -0.01931762695312500000f, - -0.00973510742187500000f, -0.00131225585937500000f, - 0.00289916992187500000f, 0.00320434570312500000f, - 0.00323486328125000000f, 0.00354003906250000000f, - -0.00463867187500000000f, -0.00427246093750000000f, - -0.00381469726562499960f, 0.00015258789062500000f, - 0.00527954101562500000f, 0.00836181640625000000f, - 0.00805664062500000000f, 0.01010131835937500000f, - -0.00112915039062500000f, -0.00894165039062500000f, - -0.01858520507812500000f, -0.02398681640625000000f, - -0.02926635742187500000f, -0.02484130859375000300f, - -0.01968383789062500000f, -0.00726318359375000000f, - -0.00277709960937500000f, 0.00109863281250000000f, - -0.00033569335937499995f, -0.00308227539062500000f, - -0.00851440429687500000f, -0.00692749023437500000f, - -0.00122070312500000000f, 0.00274658203125000000f, - 0.01617431640625000000f, 0.02066040039062500000f, - 0.02716064453125000000f, 0.03369140625000000000f, - 0.03048706054687500000f, 0.02548217773437500000f, - 0.01721191406250000000f, 0.00900268554687500000f, - -0.00854492187500000000f, -0.01110839843750000000f, - -0.01037597656250000000f, -0.01010131835937500000f, - -0.00866699218750000000f, 0.00878906250000000000f, - 0.02322387695312500000f, 0.02685546875000000000f, - 0.03015136718750000000f, 0.01913452148437500000f, - 0.00445556640625000000f, -0.00689697265625000000f, - -0.00619506835937500000f, -0.00552368164062500000f, - -0.00433349609375000000f, 0.00119018554687500000f, - 0.00073242187500000000f, -0.00079345703125000011f, - -0.00326538085937500000f, -0.00280761718750000000f, - -0.00491333007812500000f, -0.00411987304687500000f, - -0.00399780273437500000f, -0.00268554687499999960f, - -0.00488281250000000000f, -0.00476074218750000000f, - -0.00228881835937500000f, -0.00131225585937500000f, - -0.00109863281250000000f, -0.00018310546875000000f, - -0.00100708007812500000f, 0.00100708007812500000f, - -0.00988769531250000000f, -0.01266479492187500000f, - -0.00329589843750000000f, 0.00378417968750000000f, - 0.00479125976562500000f, 0.00582885742187500000f, - 0.00619506835937500000f, 0.00601196289062499910f, - 0.00439453125000000000f, 0.00332641601562499960f, - 0.00463867187500000000f, 0.00537109374999999910f, - 0.00579833984375000000f, 0.00372314453125000000f, - 0.00308227539062500000f, 0.00485229492187500000f, - 0.02023315429687500000f, 0.02038574218750000000f, - 0.01464843749999999800f, 0.01220703125000000000f, - 0.01156616210937500000f, 0.01354980468750000000f, - 0.01361083984375000000f, 0.01397705078124999800f, - 0.01046752929687500200f, 0.01071166992187500000f, - 0.00946044921875000000f, 0.00695800781250000000f, - 0.00405883789062500000f, 0.00134277343749999980f, - 0.00228881835937500000f, 0.00192260742187500000f, - -0.00256347656250000000f, 0.00119018554687500000f, - -0.00088500976562500000f, 0.00106811523437500000f, - -0.00286865234375000000f, -0.00711059570312500000f, - -0.00796508789062500000f, -0.01080322265625000200f, - 0.00234985351562500000f, 0.00799560546875000000f, - -0.00073242187500000000f, -0.00442504882812500000f, - -0.01016235351562500000f, -0.01248168945312500000f, - -0.01232910156250000000f, -0.01821899414062500000f, - -0.01489257812500000000f, -0.00915527343750000000f, - 0.02777099609375000000f, 0.01806640625000000000f, - 0.01257324218750000000f, 0.00366210937499999960f, - 0.00396728515625000000f, -0.00155639648437500000f, - -0.00112915039062500000f, -0.00234985351562500000f, - -0.00524902343750000000f, -0.00552368164062500000f, - -0.00485229492187500000f, -0.00451660156250000000f, - -0.00219726562500000000f, -0.00189208984375000000f, - 0.01556396484375000000f, 0.01574707031250000000f, - 0.00344848632812500000f, -0.01785278320312500000f, - -0.03280639648437500000f, -0.02920532226562500000f, - -0.01272583007812500000f, -0.00595092773437500000f, - 0.00027465820312500000f, 0.00021362304687500000f, - -0.00268554687499999960f, -0.00527954101562500000f, - -0.00277709960937500000f, 0.00164794921875000000f, - 0.00299072265625000000f, 0.00289916992187500000f, - -0.00085449218750000000f, 0.00601196289062499910f, - -0.01608276367187500000f, -0.01895141601562500000f, - 0.00479125976562500000f, 0.00372314453125000000f, - -0.00512695312500000000f, 0.00448608398437500000f, - 0.00942993164062500000f, 0.00915527343750000000f, - 0.01025390625000000000f, 0.00961303710937500000f, - 0.01208496093750000200f, 0.01245117187500000000f, - 0.01147460937500000000f, 0.00323486328125000000f, - -0.00494384765625000000f, -0.00518798828125000000f, - -0.00961303710937500000f, 0.00299072265625000000f, - 0.02505493164062499700f, 0.02770996093750000000f, - 0.01739501953125000000f, -0.00100708007812500000f, - -0.00952148437500000000f, -0.01733398437500000000f, - -0.01745605468750000000f, -0.01153564453125000000f, - -0.00326538085937500000f, 0.00070190429687500000f, - 0.00476074218750000000f, 0.00283813476562499960f, - -0.00393676757812500000f, -0.00265502929687500000f, - 0.00061035156250000000f, -0.00219726562500000000f, - -0.00112915039062500000f, 0.00122070312500000000f, - 0.00064086914062500000f, 0.00082397460937500000f, - 0.00146484375000000000f, 0.00228881835937500000f, - 0.00234985351562500000f, 0.00198364257812500000f, - 0.00140380859375000000f, 0.00216674804687500000f, - 0.00201416015625000000f, 0.00143432617187500000f, - 0.00415039062500000000f, 0.01049804687500000000f, - 0.00720214843750000000f, 0.00982666015625000000f, - 0.00518798828125000000f, 0.00863647460937500000f, - 0.00820922851562500000f, 0.00888061523437500000f, - 0.00494384765625000000f, -0.00131225585937500000f, - -0.00622558593750000000f, -0.00790405273437500000f, - -0.00732421874999999910f, -0.00930786132812500000f, - -0.01068115234374999800f, -0.00952148437500000000f, - 0.01364135742187499800f, 0.01062011718750000000f, - 0.01052856445312500000f, 0.00784301757812500000f, - 0.00216674804687500000f, -0.00399780273437500000f, - -0.00234985351562500000f, -0.00579833984375000000f, - -0.00616455078125000000f, -0.00122070312500000000f, - 0.00106811523437500000f, 0.00405883789062500000f, - 0.00796508789062500000f, 0.01113891601562500000f, - 0.01336669921875000200f, 0.00924682617187500000f, - -0.00024414062500000000f, 0.00067138671874999989f, - 0.00427246093750000000f, 0.00418090820312500000f, - -0.00915527343750000000f, -0.01956176757812500000f, - -0.02331542968750000000f, -0.00817871093750000000f, - -0.00070190429687500000f, -0.00076293945312500000f, - 0.00222778320312500000f, -0.00494384765625000000f, - -0.00457763671875000000f, -0.00646972656250000000f, - -0.00219726562500000000f, 0.00018310546875000000f, - 0.00119018554687500000f, 0.00238037109375000000f, - 0.00317382812500000040f, -0.00283813476562499960f, - -0.00939941406250000000f, -0.00415039062500000000f, - 0.00357055664062500000f, -0.00216674804687500000f, - -0.01565551757812500000f, -0.02502441406250000000f, - -0.02136230468749999700f, -0.01373291015625000000f, - -0.00491333007812500000f, -0.00070190429687500000f, - 0.00088500976562500000f, 0.00238037109375000000f, - 0.01028442382812500000f, 0.00323486328125000000f, - -0.01239013671875000000f, -0.02386474609375000000f, - -0.00341796875000000000f, 0.00711059570312500000f, - 0.01168823242187499800f, 0.00189208984375000000f, - -0.00384521484375000000f, 0.00018310546875000000f, - -0.00234985351562500000f, -0.00088500976562500000f, - -0.00445556640625000000f, -0.00375366210937500000f, - -0.00155639648437500000f, -0.00082397460937500000f, - -0.00082397460937500000f, -0.01162719726562500000f, - -0.01956176757812500000f, 0.01226806640625000000f, - 0.01644897460937500000f, 0.00024414062500000000f, - -0.00631713867187499910f, -0.01116943359375000000f, - -0.00109863281250000000f, -0.00082397460937500000f, - -0.00622558593750000000f, -0.00692749023437500000f, - -0.00723266601562500000f, -0.00576782226562500000f, - -0.00195312500000000000f, 0.00155639648437500000f, - -0.00280761718750000000f, -0.00418090820312500000f, - -0.00857543945312500000f, 0.00189208984375000000f, - 0.00711059570312500000f, 0.00280761718750000000f, - 0.00451660156250000000f, 0.00897216796875000000f, - 0.01107788085937500200f, 0.01269531250000000200f, - 0.01721191406250000000f, 0.01907348632812500000f, - 0.01129150390625000000f, -0.00109863281250000000f, - -0.01431274414062499800f, -0.01409912109375000000f, - 0.00311279296875000000f, 0.00512695312500000000f, - 0.00097656250000000000f, 0.00357055664062500000f, - -0.00064086914062500000f, 0.00296020507812500000f, - 0.00424194335937500000f, 0.00271606445312500000f, - 0.00317382812500000040f, 0.00106811523437500000f, - 0.00012207031250000000f, 0.00250244140625000000f, - 0.00201416015625000000f, 0.00177001953125000000f, - 0.00222778320312500000f, 0.00283813476562499960f, - -0.00231933593750000000f, -0.00976562500000000000f, - -0.00720214843750000000f, -0.00576782226562500000f, - -0.00619506835937500000f, -0.00433349609375000000f, - -0.00082397460937500000f, -0.00222778320312500000f, - 0.00027465820312500000f, -0.00027465820312500000f, - -0.00076293945312500000f, 0.00036621093750000000f, - -0.00045776367187499995f, 0.00012207031250000000f, - 0.00012207031250000000f, -0.00152587890625000000f, - 0.00958251953125000000f, 0.00549316406250000000f, - 0.00494384765625000000f, -0.00149536132812500000f, - 0.00607299804687500000f, -0.00329589843750000000f, - -0.00692749023437500000f, -0.00201416015625000000f, - -0.01364135742187499800f, -0.00204467773437500000f, - -0.00805664062500000000f, -0.01202392578124999800f, - 0.00015258789062500000f, 0.00167846679687500000f, - -0.00405883789062500000f, -0.00537109374999999910f, - -0.00354003906250000000f, -0.00735473632812500090f, - 0.00830078125000000000f, 0.00332641601562499960f, - 0.00860595703125000000f, 0.00799560546875000000f, - 0.00585937500000000000f, -0.00195312500000000000f, - -0.01196289062500000000f, -0.01568603515625000000f, - 0.00476074218750000000f, 0.00619506835937500000f, - 0.00469970703125000000f, 0.00219726562500000000f, - -0.00103759765625000000f, -0.00488281250000000000f, - -0.00222778320312500000f, 0.00009155273437500000f, - -0.00100708007812500000f, -0.01315307617187500000f, - 0.00979614257812500000f, 0.00054931640625000000f, - -0.01730346679687500000f, -0.01800537109375000000f, - -0.00329589843750000000f, 0.00268554687499999960f, - 0.00201416015625000000f, 0.00155639648437500000f, - -0.00094604492187500000f, -0.00588989257812500000f, - -0.00140380859375000000f, 0.00198364257812500000f, - -0.00088500976562500000f, -0.00070190429687500000f, - 0.00656127929687500000f, -0.00094604492187500000f, - 0.00308227539062500000f, -0.00344848632812500000f, - 0.00097656250000000000f, 0.00927734375000000000f, - 0.00268554687499999960f, 0.00976562500000000000f, - 0.01367187500000000000f, 0.00015258789062500000f, - -0.01339721679687500000f, -0.01715087890625000000f, - -0.01550292968750000000f, -0.00411987304687500000f, - -0.00039672851562500005f, -0.00521850585937500000f, - -0.00024414062500000000f, 0.00555419921875000000f, - -0.00302124023437500040f, -0.00552368164062500000f, - -0.00454711914062500000f, 0.01147460937500000000f, - 0.01452636718750000000f, 0.00195312500000000000f, - -0.01208496093750000200f, -0.01989746093750000000f, - -0.00457763671875000000f, 0.00537109374999999910f, - 0.00677490234375000000f, 0.00198364257812500000f, - -0.01800537109375000000f, 0.02194213867187500300f, - 0.00827026367187500000f, 0.01217651367187500000f, - 0.00747680664062500000f, 0.00219726562500000000f, - -0.00476074218750000000f, -0.00463867187500000000f, - -0.00537109374999999910f, 0.00180053710937500000f, - 0.00286865234375000000f, 0.00381469726562499960f, - -0.00027465820312500000f, -0.00021362304687500000f, - 0.00027465820312500000f, 0.00003051757812500000f, - -0.00186157226562500000f, -0.00354003906250000000f, - -0.00250244140625000000f, 0.00003051757812500000f, - 0.00241088867187500000f, 0.00067138671874999989f, - -0.00134277343749999980f, -0.00045776367187499995f, - -0.00146484375000000000f, -0.00198364257812500000f, - -0.00189208984375000000f, -0.00308227539062500000f, - -0.00311279296875000000f, -0.00164794921875000000f, - -0.00213623046875000000f, -0.00238037109375000000f, - -0.00244140625000000000f, -0.00076293945312500000f, - 0.01214599609375000000f, 0.00216674804687500000f, - 0.00424194335937500000f, 0.00115966796875000000f, - 0.00274658203125000000f, 0.00592041015625000000f, - 0.00677490234375000000f, 0.00759887695312500000f, - 0.00503540039062499910f, 0.00286865234375000000f, - 0.00674438476562500000f, 0.00799560546875000000f, - 0.00497436523437500000f, 0.00277709960937500000f, - -0.00628662109375000000f, 0.01748657226562500000f, - 0.00610351562500000000f, -0.00875854492187500000f, - -0.00448608398437500000f, 0.00015258789062500000f, - -0.00054931640625000000f, -0.00259399414062500000f, - -0.00225830078125000000f, -0.00381469726562499960f, - -0.00265502929687500000f, 0.00259399414062500000f, - 0.00430297851562500000f, 0.00012207031250000000f, - -0.00012207031250000000f, 0.00085449218750000000f, - 0.00714111328125000000f, 0.00146484375000000000f, - -0.00457763671875000000f, -0.00338745117187500000f, - -0.01544189453125000000f, 0.00723266601562500000f, - -0.00637817382812500090f, 0.01052856445312500000f, - 0.00286865234375000000f, -0.00378417968750000000f, - 0.00234985351562500000f, 0.00369262695312500000f, - 0.00436401367187500000f, 0.00036621093750000000f, - -0.00244140625000000000f, -0.00146484375000000000f, - 0.00582885742187500000f, 0.00439453125000000000f, - -0.00283813476562499960f, -0.00198364257812500000f, - -0.00460815429687500000f, -0.01962280273437500000f, - 0.01327514648437500000f, 0.00323486328125000000f, - 0.00265502929687500000f, 0.00021362304687500000f, - 0.00198364257812500000f, 0.00311279296875000000f, - 0.00286865234375000000f, 0.00207519531250000000f, - 0.00015258789062500000f, 0.00302124023437500040f, - 0.00677490234375000000f, 0.00283813476562499960f, - 0.00286865234375000000f, 0.01083374023437500000f, - -0.00039672851562500005f, -0.00271606445312500000f, - -0.00695800781250000000f, -0.01535034179687500000f, - 0.00875854492187500000f, 0.00332641601562499960f, - 0.00329589843750000000f, 0.01370239257812500200f, - 0.00772094726562500000f, -0.00088500976562500000f, - -0.00332641601562499960f, -0.00354003906250000000f, - 0.00045776367187499995f, -0.00222778320312500000f, - -0.00061035156250000000f, 0.00399780273437500000f, - -0.00448608398437500000f, 0.00219726562500000000f, - 0.00180053710937500000f, -0.00457763671875000000f, - -0.01812744140625000000f, 0.00833129882812500000f, - 0.00964355468750000000f, 0.00402832031250000000f, - 0.00607299804687500000f, 0.00323486328125000000f, - 0.00604248046875000090f, 0.00646972656250000000f, - 0.00671386718750000000f, 0.00250244140625000000f, - 0.00137329101562500000f, -0.00039672851562500005f, - 0.00680541992187500000f, 0.00418090820312500000f, - 0.00823974609375000000f, 0.00115966796875000000f, - 0.00769042968750000000f, 0.00411987304687500000f, - -0.00540161132812500090f, -0.00631713867187499910f, - -0.01098632812500000000f, -0.00311279296875000000f, - 0.01229858398437500000f, 0.01239013671875000000f, - -0.00042724609375000000f, 0.00253295898437500040f, - 0.00195312500000000000f, 0.00155639648437500000f, - -0.00021362304687500000f, -0.00302124023437500040f, - -0.00296020507812500000f, -0.00268554687499999960f, - -0.00378417968750000000f, -0.00198364257812500000f, - 0.00128173828125000000f, 0.00097656250000000000f, - 0.00085449218750000000f, 0.00088500976562500000f, - 0.00036621093750000000f, 0.00061035156250000000f, - 0.00363159179687500000f, -0.00079345703125000011f, - -0.00646972656250000000f, -0.00613403320312500000f, - 0.01138305664062500000f, 0.00765991210937500090f, - 0.00430297851562500000f, 0.00314331054687500000f, - 0.00109863281250000000f, -0.00158691406250000020f, - 0.00201416015625000000f, 0.00054931640625000000f, - -0.00018310546875000000f, -0.00289916992187500000f, - -0.00598144531250000000f, 0.00015258789062500000f, - 0.00299072265625000000f, -0.00259399414062500000f, - -0.00329589843750000000f, 0.00665283203124999910f, - -0.00500488281250000000f, 0.00061035156250000000f, - 0.01086425781250000000f, 0.00524902343750000000f, - 0.00112915039062500000f, 0.00811767578125000000f, - 0.00070190429687500000f, 0.00341796875000000000f, - -0.00073242187500000000f, -0.00302124023437500040f, - -0.00280761718750000000f, -0.00543212890625000000f, - 0.00088500976562500000f, -0.00848388671875000000f, - 0.01184082031250000000f, -0.00183105468749999980f, - -0.00671386718750000000f, 0.00915527343750000000f, - -0.00039672851562500005f, 0.00469970703125000000f, - 0.00582885742187500000f, 0.00045776367187499995f, - -0.00112915039062500000f, -0.00335693359375000000f, - -0.00466918945312500000f, -0.00457763671875000000f, - -0.00347900390625000000f, -0.00021362304687500000f, - -0.00286865234375000000f, -0.00094604492187500000f, - -0.00189208984375000000f, -0.00540161132812500090f, - 0.00012207031250000000f, -0.00213623046875000000f, - 0.00106811523437500000f, 0.01382446289062500000f, - 0.00448608398437500000f, -0.00753784179687500000f, - -0.01000976562500000000f, 0.00308227539062500000f, - 0.00061035156250000000f, -0.00347900390625000000f, - 0.00448608398437500000f, 0.00329589843750000000f, - -0.00363159179687500000f, -0.00332641601562499960f, - -0.00311279296875000000f, -0.00726318359375000000f, - 0.00167846679687500000f, -0.00311279296875000000f, - 0.00527954101562500000f, -0.00271606445312500000f, - 0.00393676757812500000f, 0.00421142578125000000f, - -0.01007080078124999800f, -0.00488281250000000000f, - 0.01480102539062500000f, 0.00469970703125000000f, - -0.00180053710937500000f, -0.00518798828125000000f, - -0.00061035156250000000f, -0.00103759765625000000f, - -0.00796508789062500000f, -0.00122070312500000000f, - -0.00393676757812500000f, 0.00234985351562500000f, - -0.00256347656250000000f, 0.00210571289062500000f, - 0.00253295898437500040f, 0.00488281250000000000f, - 0.00515747070312500000f, 0.00192260742187500000f, - -0.01574707031250000000f, 0.00091552734374999989f, - 0.01025390625000000000f, 0.00158691406250000020f, - -0.00000000000000000000f, -0.00158691406250000020f, - -0.00378417968750000000f, 0.00482177734375000000f, - 0.00057983398437500000f, 0.00601196289062499910f, - -0.00030517578125000000f, -0.01144409179687500000f, - 0.01235961914062499800f, 0.00869750976562500000f, - 0.00347900390625000000f, -0.01205444335937500000f, - -0.00143432617187500000f, 0.00598144531250000000f, - 0.00189208984375000000f, 0.00265502929687500000f, - -0.00323486328125000000f, -0.00198364257812500000f, - -0.00228881835937500000f, -0.00210571289062500000f, - -0.00039672851562500005f, 0.00103759765625000000f, - 0.00302124023437500040f, 0.00180053710937500000f, - 0.00253295898437500040f, 0.00299072265625000000f, - 0.00134277343749999980f, 0.00000000000000000000f, - 0.00073242187500000000f, 0.00054931640625000000f, - 0.00051879882812500000f, 0.00213623046875000000f, - -0.00067138671874999989f, 0.00592041015625000000f, - 0.00634765625000000090f, 0.00439453125000000000f, - -0.00241088867187500000f, -0.00045776367187499995f, - 0.00097656250000000000f, -0.00317382812500000040f, - -0.00085449218750000000f, -0.00320434570312500000f, - -0.00567626953124999910f, -0.00646972656250000000f, - -0.00695800781250000000f, -0.00241088867187500000f, - -0.00231933593750000000f, 0.00155639648437500000f, - -0.00216674804687500000f, 0.00219726562500000000f, - 0.00360107421875000000f, -0.00103759765625000000f, - -0.00009155273437500000f, -0.00521850585937500000f, - 0.00015258789062500000f, 0.00006103515625000000f, - -0.00329589843750000000f, -0.00381469726562499960f, - 0.00189208984375000000f, -0.00177001953125000000f, - 0.00177001953125000000f, -0.00369262695312500000f, - 0.00222778320312500000f, -0.01422119140625000000f, - 0.00280761718750000000f, 0.00192260742187500000f, - -0.00286865234375000000f, -0.00238037109375000000f, - -0.00231933593750000000f, 0.00646972656250000000f, - 0.00109863281250000000f, -0.00686645507812500000f, - -0.00216674804687500000f, -0.01080322265625000200f, - 0.00463867187500000000f, 0.00436401367187500000f, - -0.00241088867187500000f, -0.00750732421875000000f, - -0.00155639648437500000f, -0.00094604492187500000f, - -0.00018310546875000000f, -0.00823974609375000000f, - 0.00732421874999999910f, 0.00640869140625000000f, - 0.00091552734374999989f, -0.00479125976562500000f, - -0.00704956054687500000f, 0.00225830078125000000f, - -0.00445556640625000000f, 0.00268554687499999960f, - -0.00833129882812500000f, 0.00476074218750000000f, - 0.00280761718750000000f, 0.00170898437500000000f, - 0.00216674804687500000f, 0.00006103515625000000f, - 0.00970458984375000000f, 0.00500488281250000000f, - 0.00097656250000000000f, -0.00335693359375000000f, - -0.00106811523437500000f, -0.00125122070312500000f, - -0.00289916992187500000f, -0.00323486328125000000f, - 0.00033569335937499995f, 0.00402832031250000000f, - -0.00207519531250000000f, 0.00167846679687500000f, - 0.00375366210937500000f, -0.00253295898437500040f, - -0.00454711914062500000f, 0.00646972656250000000f, - 0.00402832031250000000f, 0.00000000000000000000f, - -0.00592041015625000000f, 0.00167846679687500000f, - 0.00628662109375000000f, -0.00329589843750000000f, - -0.01077270507812500000f, 0.00881958007812500000f, - -0.00595092773437500000f, 0.00003051757812500000f, - 0.00711059570312500000f, -0.00067138671874999989f, - -0.00183105468749999980f, 0.00061035156250000000f, - 0.00079345703125000011f, 0.00207519531250000000f, - 0.00506591796875000090f, 0.00082397460937500000f, - -0.00177001953125000000f, 0.00396728515625000000f, - 0.00341796875000000000f, 0.00326538085937500000f, - 0.00082397460937500000f, -0.00503540039062499910f, - 0.00350952148437500040f, -0.00283813476562499960f, - -0.00112915039062500000f, 0.00115966796875000000f, - 0.00253295898437500040f, 0.01473999023437500000f, - 0.00198364257812500000f, -0.00698852539062499910f, - -0.00039672851562500005f, 0.00479125976562500000f, - 0.00259399414062500000f, 0.00152587890625000000f, - 0.00415039062500000000f, 0.00030517578125000000f, - 0.00097656250000000000f, 0.00253295898437500040f, - 0.00250244140625000000f, 0.00167846679687500000f, - 0.00015258789062500000f, -0.00027465820312500000f, - -0.00158691406250000020f, -0.00238037109375000000f, - -0.00247192382812500000f, -0.00155639648437500000f, - 0.00122070312500000000f, 0.00054931640625000000f, - -0.00387573242187500000f, -0.00683593750000000000f, - -0.00125122070312500000f, 0.00161743164062500000f, - -0.00640869140625000000f, -0.00344848632812500000f, - 0.00073242187500000000f, -0.00051879882812500000f, - -0.00570678710937500090f, -0.00271606445312500000f, - 0.00024414062500000000f, 0.00369262695312500000f, - 0.00253295898437500040f, 0.00234985351562500000f, - 0.00277709960937500000f, -0.00225830078125000000f, - -0.00106811523437500000f, -0.00341796875000000000f, - -0.00491333007812500000f, -0.00527954101562500000f, - 0.00311279296875000000f, 0.00402832031250000000f, - -0.00381469726562499960f, -0.00186157226562500000f, - 0.00314331054687500000f, -0.00793457031250000000f, - 0.00158691406250000020f, 0.00506591796875000090f, - -0.00097656250000000000f, -0.00476074218750000000f, - -0.00265502929687500000f, -0.00170898437500000000f, - 0.00183105468749999980f, -0.00213623046875000000f, - -0.00378417968750000000f, 0.00738525390625000000f, - 0.00347900390625000000f, -0.00765991210937500090f, - -0.00506591796875000090f, 0.00613403320312500000f, - 0.00387573242187500000f, 0.00085449218750000000f, - -0.00033569335937499995f, 0.00070190429687500000f, - -0.00244140625000000000f, -0.00350952148437500040f, - -0.00061035156250000000f, -0.00155639648437500000f, - -0.01062011718750000000f, 0.01037597656250000000f, - -0.00103759765625000000f, 0.00405883789062500000f, - 0.00039672851562500005f, 0.00280761718750000000f, - -0.00378417968750000000f, -0.00415039062500000000f, - -0.00366210937499999960f, -0.00079345703125000011f, - -0.00018310546875000000f, 0.00051879882812500000f, - 0.00085449218750000000f, 0.00064086914062500000f, - 0.00366210937499999960f, -0.00512695312500000000f, - 0.00488281250000000000f, -0.00106811523437500000f, - 0.00350952148437500040f, 0.00085449218750000000f, - 0.00027465820312500000f, 0.00021362304687500000f, - -0.00170898437500000000f, 0.00119018554687500000f, - 0.00476074218750000000f, 0.00781250000000000000f, - -0.00054931640625000000f, 0.00003051757812500000f, - 0.00845336914062500000f, 0.00250244140625000000f, - -0.00213623046875000000f, -0.00439453125000000000f, - -0.00268554687499999960f, -0.00039672851562500005f, - -0.00180053710937500000f, -0.00479125976562500000f, - 0.00024414062500000000f, -0.00408935546875000000f, - 0.00064086914062500000f, -0.00122070312500000000f, - 0.00177001953125000000f, -0.00064086914062500000f, - 0.00592041015625000000f, -0.00842285156250000000f, - 0.00296020507812500000f, 0.00851440429687500000f, - -0.00170898437500000000f, -0.00427246093750000000f, - 0.00381469726562499960f, 0.00173950195312500000f, - -0.00561523437500000000f, -0.00622558593750000000f, - -0.00213623046875000000f, -0.00006103515625000000f, - 0.00390625000000000000f, -0.00616455078125000000f, - -0.00238037109375000000f, 0.00701904296875000090f, - -0.00070190429687500000f, 0.00491333007812500000f, - -0.00311279296875000000f, 0.00003051757812500000f, - 0.00003051757812500000f, 0.00549316406250000000f, - -0.00094604492187500000f, -0.00262451171875000000f, - -0.00509643554687500000f, -0.00173950195312500000f, - -0.00183105468749999980f, 0.00082397460937500000f, - -0.00039672851562500005f, 0.00302124023437500040f, - 0.00329589843750000000f, 0.00338745117187500000f, - 0.00231933593750000000f, 0.00210571289062500000f, - 0.00103759765625000000f, -0.00064086914062500000f, - 0.00161743164062500000f, 0.00115966796875000000f, - 0.00103759765625000000f, 0.00238037109375000000f, - 0.00222778320312500000f, 0.00668334960937500090f, - 0.00155639648437500000f, 0.00045776367187499995f, - -0.00219726562500000000f, -0.00314331054687500000f, - -0.00631713867187499910f, 0.00091552734374999989f, - 0.00650024414062500000f, -0.00042724609375000000f, - 0.00094604492187500000f, -0.00286865234375000000f, - -0.00122070312500000000f, -0.00439453125000000000f, - 0.00204467773437500000f, 0.00012207031250000000f, - 0.00320434570312500000f, 0.00180053710937500000f, - -0.00732421874999999910f, 0.00076293945312500000f, - 0.00744628906250000000f, 0.00210571289062500000f, - 0.00177001953125000000f, 0.00070190429687500000f, - -0.00073242187500000000f, -0.00015258789062500000f, - -0.00045776367187499995f, -0.00405883789062500000f, - -0.00216674804687500000f, -0.00204467773437500000f, - 0.00552368164062500000f, 0.00088500976562500000f, - -0.00137329101562500000f, 0.00369262695312500000f, - 0.00292968750000000000f, 0.00155639648437500000f, - -0.00219726562500000000f, -0.00161743164062500000f, - 0.00170898437500000000f, -0.00466918945312500000f, - -0.00082397460937500000f, 0.00259399414062500000f, - 0.00558471679687500000f, 0.00643920898437500000f, - 0.00320434570312500000f, -0.00103759765625000000f, - -0.00140380859375000000f, 0.00131225585937500000f, - -0.00219726562500000000f, -0.00283813476562499960f, - 0.00109863281250000000f, -0.00390625000000000000f, - 0.00088500976562500000f, 0.00338745117187500000f, - -0.00289916992187500000f, -0.00476074218750000000f, - -0.00546264648437500000f, -0.00717163085937500000f, - 0.00064086914062500000f, -0.00119018554687500000f, - -0.00216674804687500000f, -0.00100708007812500000f, - -0.00186157226562500000f, -0.00769042968750000000f, - 0.00701904296875000090f, -0.00399780273437500000f, - 0.00479125976562500000f, -0.00064086914062500000f, - -0.00259399414062500000f, -0.00085449218750000000f, - -0.00375366210937500000f, 0.00244140625000000000f, - -0.00488281250000000000f, 0.00192260742187500000f, - 0.00143432617187500000f, -0.00018310546875000000f, - -0.00149536132812500000f, -0.00292968750000000000f, - -0.00057983398437500000f, 0.00051879882812500000f, - -0.00177001953125000000f, 0.00051879882812500000f, - -0.00000000000000000000f, -0.00039672851562500005f, - -0.00518798828125000000f, 0.00076293945312500000f, - -0.00106811523437500000f, 0.00180053710937500000f, - 0.00030517578125000000f, -0.00094604492187500000f, - -0.01260375976562500000f, 0.00247192382812500000f, - 0.00189208984375000000f, 0.00054931640625000000f, - -0.00500488281250000000f, 0.00747680664062500000f, - 0.00280761718750000000f, -0.00503540039062499910f, - 0.00128173828125000000f, 0.00079345703125000011f, - 0.00384521484375000000f, -0.00756835937500000000f, - 0.00588989257812500000f, -0.00167846679687500000f, - 0.00048828125000000000f, 0.00119018554687500000f, - 0.00042724609375000000f, 0.00152587890625000000f - }; - -// const SKP_Silk_NLSF_CBS_FLP SKP_Silk_NLSF_CB1_16_Stage_info_FLP[ NLSF_MSVQ_CB1_16_STAGES ] = -// { -// { 32, &SKP_Silk_NLSF_MSVQ_CB1_16[ 16 * 0 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates[ 0 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB1_16[ 16 * 32 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates[ 32 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB1_16[ 16 * 40 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates[ 40 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB1_16[ 16 * 48 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates[ 48 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB1_16[ 16 * 56 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates[ 56 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB1_16[ 16 * 64 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates[ 64 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB1_16[ 16 * 72 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates[ 72 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB1_16[ 16 * 80 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates[ 80 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB1_16[ 16 * 88 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates[ 88 ] }, -// { 8, &SKP_Silk_NLSF_MSVQ_CB1_16[ 16 * 96 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates[ 96 ] } -// }; - - static final SKP_Silk_NLSF_CBS_FLP SKP_Silk_NLSF_CB1_16_Stage_info_FLP[] = - { - new SKP_Silk_NLSF_CBS_FLP(32, SKP_Silk_NLSF_MSVQ_CB1_16, 16*0, SKP_Silk_NLSF_MSVQ_CB1_16_rates, 0), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB1_16, 16*32, SKP_Silk_NLSF_MSVQ_CB1_16_rates, 32), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB1_16, 16*40, SKP_Silk_NLSF_MSVQ_CB1_16_rates, 40), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB1_16, 16*48, SKP_Silk_NLSF_MSVQ_CB1_16_rates, 48), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB1_16, 16*56, SKP_Silk_NLSF_MSVQ_CB1_16_rates, 56), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB1_16, 16*64, SKP_Silk_NLSF_MSVQ_CB1_16_rates, 64), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB1_16, 16*72, SKP_Silk_NLSF_MSVQ_CB1_16_rates, 72), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB1_16, 16*80, SKP_Silk_NLSF_MSVQ_CB1_16_rates, 80), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB1_16, 16*88, SKP_Silk_NLSF_MSVQ_CB1_16_rates, 88), - new SKP_Silk_NLSF_CBS_FLP(8, SKP_Silk_NLSF_MSVQ_CB1_16, 16*96, SKP_Silk_NLSF_MSVQ_CB1_16_rates, 96), - }; - -// const SKP_Silk_NLSF_CB_FLP SKP_Silk_NLSF_CB1_16_FLP = -// { -// NLSF_MSVQ_CB1_16_STAGES, -// SKP_Silk_NLSF_CB1_16_Stage_info_FLP, -// SKP_Silk_NLSF_MSVQ_CB1_16_ndelta_min, -// SKP_Silk_NLSF_MSVQ_CB1_16_CDF, -// SKP_Silk_NLSF_MSVQ_CB1_16_CDF_start_ptr, -// SKP_Silk_NLSF_MSVQ_CB1_16_CDF_middle_idx -// }; - static final SKP_Silk_NLSF_CB_FLP SKP_Silk_NLSF_CB1_16_FLP = - new SKP_Silk_NLSF_CB_FLP ( - Silk_tables_NLSF_CB1_16.NLSF_MSVQ_CB1_16_STAGES, - SKP_Silk_NLSF_CB1_16_Stage_info_FLP, - SKP_Silk_NLSF_MSVQ_CB1_16_ndelta_min, - Silk_tables_NLSF_CB1_16.SKP_Silk_NLSF_MSVQ_CB1_16_CDF, - Silk_tables_NLSF_CB1_16.SKP_Silk_NLSF_MSVQ_CB1_16_CDF_start_ptr, - Silk_tables_NLSF_CB1_16.SKP_Silk_NLSF_MSVQ_CB1_16_CDF_middle_idx - ); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_gain.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_gain.java deleted file mode 100644 index 3359be1a6..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_gain.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_tables_gain -{ - static int[][] SKP_Silk_gain_CDF = { - { 0, 18, 45, 94, 181, 320, 519, 777, 1093, 1468, 1909, 2417, 2997, - 3657, 4404, 5245, 6185, 7228, 8384, 9664, 11069, 12596, - 14244, 16022, 17937, 19979, 22121, 24345, 26646, 29021, - 31454, 33927, 36438, 38982, 41538, 44068, 46532, 48904, - 51160, 53265, 55184, 56904, 58422, 59739, 60858, 61793, - 62568, 63210, 63738, 64165, 64504, 64769, 64976, 65133, - 65249, 65330, 65386, 65424, 65451, 65471, 65487, 65501, - 65513, 65524, 65535 }, - { 0, 214, 581, 1261, 2376, 3920, 5742, 7632, 9449, 11157, 12780, - 14352, 15897, 17427, 18949, 20462, 21957, 23430, 24889, - 26342, 27780, 29191, 30575, 31952, 33345, 34763, 36200, - 37642, 39083, 40519, 41930, 43291, 44602, 45885, 47154, - 48402, 49619, 50805, 51959, 53069, 54127, 55140, 56128, - 57101, 58056, 58979, 59859, 60692, 61468, 62177, 62812, - 63368, 63845, 64242, 64563, 64818, 65023, 65184, 65306, - 65391, 65447, 65482, 65505, 65521, 65535 } }; - - static final int SKP_Silk_gain_CDF_offset = 32; - - static int[] SKP_Silk_delta_gain_CDF = { - 0, 2358, 3856, 7023, 15376, 53058, 59135, 61555, - 62784, 63498, 63949, 64265, 64478, 64647, 64783, 64894, - 64986, 65052, 65113, 65169, 65213, 65252, 65284, 65314, - 65338, 65359, 65377, 65392, 65403, 65415, 65424, 65432, - 65440, 65448, 65455, 65462, 65470, 65477, 65484, 65491, - 65499, 65506, 65513, 65521, 65528, 65535 - }; - - static final int SKP_Silk_delta_gain_CDF_offset = 5; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_other.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_other.java deleted file mode 100644 index 197d2f98e..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_other.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_tables_other -{ - /* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */ - static final int[] TargetRate_table_NB = - { - 0, 8000, 9000, 11000, 13000, 16000, 22000, 100000 - }; - - static final int[] TargetRate_table_MB = { - 0, 10000, 12000, 14000, 17000, 21000, 28000, 100000 - }; - - static final int[] TargetRate_table_WB = { - 0, 11000, 14000, 17000, 21000, 26000, 36000, 100000 - }; - - static final int[] TargetRate_table_SWB = { - 0, 13000, 16000, 19000, 25000, 32000, 46000, 100000 - }; - - static final int[] SNR_table_Q1 = { - 19, 31, 35, 39, 43, 47, 54, 59 - }; - - static final int[] SNR_table_one_bit_per_sample_Q7 = { - 1984, 2240, 2408, 2708 - }; - - /* Filter coeficicnts for HP filter: 4. Order filter implementad as two biquad filters */ - static final short[][] SKP_Silk_SWB_detect_B_HP_Q13 = { - {575, -948, 575}, {575, -221, 575}, {575, 104, 575} - }; - static final short[][] SKP_Silk_SWB_detect_A_HP_Q13 = { - {14613, 6868}, {12883, 7337}, {11586, 7911} - }; - - /* Decoder high-pass filter coefficients for 24 kHz sampling, -6 dB @ 44 Hz */ - static final short[] SKP_Silk_Dec_A_HP_24 = {-16220, 8030}; // second order AR coefs, Q13 - static final short[] SKP_Silk_Dec_B_HP_24 = {8000, -16000, 8000}; // second order MA coefs, Q13 - - /* Decoder high-pass filter coefficients for 16 kHz sampling, - 6 dB @ 46 Hz */ - static final short[] SKP_Silk_Dec_A_HP_16 = {-16127, 7940}; // second order AR coefs, Q13 - static final short[] SKP_Silk_Dec_B_HP_16 = {8000, -16000, 8000}; // second order MA coefs, Q13 - - - /* Decoder high-pass filter coefficients for 12 kHz sampling, -6 dB @ 44 Hz */ - static final short[] SKP_Silk_Dec_A_HP_12 = {-16043, 7859}; // second order AR coefs, Q13 - static final short[] SKP_Silk_Dec_B_HP_12 = {8000, -16000, 8000}; // second order MA coefs, Q13 - - - /* Decoder high-pass filter coefficients for 8 kHz sampling, -6 dB @ 43 Hz */ - static final short[] SKP_Silk_Dec_A_HP_8 = {-15885, 7710}; // second order AR coefs, Q13 - static final short[] SKP_Silk_Dec_B_HP_8 = {8000, -16000, 8000}; // second order MA coefs, Q13 - - /* table for LSB coding */ - static final int[] SKP_Silk_lsb_CDF = {0, 40000, 65535}; - - /* tables for LTPScale */ - static final int[] SKP_Silk_LTPscale_CDF = {0, 32000, 48000, 65535}; - static final int SKP_Silk_LTPscale_offset = 2; - - /* tables for VAD flag */ - static final int[] SKP_Silk_vadflag_CDF = {0, 22000, 65535}; // 66% for speech, 33% for no speech - static final int SKP_Silk_vadflag_offset =1; - - /* tables for sampling rate */ - static final int[] SKP_Silk_SamplingRates_table = {8, 12, 16, 24}; - static final int[] SKP_Silk_SamplingRates_CDF = {0, 16000, 32000, 48000, 65535}; - static final int SKP_Silk_SamplingRates_offset = 2; - - /* tables for NLSF interpolation factor */ - static final int[] SKP_Silk_NLSF_interpolation_factor_CDF = {0, 3706, 8703, 19226, 30926, 65535}; - static final int SKP_Silk_NLSF_interpolation_factor_offset = 4; - - /* Table for frame termination indication */ - static final int[] SKP_Silk_FrameTermination_CDF = {0, 20000, 45000, 56000, 65535}; - static final int SKP_Silk_FrameTermination_offset = 2; - - /* Table for random seed */ - static final int[] SKP_Silk_Seed_CDF = {0, 16384, 32768, 49152, 65535}; - static final int SKP_Silk_Seed_offset = 2; - - /* Quantization offsets */ - static final short[][] SKP_Silk_Quantization_Offsets_Q10 = { - { Silk_define.OFFSET_VL_Q10, Silk_define.OFFSET_VH_Q10 }, { Silk_define.OFFSET_UVL_Q10, Silk_define.OFFSET_UVH_Q10 } - }; - - /* Table for LTPScale */ - static final short[] SKP_Silk_LTPScales_table_Q14 = { 15565, 11469, 8192 }; - - - /* Elliptic/Cauer filters designed with 0.1 dB passband ripple, - 80 dB minimum stopband attenuation, and - [0.95 : 0.15 : 0.35] normalized cut off frequencies. */ - - /* Interpolation points for filter coefficients used in the bandwidth transition smoother */ - static final int[][] SKP_Silk_Transition_LP_B_Q28= - { - { 250767114, 501534038, 250767114 }, - { 209867381, 419732057, 209867381 }, - { 170987846, 341967853, 170987846 }, - { 131531482, 263046905, 131531482 }, - { 89306658, 178584282, 89306658 } - }; - - /* Interpolation points for filter coefficients used in the bandwidth transition smoother */ - static final int[][] SKP_Silk_Transition_LP_A_Q28 = - { - { 506393414, 239854379 }, - { 411067935, 169683996 }, - { 306733530, 116694253 }, - { 185807084, 77959395 }, - { 35497197, 57401098 } - }; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_other_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_other_FLP.java deleted file mode 100644 index 42ebd8beb..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_other_FLP.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - * - */ -public class Silk_tables_other_FLP -{ - static float[] SKP_Silk_HarmShapeFIR_FLP = { 16384.0f / 65536.0f, 32767.0f / 65536.0f, 16384.0f / 65536.0f }; - - float[][] SKP_Silk_Quantization_Offsets = - { - { Silk_define.OFFSET_VL_Q10 / 1024.0f, Silk_define.OFFSET_VH_Q10 / 1024.0f }, - { Silk_define.OFFSET_UVL_Q10 / 1024.0f, Silk_define.OFFSET_UVH_Q10 / 1024.0f } - }; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_pitch_lag.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_pitch_lag.java deleted file mode 100644 index ef0a030bf..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_pitch_lag.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_tables_pitch_lag -{ - static int[] SKP_Silk_pitch_lag_NB_CDF = { - 0, 194, 395, 608, 841, 1099, 1391, 1724, - 2105, 2544, 3047, 3624, 4282, 5027, 5865, 6799, - 7833, 8965, 10193, 11510, 12910, 14379, 15905, 17473, - 19065, 20664, 22252, 23814, 25335, 26802, 28206, 29541, - 30803, 31992, 33110, 34163, 35156, 36098, 36997, 37861, - 38698, 39515, 40319, 41115, 41906, 42696, 43485, 44273, - 45061, 45847, 46630, 47406, 48175, 48933, 49679, 50411, - 51126, 51824, 52502, 53161, 53799, 54416, 55011, 55584, - 56136, 56666, 57174, 57661, 58126, 58570, 58993, 59394, - 59775, 60134, 60472, 60790, 61087, 61363, 61620, 61856, - 62075, 62275, 62458, 62625, 62778, 62918, 63045, 63162, - 63269, 63368, 63459, 63544, 63623, 63698, 63769, 63836, - 63901, 63963, 64023, 64081, 64138, 64194, 64248, 64301, - 64354, 64406, 64457, 64508, 64558, 64608, 64657, 64706, - 64754, 64803, 64851, 64899, 64946, 64994, 65041, 65088, - 65135, 65181, 65227, 65272, 65317, 65361, 65405, 65449, - 65492, 65535 - }; - - static final int SKP_Silk_pitch_lag_NB_CDF_offset = 43; - - static int[] SKP_Silk_pitch_contour_NB_CDF = { - 0, 14445, 18587, 25628, 30013, 34859, 40597, 48426, - 54460, 59033, 62990, 65535 - }; - - static final int SKP_Silk_pitch_contour_NB_CDF_offset = 5; - - static int[] SKP_Silk_pitch_lag_MB_CDF = { - 0, 132, 266, 402, 542, 686, 838, 997, - 1167, 1349, 1546, 1760, 1993, 2248, 2528, 2835, - 3173, 3544, 3951, 4397, 4882, 5411, 5984, 6604, - 7270, 7984, 8745, 9552, 10405, 11300, 12235, 13206, - 14209, 15239, 16289, 17355, 18430, 19507, 20579, 21642, - 22688, 23712, 24710, 25677, 26610, 27507, 28366, 29188, - 29971, 30717, 31427, 32104, 32751, 33370, 33964, 34537, - 35091, 35630, 36157, 36675, 37186, 37692, 38195, 38697, - 39199, 39701, 40206, 40713, 41222, 41733, 42247, 42761, - 43277, 43793, 44309, 44824, 45336, 45845, 46351, 46851, - 47347, 47836, 48319, 48795, 49264, 49724, 50177, 50621, - 51057, 51484, 51902, 52312, 52714, 53106, 53490, 53866, - 54233, 54592, 54942, 55284, 55618, 55944, 56261, 56571, - 56873, 57167, 57453, 57731, 58001, 58263, 58516, 58762, - 58998, 59226, 59446, 59656, 59857, 60050, 60233, 60408, - 60574, 60732, 60882, 61024, 61159, 61288, 61410, 61526, - 61636, 61742, 61843, 61940, 62033, 62123, 62210, 62293, - 62374, 62452, 62528, 62602, 62674, 62744, 62812, 62879, - 62945, 63009, 63072, 63135, 63196, 63256, 63316, 63375, - 63434, 63491, 63549, 63605, 63661, 63717, 63772, 63827, - 63881, 63935, 63988, 64041, 64094, 64147, 64199, 64252, - 64304, 64356, 64409, 64461, 64513, 64565, 64617, 64669, - 64721, 64773, 64824, 64875, 64925, 64975, 65024, 65072, - 65121, 65168, 65215, 65262, 65308, 65354, 65399, 65445, - 65490, 65535 - }; - - static final int SKP_Silk_pitch_lag_MB_CDF_offset = 64; - - static final int[] SKP_Silk_pitch_lag_WB_CDF = { - 0, 106, 213, 321, 429, 539, 651, 766, - 884, 1005, 1132, 1264, 1403, 1549, 1705, 1870, - 2047, 2236, 2439, 2658, 2893, 3147, 3420, 3714, - 4030, 4370, 4736, 5127, 5546, 5993, 6470, 6978, - 7516, 8086, 8687, 9320, 9985, 10680, 11405, 12158, - 12938, 13744, 14572, 15420, 16286, 17166, 18057, 18955, - 19857, 20759, 21657, 22547, 23427, 24293, 25141, 25969, - 26774, 27555, 28310, 29037, 29736, 30406, 31048, 31662, - 32248, 32808, 33343, 33855, 34345, 34815, 35268, 35704, - 36127, 36537, 36938, 37330, 37715, 38095, 38471, 38844, - 39216, 39588, 39959, 40332, 40707, 41084, 41463, 41844, - 42229, 42615, 43005, 43397, 43791, 44186, 44583, 44982, - 45381, 45780, 46179, 46578, 46975, 47371, 47765, 48156, - 48545, 48930, 49312, 49690, 50064, 50433, 50798, 51158, - 51513, 51862, 52206, 52544, 52877, 53204, 53526, 53842, - 54152, 54457, 54756, 55050, 55338, 55621, 55898, 56170, - 56436, 56697, 56953, 57204, 57449, 57689, 57924, 58154, - 58378, 58598, 58812, 59022, 59226, 59426, 59620, 59810, - 59994, 60173, 60348, 60517, 60681, 60840, 60993, 61141, - 61284, 61421, 61553, 61679, 61800, 61916, 62026, 62131, - 62231, 62326, 62417, 62503, 62585, 62663, 62737, 62807, - 62874, 62938, 62999, 63057, 63113, 63166, 63217, 63266, - 63314, 63359, 63404, 63446, 63488, 63528, 63567, 63605, - 63642, 63678, 63713, 63748, 63781, 63815, 63847, 63879, - 63911, 63942, 63973, 64003, 64033, 64063, 64092, 64121, - 64150, 64179, 64207, 64235, 64263, 64291, 64319, 64347, - 64374, 64401, 64428, 64455, 64481, 64508, 64534, 64560, - 64585, 64610, 64635, 64660, 64685, 64710, 64734, 64758, - 64782, 64807, 64831, 64855, 64878, 64902, 64926, 64950, - 64974, 64998, 65022, 65045, 65069, 65093, 65116, 65139, - 65163, 65186, 65209, 65231, 65254, 65276, 65299, 65321, - 65343, 65364, 65386, 65408, 65429, 65450, 65471, 65493, - 65514, 65535 - }; - - static final int SKP_Silk_pitch_lag_WB_CDF_offset = 86; - - static int[] SKP_Silk_pitch_lag_SWB_CDF = { - 0, 253, 505, 757, 1008, 1258, 1507, 1755, - 2003, 2249, 2494, 2738, 2982, 3225, 3469, 3713, - 3957, 4202, 4449, 4698, 4949, 5203, 5460, 5720, - 5983, 6251, 6522, 6798, 7077, 7361, 7650, 7942, - 8238, 8539, 8843, 9150, 9461, 9775, 10092, 10411, - 10733, 11057, 11383, 11710, 12039, 12370, 12701, 13034, - 13368, 13703, 14040, 14377, 14716, 15056, 15398, 15742, - 16087, 16435, 16785, 17137, 17492, 17850, 18212, 18577, - 18946, 19318, 19695, 20075, 20460, 20849, 21243, 21640, - 22041, 22447, 22856, 23269, 23684, 24103, 24524, 24947, - 25372, 25798, 26225, 26652, 27079, 27504, 27929, 28352, - 28773, 29191, 29606, 30018, 30427, 30831, 31231, 31627, - 32018, 32404, 32786, 33163, 33535, 33902, 34264, 34621, - 34973, 35320, 35663, 36000, 36333, 36662, 36985, 37304, - 37619, 37929, 38234, 38535, 38831, 39122, 39409, 39692, - 39970, 40244, 40513, 40778, 41039, 41295, 41548, 41796, - 42041, 42282, 42520, 42754, 42985, 43213, 43438, 43660, - 43880, 44097, 44312, 44525, 44736, 44945, 45153, 45359, - 45565, 45769, 45972, 46175, 46377, 46578, 46780, 46981, - 47182, 47383, 47585, 47787, 47989, 48192, 48395, 48599, - 48804, 49009, 49215, 49422, 49630, 49839, 50049, 50259, - 50470, 50682, 50894, 51107, 51320, 51533, 51747, 51961, - 52175, 52388, 52601, 52813, 53025, 53236, 53446, 53655, - 53863, 54069, 54274, 54477, 54679, 54879, 55078, 55274, - 55469, 55662, 55853, 56042, 56230, 56415, 56598, 56779, - 56959, 57136, 57311, 57484, 57654, 57823, 57989, 58152, - 58314, 58473, 58629, 58783, 58935, 59084, 59230, 59373, - 59514, 59652, 59787, 59919, 60048, 60174, 60297, 60417, - 60533, 60647, 60757, 60865, 60969, 61070, 61167, 61262, - 61353, 61442, 61527, 61609, 61689, 61765, 61839, 61910, - 61979, 62045, 62109, 62170, 62230, 62287, 62343, 62396, - 62448, 62498, 62547, 62594, 62640, 62685, 62728, 62770, - 62811, 62852, 62891, 62929, 62967, 63004, 63040, 63075, - 63110, 63145, 63178, 63212, 63244, 63277, 63308, 63340, - 63371, 63402, 63432, 63462, 63491, 63521, 63550, 63578, - 63607, 63635, 63663, 63690, 63718, 63744, 63771, 63798, - 63824, 63850, 63875, 63900, 63925, 63950, 63975, 63999, - 64023, 64046, 64069, 64092, 64115, 64138, 64160, 64182, - 64204, 64225, 64247, 64268, 64289, 64310, 64330, 64351, - 64371, 64391, 64411, 64431, 64450, 64470, 64489, 64508, - 64527, 64545, 64564, 64582, 64600, 64617, 64635, 64652, - 64669, 64686, 64702, 64719, 64735, 64750, 64766, 64782, - 64797, 64812, 64827, 64842, 64857, 64872, 64886, 64901, - 64915, 64930, 64944, 64959, 64974, 64988, 65003, 65018, - 65033, 65048, 65063, 65078, 65094, 65109, 65125, 65141, - 65157, 65172, 65188, 65204, 65220, 65236, 65252, 65268, - 65283, 65299, 65314, 65330, 65345, 65360, 65375, 65390, - 65405, 65419, 65434, 65449, 65463, 65477, 65492, 65506, - 65521, 65535 - }; - - static final int SKP_Silk_pitch_lag_SWB_CDF_offset = 128; - - static int[] SKP_Silk_pitch_contour_CDF = { - 0, 372, 843, 1315, 1836, 2644, 3576, 4719, - 6088, 7621, 9396, 11509, 14245, 17618, 20777, 24294, - 27992, 33116, 40100, 44329, 47558, 50679, 53130, 55557, - 57510, 59022, 60285, 61345, 62316, 63140, 63762, 64321, - 64729, 65099, 65535 - }; - - static final int SKP_Silk_pitch_contour_CDF_offset = 17; - - static int[] SKP_Silk_pitch_delta_CDF = { - 0, 343, 740, 1249, 1889, 2733, 3861, 5396, - 7552, 10890, 16053, 24152, 30220, 34680, 37973, 40405, - 42243, 43708, 44823, 45773, 46462, 47055, 65535 - }; - - static final int SKP_Silk_pitch_delta_CDF_offset = 11; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_pulses_per_block.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_pulses_per_block.java deleted file mode 100644 index 68d1cbc28..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_pulses_per_block.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_tables_pulses_per_block -{ - static int[] SKP_Silk_max_pulses_table = { - 6, 8, 12, 18 - }; - - static int[][] SKP_Silk_pulses_per_block_CDF = - { - { - 0, 47113, 61501, 64590, 65125, 65277, 65352, 65407, - 65450, 65474, 65488, 65501, 65508, 65514, 65516, 65520, - 65521, 65523, 65524, 65526, 65535 - }, - { - 0, 26368, 47760, 58803, 63085, 64567, 65113, 65333, - 65424, 65474, 65498, 65511, 65517, 65520, 65523, 65525, - 65526, 65528, 65529, 65530, 65535 - }, - { - 0, 9601, 28014, 45877, 57210, 62560, 64611, 65260, - 65447, 65500, 65511, 65519, 65521, 65525, 65526, 65529, - 65530, 65531, 65532, 65534, 65535 - }, - { - 0, 3351, 12462, 25972, 39782, 50686, 57644, 61525, - 63521, 64506, 65009, 65255, 65375, 65441, 65471, 65488, - 65497, 65505, 65509, 65512, 65535 - }, - { - 0, 488, 2944, 9295, 19712, 32160, 43976, 53121, - 59144, 62518, 64213, 65016, 65346, 65470, 65511, 65515, - 65525, 65529, 65531, 65534, 65535 - }, - { - 0, 17013, 30405, 40812, 48142, 53466, 57166, 59845, - 61650, 62873, 63684, 64223, 64575, 64811, 64959, 65051, - 65111, 65143, 65165, 65183, 65535 - }, - { - 0, 2994, 8323, 15845, 24196, 32300, 39340, 45140, - 49813, 53474, 56349, 58518, 60167, 61397, 62313, 62969, - 63410, 63715, 63906, 64056, 65535 - }, - { - 0, 88, 721, 2795, 7542, 14888, 24420, 34593, - 43912, 51484, 56962, 60558, 62760, 64037, 64716, 65069, - 65262, 65358, 65398, 65420, 65535 - }, - { - 0, 287, 789, 2064, 4398, 8174, 13534, 20151, - 27347, 34533, 41295, 47242, 52070, 55772, 58458, 60381, - 61679, 62533, 63109, 63519, 65535 - }, - { - 0, 1, 3, 91, 4521, 14708, 28329, 41955, - 52116, 58375, 61729, 63534, 64459, 64924, 65092, 65164, - 65182, 65198, 65203, 65211, 65535 - } - }; - - static final int SKP_Silk_pulses_per_block_CDF_offset = 6; - - static short[][] SKP_Silk_pulses_per_block_BITS_Q6 = - { - { - 30, 140, 282, 444, 560, 625, 654, 677, - 731, 780, 787, 844, 859, 960, 896, 1024, - 960, 1024, 960, 821 - }, - { - 84, 103, 164, 252, 350, 442, 526, 607, - 663, 731, 787, 859, 923, 923, 960, 1024, - 960, 1024, 1024, 875 - }, - { - 177, 117, 120, 162, 231, 320, 426, 541, - 657, 803, 832, 960, 896, 1024, 923, 1024, - 1024, 1024, 960, 1024 - }, - { - 275, 182, 146, 144, 166, 207, 261, 322, - 388, 450, 516, 582, 637, 710, 762, 821, - 832, 896, 923, 734 - }, - { - 452, 303, 216, 170, 153, 158, 182, 220, - 274, 337, 406, 489, 579, 681, 896, 811, - 896, 960, 923, 1024 - }, - { - 125, 147, 170, 202, 232, 265, 295, 332, - 368, 406, 443, 483, 520, 563, 606, 646, - 704, 739, 757, 483 - }, - { - 285, 232, 200, 190, 193, 206, 224, 244, - 266, 289, 315, 340, 367, 394, 425, 462, - 496, 539, 561, 350 - }, - { - 611, 428, 319, 242, 202, 178, 172, 180, - 199, 229, 268, 313, 364, 422, 482, 538, - 603, 683, 739, 586 - }, - { - 501, 450, 364, 308, 264, 231, 212, 204, - 204, 210, 222, 241, 265, 295, 326, 362, - 401, 437, 469, 321 - } - }; - - static int[][] SKP_Silk_rate_levels_CDF = - { - { - 0, 2005, 12717, 20281, 31328, 36234, 45816, 57753, - 63104, 65535 - }, - { - 0, 8553, 23489, 36031, 46295, 53519, 56519, 59151, - 64185, 65535 - } - }; - - static final int SKP_Silk_rate_levels_CDF_offset = 4; - - static short[][] SKP_Silk_rate_levels_BITS_Q6 = - { - { - 322, 167, 199, 164, 239, 178, 157, 231, - 304 - }, - { - 188, 137, 153, 171, 204, 285, 297, 237, - 358 - } - }; - - static int[] SKP_Silk_shell_code_table0 = { - 0, 32748, 65535, 0, 9505, 56230, 65535, 0, - 4093, 32204, 61720, 65535, 0, 2285, 16207, 48750, - 63424, 65535, 0, 1709, 9446, 32026, 55752, 63876, - 65535, 0, 1623, 6986, 21845, 45381, 59147, 64186, - 65535 - }; - - static int[] SKP_Silk_shell_code_table1 = { - 0, 32691, 65535, 0, 12782, 52752, 65535, 0, - 4847, 32665, 60899, 65535, 0, 2500, 17305, 47989, - 63369, 65535, 0, 1843, 10329, 32419, 55433, 64277, - 65535, 0, 1485, 7062, 21465, 43414, 59079, 64623, - 65535, 0, 0, 4841, 14797, 31799, 49667, 61309, - 65535, 65535, 0, 0, 0, 8032, 21695, 41078, - 56317, 65535, 65535, 65535 - }; - - static int[] SKP_Silk_shell_code_table2 = { - 0, 32615, 65535, 0, 14447, 50912, 65535, 0, - 6301, 32587, 59361, 65535, 0, 3038, 18640, 46809, - 62852, 65535, 0, 1746, 10524, 32509, 55273, 64278, - 65535, 0, 1234, 6360, 21259, 43712, 59651, 64805, - 65535, 0, 1020, 4461, 14030, 32286, 51249, 61904, - 65100, 65535, 0, 851, 3435, 10006, 23241, 40797, - 55444, 63009, 65252, 65535, 0, 0, 2075, 7137, - 17119, 31499, 46982, 58723, 63976, 65535, 65535, 0, - 0, 0, 3820, 11572, 23038, 37789, 51969, 61243, - 65535, 65535, 65535, 0, 0, 0, 0, 6882, - 16828, 30444, 44844, 57365, 65535, 65535, 65535, 65535, - 0, 0, 0, 0, 0, 10093, 22963, 38779, - 54426, 65535, 65535, 65535, 65535, 65535 - }; - - static int[] SKP_Silk_shell_code_table3 = { - 0, 32324, 65535, 0, 15328, 49505, 65535, 0, - 7474, 32344, 57955, 65535, 0, 3944, 19450, 45364, - 61873, 65535, 0, 2338, 11698, 32435, 53915, 63734, - 65535, 0, 1506, 7074, 21778, 42972, 58861, 64590, - 65535, 0, 1027, 4490, 14383, 32264, 50980, 61712, - 65043, 65535, 0, 760, 3022, 9696, 23264, 41465, - 56181, 63253, 65251, 65535, 0, 579, 2256, 6873, - 16661, 31951, 48250, 59403, 64198, 65360, 65535, 0, - 464, 1783, 5181, 12269, 24247, 39877, 53490, 61502, - 64591, 65410, 65535, 0, 366, 1332, 3880, 9273, - 18585, 32014, 45928, 56659, 62616, 64899, 65483, 65535, - 0, 286, 1065, 3089, 6969, 14148, 24859, 38274, - 50715, 59078, 63448, 65091, 65481, 65535, 0, 0, - 482, 2010, 5302, 10408, 18988, 30698, 43634, 54233, - 60828, 64119, 65288, 65535, 65535, 0, 0, 0, - 1006, 3531, 7857, 14832, 24543, 36272, 47547, 56883, - 62327, 64746, 65535, 65535, 65535, 0, 0, 0, - 0, 1863, 4950, 10730, 19284, 29397, 41382, 52335, - 59755, 63834, 65535, 65535, 65535, 65535, 0, 0, - 0, 0, 0, 2513, 7290, 14487, 24275, 35312, - 46240, 55841, 62007, 65535, 65535, 65535, 65535, 65535, - 0, 0, 0, 0, 0, 0, 3606, 9573, - 18764, 28667, 40220, 51290, 59924, 65535, 65535, 65535, - 65535, 65535, 65535, 0, 0, 0, 0, 0, - 0, 0, 4879, 13091, 23376, 36061, 49395, 59315, - 65535, 65535, 65535, 65535, 65535, 65535, 65535 - }; - - static int[] SKP_Silk_shell_code_table_offsets = { - 0, 0, 3, 7, 12, 18, 25, 33, - 42, 52, 63, 75, 88, 102, 117, 133, - 150, 168, 187 - }; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_sign.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_sign.java deleted file mode 100644 index 90e7173a4..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_sign.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_tables_sign -{ - static int[] SKP_Silk_sign_CDF = - { - 37840, 36944, 36251, 35304, - 34715, 35503, 34529, 34296, - 34016, 47659, 44945, 42503, - 40235, 38569, 40254, 37851, - 37243, 36595, 43410, 44121, - 43127, 40978, 38845, 40433, - 38252, 37795, 36637, 59159, - 55630, 51806, 48073, 45036, - 48416, 43857, 42678, 41146, - }; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_type_offset.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_type_offset.java deleted file mode 100644 index 91295d09d..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_tables_type_offset.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_tables_type_offset -{ - static final int[] SKP_Silk_type_offset_CDF = { - 0, 37522, 41030, 44212, 65535 - }; - - static final int SKP_Silk_type_offset_CDF_offset = 2; - - static final int[][] SKP_Silk_type_offset_joint_CDF = - { - { - 0, 57686, 61230, 62358, 65535 - }, - { - 0, 18346, 40067, 43659, 65535 - }, - { - 0, 22694, 24279, 35507, 65535 - }, - { - 0, 6067, 7215, 13010, 65535 - } - }; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_typedef.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_typedef.java deleted file mode 100644 index 9b4f386a1..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_typedef.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_typedef -{ - static int SKP_STR_CASEINSENSITIVE_COMPARE(String x, String y) - { - return x.compareTo(y); - } - - static final long SKP_int64_MAX = 0x7FFFFFFFFFFFFFFFL; // 2^63 - 1 - static final long SKP_int64_MIN = 0x8000000000000000L; // -2^63 - static final int SKP_int32_MAX = 0x7FFFFFFF; // 2^31 - 1 = 2147483647 - static final int SKP_int32_MIN = 0x80000000; // -2^31 = -2147483648 - static final short SKP_int16_MAX = 0x7FFF; // 2^15 - 1 = 32767 - static final short SKP_int16_MIN = (short)0x8000; // -2^15 = -32768 - static final byte SKP_int8_MAX = 0x7F; // 2^7 - 1 = 127 - static final byte SKP_int8_MIN = (byte)0x80; // -2^7 = -128 - - static final long SKP_uint32_MAX = 0xFFFFFFFFL; // 2^32 - 1 = 4294967295 - static final long SKP_uint32_MIN = 0x00000000L; - static final int SKP_uint16_MAX = 0xFFFF; // 2^16 - 1 = 65535 - static final int SKP_uint16_MIN = 0x0000; - static final short SKP_uint8_MAX = 0xFF; // 2^8 - 1 = 255 - static final short SKP_uint8_MIN = 0x00; - - static final boolean SKP_TRUE = true; - static final boolean SKP_FALSE = false; - - /* assertions */ - static void SKP_assert(boolean COND) - { - assert(COND); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_wrappers_FLP.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_wrappers_FLP.java deleted file mode 100644 index 01f139ac2..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/silk/Silk_wrappers_FLP.java +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.silk; - -/** - * - * @author Jing Dai - * @author Dingxin Xu - */ -public class Silk_wrappers_FLP -{ - /* Wrappers. Calls flp / fix code */ - static long ar2_q13_file_offset = 0; - static long x_16_file_offset = 0; - static int frame_cnt = 0; - - /* Convert AR filter coefficients to NLSF parameters */ - static void SKP_Silk_A2NLSF_FLP( - float[] pNLSF, /* O NLSF vector [ LPC_order ] */ - float[] pAR, /* I LPC coefficients [ LPC_order ] */ - final int LPC_order /* I LPC order */ - ) - { - int i; - int[] NLSF_fix = new int[ Silk_define.MAX_LPC_ORDER ]; - int[] a_fix_Q16 = new int[ Silk_define.MAX_LPC_ORDER ]; - - for( i = 0; i < LPC_order; i++ ) - { - a_fix_Q16[ i ] = Silk_SigProc_FLP.SKP_float2int( pAR[ i ] * 65536.0f ); - } - Silk_A2NLSF.SKP_Silk_A2NLSF( NLSF_fix, a_fix_Q16, LPC_order ); - - for( i = 0; i < LPC_order; i++ ) - { - pNLSF[ i ] = NLSF_fix[ i ] * ( 1.0f / 32768.0f ); - } - } - - /* Convert LSF parameters to AR prediction filter coefficients */ - static void SKP_Silk_NLSF2A_stable_FLP( - float [] pAR, /* O LPC coefficients [ LPC_order ] */ - float[] pNLSF, /* I NLSF vector [ LPC_order ] */ - final int LPC_order /* I LPC order */ - ) - { - int i; - int[] NLSF_fix = new int[ Silk_define.MAX_LPC_ORDER ]; - short[] a_fix_Q12 = new short[ Silk_define.MAX_LPC_ORDER ]; - - for( i = 0; i < LPC_order; i++ ) - { - NLSF_fix[ i ] = Silk_SigProc_FLP.SKP_float2int( pNLSF[ i ] * 32768.0f ); - } - - Silk_NLSF2A_stable.SKP_Silk_NLSF2A_stable( a_fix_Q12, NLSF_fix, LPC_order ); - - for( i = 0; i < LPC_order; i++ ) - { - pAR[ i ] = a_fix_Q12[ i ] / 4096.0f; - } - } - - - /* LSF stabilizer, for a single input data vector */ - static void SKP_Silk_NLSF_stabilize_FLP( - float[] pNLSF, /* I/O (Un)stable NLSF vector [ LPC_order ] */ - float[] pNDelta_min, /* I Normalized delta min vector[LPC_order+1]*/ - final int LPC_order /* I LPC order */ - ) - { - int i; - int[] NLSF_Q15 = new int[ Silk_define.MAX_LPC_ORDER ], ndelta_min_Q15 = new int[ Silk_define.MAX_LPC_ORDER + 1 ]; - - for( i = 0; i < LPC_order; i++ ) - { - NLSF_Q15[ i ] = Silk_SigProc_FLP.SKP_float2int( pNLSF[ i ] * 32768.0f ); - ndelta_min_Q15[ i ] = Silk_SigProc_FLP.SKP_float2int( pNDelta_min[ i ] * 32768.0f ); - } - ndelta_min_Q15[ LPC_order ] = Silk_SigProc_FLP.SKP_float2int( pNDelta_min[ LPC_order ] * 32768.0f ); - - /* NLSF stabilizer, for a single input data vector */ - Silk_NLSF_stabilize.SKP_Silk_NLSF_stabilize( NLSF_Q15,0, ndelta_min_Q15, LPC_order ); - - for( i = 0; i < LPC_order; i++ ) - { - pNLSF[ i ] = NLSF_Q15[ i ] * ( 1.0f / 32768.0f ); - } - } - - /* Interpolation function with fixed point rounding */ - static void SKP_Silk_interpolate_wrapper_FLP( - float xi[], /* O Interpolated vector */ - float x0[], /* I First vector */ - float x1[], /* I Second vector */ - final float ifact, /* I Interp. factor, weight on second vector */ - final int d /* I Number of parameters */ - ) - { - int[] x0_int = new int[ Silk_define.MAX_LPC_ORDER ], x1_int = new int[ Silk_define.MAX_LPC_ORDER ], xi_int = new int[ Silk_define.MAX_LPC_ORDER ]; - int ifact_Q2 = ( int )( ifact * 4.0f ); - int i; - - /* Convert input from flp to fix */ - for( i = 0; i < d; i++ ) { - x0_int[ i ] = Silk_SigProc_FLP.SKP_float2int( x0[ i ] * 32768.0f ); - x1_int[ i ] = Silk_SigProc_FLP.SKP_float2int( x1[ i ] * 32768.0f ); - } - - /* Interpolate two vectors */ - Silk_interpolate.SKP_Silk_interpolate( xi_int, x0_int, x1_int, ifact_Q2, d ); - - /* Convert output from fix to flp */ - for( i = 0; i < d; i++ ) - { - xi[ i ] = xi_int[ i ] * ( 1.0f / 32768.0f ); - } - } - - /****************************************/ - /* Floating-point Silk VAD wrapper */ - /****************************************/ - static int SKP_Silk_VAD_FLP( - SKP_Silk_encoder_state_FLP psEnc, /* I/O Encoder state FLP */ - SKP_Silk_encoder_control_FLP psEncCtrl, /* I/O Encoder control FLP */ - short[] pIn, /* I Input signal */ - int pIn_offset - ) - { - int i, ret; - int[] SA_Q8 = new int[1], SNR_dB_Q7 = new int[1], Tilt_Q15 = new int[1]; - int[] Quality_Bands_Q15 = new int[ Silk_define.VAD_N_BANDS ]; - - ret = Silk_VAD.SKP_Silk_VAD_GetSA_Q8( psEnc.sCmn.sVAD, SA_Q8, SNR_dB_Q7, Quality_Bands_Q15, Tilt_Q15, - pIn,pIn_offset, psEnc.sCmn.frame_length ); - - psEnc.speech_activity = SA_Q8[0] / 256.0f; - for( i = 0; i < Silk_define.VAD_N_BANDS; i++ ) - { - psEncCtrl.input_quality_bands[ i ] = Quality_Bands_Q15[ i ] / 32768.0f; - } - psEncCtrl.input_tilt = Tilt_Q15[0] / 32768.0f; - - return ret; - } - - /****************************************/ - /* Floating-point Silk NSQ wrapper */ - /****************************************/ - static void SKP_Silk_NSQ_wrapper_FLP( - SKP_Silk_encoder_state_FLP psEnc, /* I/O Encoder state FLP */ - SKP_Silk_encoder_control_FLP psEncCtrl, /* I/O Encoder control FLP */ - float x[], /* I Prefiltered input signal */ - int x_offset, - byte q[], /* O Quantized pulse signal */ - int q_offset, - final int useLBRR /* I LBRR flag */ - ) - { - int i, j; - float tmp_float; - short[] x_16 = new short[ Silk_define.MAX_FRAME_LENGTH ]; - /* Prediction and coding parameters */ - int[] Gains_Q16 = new int[ Silk_define.NB_SUBFR ]; - short[][] PredCoef_Q12 = new short[ 2 ][ Silk_define.MAX_LPC_ORDER ]; - short[] LTPCoef_Q14 = new short[ Silk_define.LTP_ORDER * Silk_define.NB_SUBFR ]; - int LTP_scale_Q14; - - /* Noise shaping parameters */ - /* Testing */ - short[] AR2_Q13 = new short[ Silk_define.NB_SUBFR * Silk_define.SHAPE_LPC_ORDER_MAX ]; - int[] LF_shp_Q14 = new int[ Silk_define.NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */ - int Lambda_Q10; - int[] Tilt_Q14 = new int[ Silk_define.NB_SUBFR ]; - int[] HarmShapeGain_Q14 = new int[ Silk_define.NB_SUBFR ]; - - /* Convert control struct to fix control struct */ - /* Noise shape parameters */ - for( i = 0; i < Silk_define.NB_SUBFR * Silk_define.SHAPE_LPC_ORDER_MAX; i++ ) - { - AR2_Q13[ i ] = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FLP.SKP_float2int( psEncCtrl.AR2[ i ] * 8192.0f ) ); - } - - /*TEST************************************************************************/ - /* - * test of the AR2_Q13 - * - */ - short[] ar2_q13 = new short[ Silk_define.NB_SUBFR * Silk_define.SHAPE_LPC_ORDER_MAX ]; - String ar2_q13_filename = "D:/gsoc/ar2_q13"; - -// /* -// * Option 1: -// */ -// DataInputStream ar2_q13_datain = null; -// try -// { -// ar2_q13_datain = new DataInputStream( -// new FileInputStream( -// new File(ar2_q13_filename))); -// -// for( i = 0; i < Silk_define.NB_SUBFR * Silk_define.SHAPE_LPC_ORDER_MAX; i++ ) -// { -// // AR2_Q13[ i ] = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FLP.SKP_float2int( psEncCtrl.AR2[ i ] * 8192.0f ) ); -// try -// { -// ar2_q13[i] = ar2_q13_datain.readShort(); -// AR2_Q13[i] = (short) (((ar2_q13[i] << 8) & 0xFF00) | ((ar2_q13[i] >>> 8) & 0x00FF)); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// try -// { -// ar2_q13_datain.close(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// catch (FileNotFoundException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } - /* - * Option 2; - */ -// RandomAccessFile ar2_q13_datain_rand = null; -// try -// { -// ar2_q13_datain_rand = new RandomAccessFile(new File(ar2_q13_filename), "r"); -// try -// { -// ar2_q13_datain_rand.seek(ar2_q13_file_offset); -// for( i = 0; i < Silk_define.NB_SUBFR * Silk_define.SHAPE_LPC_ORDER_MAX; i++ ) -// { -// // AR2_Q13[ i ] = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FLP.SKP_float2int( psEncCtrl.AR2[ i ] * 8192.0f ) ); -// try -// { -// ar2_q13[i] = ar2_q13_datain_rand.readShort(); -// AR2_Q13[i] = (short) (((ar2_q13[i] << 8) & 0xFF00) | ((ar2_q13[i] >>> 8) & 0x00FF)); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// ar2_q13_file_offset += i; -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// -// try -// { -// ar2_q13_datain_rand.close(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// catch (FileNotFoundException e1) -// { -// // TODO Auto-generated catch block -// e1.printStackTrace(); -// } - - /** - * Option 3: - */ -// ar2_q13_filename += frame_cnt; -// DataInputStream ar2_q13_datain = null; -// try -// { -// ar2_q13_datain = new DataInputStream( -// new FileInputStream( -// new File(ar2_q13_filename))); -// -// for( i = 0; i < Silk_define.NB_SUBFR * Silk_define.SHAPE_LPC_ORDER_MAX; i++ ) -// { -// // AR2_Q13[ i ] = (short)Silk_SigProc_FIX.SKP_SAT16( Silk_SigProc_FLP.SKP_float2int( psEncCtrl.AR2[ i ] * 8192.0f ) ); -// try -// { -// ar2_q13[i] = ar2_q13_datain.readShort(); -// AR2_Q13[i] = (short) (((ar2_q13[i] << 8) & 0xFF00) | ((ar2_q13[i] >>> 8) & 0x00FF)); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// try -// { -// ar2_q13_datain.close(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// catch (FileNotFoundException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } - /*TEST End***********************************************************************/ - - for( i = 0; i < Silk_define.NB_SUBFR; i++ ) - { - LF_shp_Q14[ i ] = ( Silk_SigProc_FLP.SKP_float2int( psEncCtrl.LF_AR_shp[ i ] * 16384.0f ) << 16 ) | - ( 0x0000FFFF & Silk_SigProc_FLP.SKP_float2int( psEncCtrl.LF_MA_shp[ i ] * 16384.0f ) ); - Tilt_Q14[ i ] = Silk_SigProc_FLP.SKP_float2int( psEncCtrl.Tilt[ i ] * 16384.0f ); - HarmShapeGain_Q14[ i ] = Silk_SigProc_FLP.SKP_float2int( psEncCtrl.HarmShapeGain[ i ] * 16384.0f ); - } - Lambda_Q10 = Silk_SigProc_FLP.SKP_float2int( psEncCtrl.Lambda * 1024.0f ); - - /* prediction and coding parameters */ - for( i = 0; i < Silk_define.NB_SUBFR * Silk_define.LTP_ORDER; i++ ) - { - LTPCoef_Q14[ i ] = ( short )Silk_SigProc_FLP.SKP_float2int( psEncCtrl.LTPCoef[ i ] * 16384.0f ); - } - - for( j = 0; j < Silk_define.NB_SUBFR >> 1; j++ ) - { - for( i = 0; i < Silk_define.MAX_LPC_ORDER; i++ ) - { - PredCoef_Q12[ j ][ i ] = ( short )Silk_SigProc_FLP.SKP_float2int( psEncCtrl.PredCoef[ j ][ i ] * 4096.0f ); - } - } - - for( i = 0; i < Silk_define.NB_SUBFR; i++ ) - { - tmp_float = Silk_SigProc_FIX.SKP_LIMIT( ( psEncCtrl.Gains[ i ] * 65536.0f ), 2147483000.0f, -2147483000.0f ); - Gains_Q16[ i ] = Silk_SigProc_FLP.SKP_float2int( tmp_float ); - if( psEncCtrl.Gains[ i ] > 0.0f ) - { - assert( tmp_float >= 0.0f ); - assert( Gains_Q16[ i ] >= 0 ); - } - } - - if( psEncCtrl.sCmn.sigtype == Silk_define.SIG_TYPE_VOICED ) { - - LTP_scale_Q14 = Silk_tables_other.SKP_Silk_LTPScales_table_Q14[ psEncCtrl.sCmn.LTP_scaleIndex ]; - } - else - { - LTP_scale_Q14 = 0; - } - - /* Convert input to fix */ - Silk_SigProc_FLP.SKP_float2short_array( x_16,0, x,x_offset, psEnc.sCmn.frame_length ); - - /*TEST************************************************************************/ - /** - * test of x_16 - */ - short x_16_test[] = new short[ Silk_define.MAX_FRAME_LENGTH ]; - String x_16_filename = "D:/gsoc/x_16"; -// /* -// * Option 1: -// */ -// DataInputStream x_16_datain = null; -// try -// { -// x_16_datain = new DataInputStream( -// new FileInputStream( -// new File(x_16_filename))); -// for(int k = 0; k < psEnc.sCmn.frame_length; k++) -// { -// try -// { -// x_16_test[k] = x_16_datain.readShort(); -// x_16[k] = (short) (((x_16_test[k]<<8)&0xFF00)|((x_16_test[k]>>>8)&0x00FF)); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// try -// { -// x_16_datain.close(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// catch (FileNotFoundException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } - - /* - * Option 2: - */ -// RandomAccessFile x_16_datain_rand = null; -// int k; -// try -// { -// x_16_datain_rand = new RandomAccessFile(new File(x_16_filename), "r"); -// try -// { -// x_16_datain_rand.seek(x_16_file_offset); -// for(k = 0; k < psEnc.sCmn.frame_length; k++) -// { -// try -// { -// x_16_test[k] = x_16_datain_rand.readShort(); -// x_16[k] = (short) (((x_16_test[k]<<8)&0xFF00)|((x_16_test[k]>>>8)&0x00FF)); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// x_16_file_offset += k; -// } -// catch (IOException e1) -// { -// // TODO Auto-generated catch block -// e1.printStackTrace(); -// } -// try -// { -// x_16_datain_rand.close(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// catch (FileNotFoundException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } - - /** - * Optino 3: - */ -// x_16_filename += frame_cnt; -// DataInputStream x_16_datain = null; -// try -// { -// x_16_datain = new DataInputStream( -// new FileInputStream( -// new File(x_16_filename))); -// for(int k = 0; k < psEnc.sCmn.frame_length; k++) -// { -// try -// { -// x_16_test[k] = x_16_datain.readShort(); -// x_16[k] = (short) (((x_16_test[k]<<8)&0xFF00)|((x_16_test[k]>>>8)&0x00FF)); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// try -// { -// x_16_datain.close(); -// } -// catch (IOException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// } -// catch (FileNotFoundException e) -// { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// frame_cnt++; - /*TEST END************************************************************************/ - - /* Call NSQ */ - short[] PredCoef_Q12_dim1_tmp= new short[PredCoef_Q12.length * PredCoef_Q12[0].length]; - int PredCoef_Q12_offset = 0; - for(int PredCoef_Q12_i = 0; PredCoef_Q12_i < PredCoef_Q12.length; PredCoef_Q12_i++) - { - System.arraycopy(PredCoef_Q12[PredCoef_Q12_i],0, PredCoef_Q12_dim1_tmp, PredCoef_Q12_offset, PredCoef_Q12[PredCoef_Q12_i].length); - PredCoef_Q12_offset += PredCoef_Q12[PredCoef_Q12_i].length; - } - if( useLBRR!=0 ) - { -// psEnc.NoiseShapingQuantizer( psEnc.sCmn, psEncCtrl.sCmn, psEnc.sNSQ_LBRR, -// x_16, q, psEncCtrl.sCmn.NLSFInterpCoef_Q2, PredCoef_Q12[ 0 ], LTPCoef_Q14, AR2_Q13, -// HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, Lambda_Q10, LTP_scale_Q14 );\ - psEnc.NoiseShapingQuantizer( psEnc.sCmn, psEncCtrl.sCmn, psEnc.sNSQ_LBRR, - x_16, q, psEncCtrl.sCmn.NLSFInterpCoef_Q2, PredCoef_Q12_dim1_tmp, LTPCoef_Q14, AR2_Q13, - HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, Lambda_Q10, LTP_scale_Q14 ); -// psEnc.NoiseShapingQuantizer( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sNSQ_LBRR, -// x_16, q, psEncCtrl->sCmn.NLSFInterpCoef_Q2, PredCoef_Q12[ 0 ], LTPCoef_Q14, AR2_Q13, -// HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, Lambda_Q10, LTP_scale_Q14 ); - } - else - { -// psEnc.NoiseShapingQuantizer( psEnc.sCmn, psEncCtrl.sCmn, psEnc.sNSQ, -// x_16, q, psEncCtrl.sCmn.NLSFInterpCoef_Q2, PredCoef_Q12[ 0 ], LTPCoef_Q14, AR2_Q13, -// HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, Lambda_Q10, LTP_scale_Q14 ); - psEnc.NoiseShapingQuantizer( psEnc.sCmn, psEncCtrl.sCmn, psEnc.sNSQ, - x_16, q, psEncCtrl.sCmn.NLSFInterpCoef_Q2, PredCoef_Q12_dim1_tmp, LTPCoef_Q14, AR2_Q13, - HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, Lambda_Q10, LTP_scale_Q14 ); -// psEnc.NoiseShapingQuantizer( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sNSQ, -// x_16, q, psEncCtrl->sCmn.NLSFInterpCoef_Q2, PredCoef_Q12[ 0 ], LTPCoef_Q14, AR2_Q13, -// HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, Lambda_Q10, LTP_scale_Q14 ); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/JNIDecoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/JNIDecoder.java deleted file mode 100644 index 19b9a3f05..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/JNIDecoder.java +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.speex; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.sf.fmj.media.*; - -/** - * Implements a Speex decoder and RTP depacketizer using the native Speex - * library. - * - * @author Lubomir Marinov - */ -public class JNIDecoder - extends AbstractCodecExt -{ - - /** - * The list of Formats of audio data supported as input by - * JNIDecoder instances. - */ - private static final Format[] SUPPORTED_INPUT_FORMATS; - - /** - * The list of Formats of audio data supported as output by - * JNIDecoder instances. - */ - private static final Format[] SUPPORTED_OUTPUT_FORMATS - = new Format[] - { - new AudioFormat( - AudioFormat.LINEAR, - Format.NOT_SPECIFIED, - 16, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED, - Format.byteArray) - }; - - static - { - Speex.assertSpeexIsFunctional(); - - double[] SUPPORTED_INPUT_SAMPLE_RATES - = JNIEncoder.SUPPORTED_INPUT_SAMPLE_RATES; - int supportedInputCount = SUPPORTED_INPUT_SAMPLE_RATES.length; - - SUPPORTED_INPUT_FORMATS = new Format[supportedInputCount]; - for (int i = 0; i < supportedInputCount; i++) - { - SUPPORTED_INPUT_FORMATS[i] - = new AudioFormat( - Constants.SPEEX_RTP, - SUPPORTED_INPUT_SAMPLE_RATES[i], - Format.NOT_SPECIFIED, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED, - Format.byteArray); - } - } - - /** - * The pointer to the native SpeexBits from which the native Speex - * decoder (i.e. {@link #state}) reads the encoded audio data. - */ - private long bits = 0; - - /** - * The duration in nanoseconds of an output Buffer produced by this - * Codec. - */ - private long duration = 0; - - /** - * The number of bytes from an input Buffer that this - * Codec processes in one call of its - * {@link #process(Buffer, Buffer)}. - */ - private int frameSize = 0; - - /** - * The sample rate configured into {@link #state}. - */ - private int sampleRate = 0; - - /** - * The native Speex decoder represented by this instance. - */ - private long state = 0; - - /** - * Initializes a new JNIDecoder instance. - */ - public JNIDecoder() - { - super( - "Speex JNI Decoder", - AudioFormat.class, - SUPPORTED_OUTPUT_FORMATS); - - inputFormats = SUPPORTED_INPUT_FORMATS; - } - - /** - * @see AbstractCodecExt#doClose() - */ - protected void doClose() - { - // state - if (state != 0) - { - Speex.speex_decoder_destroy(state); - state = 0; - sampleRate = 0; - frameSize = 0; - duration = 0; - } - // bits - Speex.speex_bits_destroy(bits); - bits = 0; - } - - /** - * Opens this Codec and acquires the resources that it needs to - * operate. A call to {@link PlugIn#open()} on this instance will result in - * a call to doOpen only if {@link AbstractCodec#opened} is - * false. All required input and/or output formats are assumed to - * have been set on this Codec before doOpen is called. - * - * @throws ResourceUnavailableException if any of the resources that this - * Codec needs to operate cannot be acquired - * @see AbstractCodecExt#doOpen() - */ - protected void doOpen() - throws ResourceUnavailableException - { - bits = Speex.speex_bits_init(); - if (bits == 0) - throw new ResourceUnavailableException("speex_bits_init"); - } - - /** - * Decodes Speex media from a specific input Buffer - * - * @param inputBuffer input Buffer - * @param outputBuffer output Buffer - * @return BUFFER_PROCESSED_OK if inBuffer has been - * successfully processed - * @see AbstractCodecExt#doProcess(Buffer, Buffer) - */ - protected int doProcess(Buffer inputBuffer, Buffer outputBuffer) - { - Format inputFormat = inputBuffer.getFormat(); - - if ((inputFormat != null) - && (inputFormat != this.inputFormat) - && !inputFormat.equals(this.inputFormat)) - { - if (null == setInputFormat(inputFormat)) - return BUFFER_PROCESSED_FAILED; - } - inputFormat = this.inputFormat; - - /* - * Make sure that the native Speex decoder which is represented by this - * instance is configured to work with the inputFormat. - */ - AudioFormat inputAudioFormat = (AudioFormat) inputFormat; - int inputSampleRate = (int) inputAudioFormat.getSampleRate(); - - if ((state != 0) && (sampleRate != inputSampleRate)) - { - Speex.speex_decoder_destroy(state); - state = 0; - sampleRate = 0; - frameSize = 0; - } - if (state == 0) - { - long mode - = Speex.speex_lib_get_mode( - (inputSampleRate == 16000) - ? Speex.SPEEX_MODEID_WB - : (inputSampleRate == 32000) - ? Speex.SPEEX_MODEID_UWB - : Speex.SPEEX_MODEID_NB); - - if (mode == 0) - return BUFFER_PROCESSED_FAILED; - state = Speex.speex_decoder_init(mode); - if (state == 0) - return BUFFER_PROCESSED_FAILED; - if (Speex.speex_decoder_ctl( - state, - Speex.SPEEX_SET_ENH, - 1) - != 0) - return BUFFER_PROCESSED_FAILED; - if (Speex.speex_decoder_ctl( - state, - Speex.SPEEX_SET_SAMPLING_RATE, - inputSampleRate) - != 0) - return BUFFER_PROCESSED_FAILED; - - int frameSize - = Speex.speex_decoder_ctl(state, Speex.SPEEX_GET_FRAME_SIZE); - - if (frameSize < 0) - return BUFFER_PROCESSED_FAILED; - - sampleRate = inputSampleRate; - this.frameSize = frameSize * 2 /* (sampleSizeInBits / 8) */; - duration = (long) ((frameSize * 1000 * 1000000) / sampleRate); - } - - /* Read the encoded audio data from inputBuffer into the SpeexBits. */ - int inputLength = inputBuffer.getLength(); - - if (inputLength > 0) - { - byte[] input = (byte[]) inputBuffer.getData(); - int inputOffset = inputBuffer.getOffset(); - - Speex.speex_bits_read_from(bits, input, inputOffset, inputLength); - inputLength = 0; - inputBuffer.setLength(inputLength); - inputBuffer.setOffset(inputOffset + inputLength); - } - - /* At long last, do the actual decoding. */ - int outputLength = this.frameSize; - boolean inputBufferNotConsumed; - - if (outputLength > 0) - { - byte[] output = validateByteArraySize(outputBuffer, outputLength); - - if (0 == Speex.speex_decode_int(state, bits, output, 0)) - { - outputBuffer.setDuration(duration); - outputBuffer.setFormat(getOutputFormat()); - outputBuffer.setLength(outputLength); - outputBuffer.setOffset(0); - inputBufferNotConsumed = (Speex.speex_bits_remaining(bits) > 0); - } - else - { - outputBuffer.setLength(0); - discardOutputBuffer(outputBuffer); - inputBufferNotConsumed = false; - } - } - else - { - outputBuffer.setLength(0); - discardOutputBuffer(outputBuffer); - inputBufferNotConsumed = false; - } - - if ((inputLength < 1) && !inputBufferNotConsumed) - return BUFFER_PROCESSED_OK; - else - return BUFFER_PROCESSED_OK | INPUT_BUFFER_NOT_CONSUMED; - } - - /** - * Get all supported output Formats. - * - * @param inputFormat input Format to determine corresponding output - * Format/tt>s - * @return array of supported Format - * @see AbstractCodecExt#getMatchingOutputFormats(Format) - */ - @Override - protected Format[] getMatchingOutputFormats(Format inputFormat) - { - AudioFormat inputAudioFormat = (AudioFormat) inputFormat; - - return - new Format[] - { - new AudioFormat( - AudioFormat.LINEAR, - inputAudioFormat.getSampleRate(), - 16, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED, - Format.byteArray) - }; - } - - /** - * Sets the Format of the media data to be input for processing in - * this Codec. - * - * @param format the Format of the media data to be input for - * processing in this Codec - * @return the Format of the media data to be input for processing - * in this Codec if format is compatible with this - * Codec; otherwise, null - * @see AbstractCodecExt#setInputFormat(Format) - */ - @Override - public Format setInputFormat(Format format) - { - Format inputFormat = super.setInputFormat(format); - - if (inputFormat != null) - { - double outputSampleRate; - int outputChannels; - - if (outputFormat == null) - { - outputSampleRate = Format.NOT_SPECIFIED; - outputChannels = Format.NOT_SPECIFIED; - } - else - { - AudioFormat outputAudioFormat = (AudioFormat) outputFormat; - - outputSampleRate = outputAudioFormat.getSampleRate(); - outputChannels = outputAudioFormat.getChannels(); - } - - AudioFormat inputAudioFormat = (AudioFormat) inputFormat; - double inputSampleRate = inputAudioFormat.getSampleRate(); - int inputChannels = inputAudioFormat.getChannels(); - - if ((outputSampleRate != inputSampleRate) - || (outputChannels != inputChannels)) - { - setOutputFormat( - new AudioFormat( - AudioFormat.LINEAR, - inputSampleRate, - 16, - inputChannels, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED, - Format.byteArray)); - } - } - return inputFormat; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/JNIEncoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/JNIEncoder.java deleted file mode 100644 index 3993ed91a..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/JNIEncoder.java +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.speex; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.sf.fmj.media.*; - -/** - * Implements a Speex encoder and RTP packetizer using the native Speex library. - * - * @author Lubomir Marinov - */ -public class JNIEncoder - extends AbstractCodecExt -{ - - /** - * The list of Formats of audio data supported as input by - * JNIEncoder instances. - */ - private static final Format[] SUPPORTED_INPUT_FORMATS; - - /** - * The list of sample rates of audio data supported as input by - * JNIEncoder instances. - */ - static final double[] SUPPORTED_INPUT_SAMPLE_RATES - = new double[] { 8000, 16000, 32000 }; - - /** - * The list of Formats of audio data supported as output by - * JNIEncoder instances. - */ - private static final Format[] SUPPORTED_OUTPUT_FORMATS - = new Format[] { new AudioFormat(Constants.SPEEX_RTP) }; - - static - { - Speex.assertSpeexIsFunctional(); - - int supportedInputCount = SUPPORTED_INPUT_SAMPLE_RATES.length; - - SUPPORTED_INPUT_FORMATS = new Format[supportedInputCount]; - for (int i = 0; i < supportedInputCount; i++) - { - SUPPORTED_INPUT_FORMATS[i] - = new AudioFormat( - AudioFormat.LINEAR, - SUPPORTED_INPUT_SAMPLE_RATES[i], - 16, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED, - Format.byteArray); - } - } - - /** - * The pointer to the native SpeexBits into which the native Speex - * encoder (i.e. {@link #state}) writes the encoded audio data. - */ - private long bits = 0; - - /** - * The duration in nanoseconds of an output Buffer produced by this - * Codec. - */ - private long duration = 0; - - /** - * The number of bytes from an input Buffer that this - * Codec processes in one call of its - * {@link #process(Buffer, Buffer)}. - */ - private int frameSize = 0; - - /** - * The bytes from an input Buffer from a previous call to - * {@link #process(Buffer, Buffer)} that this Codec didn't process - * because the total number of bytes was less than {@link #frameSize} and - * need to be prepended to a subsequent input Buffer in order to - * process a total of {@link #frameSize} bytes. - */ - private byte[] previousInput; - - /** - * The length of the audio data in {@link #previousInput}. - */ - private int previousInputLength = 0; - - /** - * The sample rate configured into {@link #state}. - */ - private int sampleRate = 0; - - /** - * The native Speex encoder represented by this instance. - */ - private long state = 0; - - /** - * Initializes a new JNIEncoder instance. - */ - public JNIEncoder() - { - super( - "Speex JNI Encoder", - AudioFormat.class, - SUPPORTED_OUTPUT_FORMATS); - - inputFormats = SUPPORTED_INPUT_FORMATS; - } - - /** - * @see AbstractCodecExt#doClose() - */ - protected void doClose() - { - // state - if (state != 0) - { - Speex.speex_encoder_destroy(state); - state = 0; - sampleRate = 0; - frameSize = 0; - duration = 0; - } - // bits - Speex.speex_bits_destroy(bits); - bits = 0; - // previousInput - previousInput = null; - } - - /** - * Opens this Codec and acquires the resources that it needs to - * operate. A call to {@link PlugIn#open()} on this instance will result in - * a call to doOpen only if {@link AbstractCodec#opened} is - * false. All required input and/or output formats are assumed to - * have been set on this Codec before doOpen is called. - * - * @throws ResourceUnavailableException if any of the resources that this - * Codec needs to operate cannot be acquired - * @see AbstractCodecExt#doOpen() - */ - protected void doOpen() - throws ResourceUnavailableException - { - bits = Speex.speex_bits_init(); - if (bits == 0) - throw new ResourceUnavailableException("speex_bits_init"); - } - - /** - * Processes (encode) a specific input Buffer. - * - * @param inputBuffer input buffer - * @param outputBuffer output buffer - * @return BUFFER_PROCESSED_OK if buffer has been successfully - * processed - * @see AbstractCodecExt#doProcess(Buffer, Buffer) - */ - protected int doProcess(Buffer inputBuffer, Buffer outputBuffer) - { - Format inputFormat = inputBuffer.getFormat(); - - if ((inputFormat != null) - && (inputFormat != this.inputFormat) - && !inputFormat.equals(this.inputFormat)) - { - if (null == setInputFormat(inputFormat)) - return BUFFER_PROCESSED_FAILED; - } - inputFormat = this.inputFormat; - - /* - * Make sure that the native Speex encoder which is represented by this - * instance is configured to work with the inputFormat. - */ - AudioFormat inputAudioFormat = (AudioFormat) inputFormat; - int inputSampleRate = (int) inputAudioFormat.getSampleRate(); - - if ((state != 0) && (sampleRate != inputSampleRate)) - { - Speex.speex_encoder_destroy(state); - state = 0; - sampleRate = 0; - frameSize = 0; - } - if (state == 0) - { - long mode - = Speex.speex_lib_get_mode( - (inputSampleRate == 16000) - ? Speex.SPEEX_MODEID_WB - : (inputSampleRate == 32000) - ? Speex.SPEEX_MODEID_UWB - : Speex.SPEEX_MODEID_NB); - - if (mode == 0) - return BUFFER_PROCESSED_FAILED; - state = Speex.speex_encoder_init(mode); - if (state == 0) - return BUFFER_PROCESSED_FAILED; - if (Speex.speex_encoder_ctl( - state, - Speex.SPEEX_SET_QUALITY, - 4) - != 0) - return BUFFER_PROCESSED_FAILED; - if (Speex.speex_encoder_ctl( - state, - Speex.SPEEX_SET_SAMPLING_RATE, - inputSampleRate) - != 0) - return BUFFER_PROCESSED_FAILED; - - int frameSize - = Speex.speex_encoder_ctl(state, Speex.SPEEX_GET_FRAME_SIZE); - - if (frameSize < 0) - return BUFFER_PROCESSED_FAILED; - - sampleRate = inputSampleRate; - this.frameSize = frameSize * 2 /* (sampleSizeInBits / 8) */; - duration - = (((long) frameSize) * 1000 * 1000000) / ((long) sampleRate); - } - - /* - * The native Speex encoder always processes frameSize bytes from the - * input in one call. If any specified inputBuffer is with a different - * length, then we'll have to wait for more bytes to arrive until we - * have frameSize bytes. Remember whatever is left unprocessed in - * previousInput and prepend it to the next inputBuffer. - */ - byte[] input = (byte[]) inputBuffer.getData(); - int inputLength = inputBuffer.getLength(); - int inputOffset = inputBuffer.getOffset(); - - if ((previousInput != null) && (previousInputLength > 0)) - { - if (previousInputLength < this.frameSize) - { - if (previousInput.length < this.frameSize) - { - byte[] newPreviousInput = new byte[this.frameSize]; - - System.arraycopy( - previousInput, 0, - newPreviousInput, 0, - previousInput.length); - previousInput = newPreviousInput; - } - - int bytesToCopyFromInputToPreviousInput - = Math.min( - this.frameSize - previousInputLength, - inputLength); - - if (bytesToCopyFromInputToPreviousInput > 0) - { - System.arraycopy( - input, inputOffset, - previousInput, previousInputLength, - bytesToCopyFromInputToPreviousInput); - previousInputLength += bytesToCopyFromInputToPreviousInput; - inputLength -= bytesToCopyFromInputToPreviousInput; - inputBuffer.setLength(inputLength); - inputBuffer.setOffset( - inputOffset + bytesToCopyFromInputToPreviousInput); - } - } - - if (previousInputLength == this.frameSize) - { - input = previousInput; - inputOffset = 0; - previousInputLength = 0; - } - else if (previousInputLength > this.frameSize) - { - input = new byte[this.frameSize]; - System.arraycopy(previousInput, 0, input, 0, input.length); - inputOffset = 0; - previousInputLength -= input.length; - System.arraycopy( - previousInput, input.length, - previousInput, 0, - previousInputLength); - } - else - { - outputBuffer.setLength(0); - discardOutputBuffer(outputBuffer); - if (inputLength < 1) - return BUFFER_PROCESSED_OK; - else - return BUFFER_PROCESSED_OK | INPUT_BUFFER_NOT_CONSUMED; - } - } - else if (inputLength < 1) - { - outputBuffer.setLength(0); - discardOutputBuffer(outputBuffer); - return BUFFER_PROCESSED_OK; - } - else if (inputLength < this.frameSize) - { - if ((previousInput == null) || (previousInput.length < inputLength)) - previousInput = new byte[this.frameSize]; - System.arraycopy(input, inputOffset, previousInput, 0, inputLength); - previousInputLength = inputLength; - outputBuffer.setLength(0); - discardOutputBuffer(outputBuffer); - return BUFFER_PROCESSED_OK; - } - else - { - inputLength -= this.frameSize; - inputBuffer.setLength(inputLength); - inputBuffer.setOffset(inputOffset + this.frameSize); - } - - /* At long last, do the actual encoding. */ - Speex.speex_bits_reset(bits); - Speex.speex_encode_int(state, input, inputOffset, bits); - - /* Read the encoded audio data from the SpeexBits into outputBuffer. */ - int outputLength = Speex.speex_bits_nbytes(bits); - - if (outputLength > 0) - { - byte[] output = validateByteArraySize(outputBuffer, outputLength); - - outputLength - = Speex.speex_bits_write(bits, output, 0, output.length); - if (outputLength > 0) - { - outputBuffer.setDuration(duration); - outputBuffer.setFormat(getOutputFormat()); - outputBuffer.setLength(outputLength); - outputBuffer.setOffset(0); - } - else - { - outputBuffer.setLength(0); - discardOutputBuffer(outputBuffer); - } - } - else - { - outputBuffer.setLength(0); - discardOutputBuffer(outputBuffer); - } - - if (inputLength < 1) - return BUFFER_PROCESSED_OK; - else - return BUFFER_PROCESSED_OK | INPUT_BUFFER_NOT_CONSUMED; - } - - /** - * Get the output formats matching a specific input format. - * - * @param inputFormat the input format to get the matching output formats of - * @return the output formats matching the specified input format - * @see AbstractCodecExt#getMatchingOutputFormats(Format) - */ - @Override - protected Format[] getMatchingOutputFormats(Format inputFormat) - { - AudioFormat inputAudioFormat = (AudioFormat) inputFormat; - - return - new Format[] - { - new AudioFormat( - Constants.SPEEX_RTP, - inputAudioFormat.getSampleRate(), - Format.NOT_SPECIFIED, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED, - Format.byteArray) - }; - } - - /** - * Get the output format. - * - * @return output format - * @see net.sf.fmj.media.AbstractCodec#getOutputFormat() - */ - @Override - public Format getOutputFormat() - { - Format outputFormat = super.getOutputFormat(); - - if ((outputFormat != null) - && (outputFormat.getClass() == AudioFormat.class)) - { - AudioFormat outputAudioFormat = (AudioFormat) outputFormat; - - outputFormat = setOutputFormat( - new AudioFormat( - outputAudioFormat.getEncoding(), - outputAudioFormat.getSampleRate(), - outputAudioFormat.getSampleSizeInBits(), - outputAudioFormat.getChannels(), - outputAudioFormat.getEndian(), - outputAudioFormat.getSigned(), - outputAudioFormat.getFrameSizeInBits(), - outputAudioFormat.getFrameRate(), - outputAudioFormat.getDataType()) - { - private static final long serialVersionUID = 0L; - - @Override - public long computeDuration(long length) - { - return JNIEncoder.this.duration; - } - }); - } - return outputFormat; - } - - /** - * Sets the input format. - * - * @param format format to set - * @return format - * @see AbstractCodecExt#setInputFormat(Format) - */ - @Override - public Format setInputFormat(Format format) - { - Format inputFormat = super.setInputFormat(format); - - if (inputFormat != null) - { - double outputSampleRate; - int outputChannels; - - if (outputFormat == null) - { - outputSampleRate = Format.NOT_SPECIFIED; - outputChannels = Format.NOT_SPECIFIED; - } - else - { - AudioFormat outputAudioFormat = (AudioFormat) outputFormat; - - outputSampleRate = outputAudioFormat.getSampleRate(); - outputChannels = outputAudioFormat.getChannels(); - } - - AudioFormat inputAudioFormat = (AudioFormat) inputFormat; - double inputSampleRate = inputAudioFormat.getSampleRate(); - int inputChannels = inputAudioFormat.getChannels(); - - if ((outputSampleRate != inputSampleRate) - || (outputChannels != inputChannels)) - { - setOutputFormat( - new AudioFormat( - Constants.SPEEX_RTP, - inputSampleRate, - Format.NOT_SPECIFIED, - inputChannels, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED, - Format.byteArray)); - } - } - return inputFormat; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/JavaDecoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/JavaDecoder.java deleted file mode 100644 index 0406d252b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/JavaDecoder.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.speex; - -import java.io.*; -import javax.media.*; -import javax.media.format.*; - -import org.xiph.speex.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.sf.fmj.media.*; - -/** - * Speex to PCM java decoder - * @author Damian Minkov - **/ -public class JavaDecoder - extends AbstractCodec -{ - /** - * Default output formats. - */ - protected Format[] DEFAULT_OUTPUT_FORMATS = new Format[] { - new AudioFormat(AudioFormat.LINEAR)}; - - /** - * The input format used to initialize the decoder. - * If null decoder must be created. - */ - private Format lastFormat = null; - - /** - * The decoder. - */ - private SpeexDecoder decoder = null; - - /** - * Creates the decoder and inits supported input formats. - */ - public JavaDecoder() - { - this.inputFormats = new AudioFormat[] - { - new AudioFormat(Constants.SPEEX_RTP, - 8000, - 8, - 1, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED), - new AudioFormat(Constants.SPEEX_RTP, - 16000, - 8, - 1, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED), - new AudioFormat(Constants.SPEEX_RTP, - 32000, - 8, - 1, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED) - }; - } - - /** - * Returns the name of this plugin/codec. - * @return the name. - */ - public String getName() - { - return "Speex Java Decoder"; - } - - /** - * Return the list of formats supported at the output. - * - * @param in the input format. - * @return array of formats supported at output - */ - public Format[] getSupportedOutputFormats(Format in) - { - // null input format - if (in == null) - return DEFAULT_OUTPUT_FORMATS; - - // mismatch input format - if (!(in instanceof AudioFormat) - || (null == AbstractCodecExt.matches(in, inputFormats))) - return new Format[0]; - - return getMatchingOutputFormats(in); - } - - /** - * Returns the output format that matches the supplied input format. - * @param in input format - * @return array of format that match input ones - */ - private Format[] getMatchingOutputFormats(Format in) - { - AudioFormat af = (AudioFormat) in; - - return new AudioFormat[] - { - new AudioFormat( - AudioFormat.LINEAR, - af.getSampleRate(), - 16, - af.getChannels(), - AudioFormat.LITTLE_ENDIAN, //isBigEndian(), - AudioFormat.SIGNED //isSigned()); - )}; - } - - /** - * Does nothing. - */ - public void open() - {} - - /** - * Does nothing. - */ - public void close() - {} - - /** - * Initialize the decoder. - * @param inFormat the input format. - */ - private void initConverter(AudioFormat inFormat) - { - lastFormat = inFormat; - - decoder = new SpeexDecoder(); - - int sampleRate = - (int)inFormat.getSampleRate(); - - int band = JavaEncoder.NARROW_BAND; - - if(sampleRate == 16000) - band = JavaEncoder.WIDE_BAND; - else if(sampleRate == 32000) - band = JavaEncoder.ULTRA_WIDE_BAND; - - decoder.init(band, - sampleRate, - inFormat.getChannels(), - false); - } - - /** - * Process the input and decodes it. - * @param inputBuffer the input data. - * @param outputBuffer the result data. - * @return state of the process. - */ - public int process(Buffer inputBuffer, Buffer outputBuffer) - { - if (!checkInputBuffer(inputBuffer)) - { - return BUFFER_PROCESSED_FAILED; - } - - if (isEOM(inputBuffer)) - { - propagateEOM(outputBuffer); - return BUFFER_PROCESSED_OK; - } - - byte[] inData = (byte[]) inputBuffer.getData(); - - int inpLength = inputBuffer.getLength(); - int outLength = 0; - - int inOffset = inputBuffer.getOffset(); - int outOffset = outputBuffer.getOffset(); - - Format newFormat = inputBuffer.getFormat(); - - if (lastFormat != newFormat) - { - initConverter( (AudioFormat) newFormat); - } - - try - { - int fullyProcessed = - decoder.processData(inData, inOffset, inpLength); - - // sometimes we get more than a frame in single speex packet - // we must process it all - while(fullyProcessed != 1) - { - fullyProcessed = decoder.processData(false); - } - - outLength = decoder.getProcessedDataByteSize(); - - /* - * Do not always allocate a new data array for outBuffer, try to reuse - * the existing one if it is suitable. - */ - Object outData = outputBuffer.getData(); - byte[] out; - - if (outData instanceof byte[]) - { - out = (byte[]) outData; - if (out.length < outLength) - out = null; - } - else - out = null; - if (out == null) - out = new byte[outLength]; - - decoder.getProcessedData(out, outOffset); - - outputBuffer.setData(out); - outputBuffer.setLength(out.length); - outputBuffer.setOffset(0); - outputBuffer.setFormat(outputFormat); - } - catch (StreamCorruptedException ex) - { - ex.printStackTrace(); - } - - return BUFFER_PROCESSED_OK; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/JavaEncoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/JavaEncoder.java deleted file mode 100644 index f9b73706e..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/JavaEncoder.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.speex; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.sf.fmj.media.*; - -import org.xiph.speex.*; - -/** - * The Speex Encoder - * - * @author Damian Minkov - * @author Lubomir Marinov - */ -public class JavaEncoder - extends AbstractCodecExt -{ - - /** - * Narrow band used for 8 kHz. - */ - static final int NARROW_BAND= 0; - - /** - * Utra wide band used for 32 kHz. - */ - static final int ULTRA_WIDE_BAND= 2; - - /** - * Wide band used for 16 kHz. - */ - static final int WIDE_BAND= 1; - - /** - * The speex encoder instance. - */ - private SpeexEncoder encoder = null; - - /** - * The frame size used for current encoder configuration. - */ - private int frameSize = -1; - - /** - * The last input format used by this instance of the encoder. - * If null we must create the encoder with the current input format. - */ - private Format lastFormat = null; - - /** - * Our custom output format which computes the rtp data duration correctly. - */ - private AudioFormat outFormat = null; - - /** - * Creates the encoder and init supported formats - */ - public JavaEncoder() - { - super( - "Speex Java Encoder", - AudioFormat.class, - new Format[] { new AudioFormat(Constants.SPEEX_RTP) }); - - inputFormats - = new AudioFormat[] - { - new AudioFormat( - AudioFormat.LINEAR, - 8000, - 16, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED), - new AudioFormat( - AudioFormat.LINEAR, - 16000, - 16, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED), - new AudioFormat( - AudioFormat.LINEAR, - 32000, - 16, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED) - }; - } - - /** - * Does nothing. - * - * @see AbstractCodecExt#doClose() - */ - public void doClose() - { - } - - /** - * Opens this Codec and acquires the resources that it needs to - * operate. A call to {@link PlugIn#open()} on this instance will result in - * a call to doOpen only if {@link AbstractCodec#opened} is - * false. All required input and/or output formats are assumed to - * have been set on this Codec before doOpen is called. - * - * @throws ResourceUnavailableException if any of the resources that this - * Codec needs to operate cannot be acquired - * @see AbstractCodecExt#doOpen() - */ - public void doOpen() - throws ResourceUnavailableException - { - } - - /** - * Process the input and encodes it. - * - * @param inputBuffer the input data. - * @param outputBuffer the result data - * @return state of the process - * @see AbstractCodecExt#doProcess(Buffer, Buffer) - */ - protected int doProcess(Buffer inputBuffer, Buffer outputBuffer) - { - Format newFormat = inputBuffer.getFormat(); - - if (lastFormat != newFormat) - initConverter((AudioFormat) newFormat); - - int inputLength = inputBuffer.getLength(); - - if (inputLength == 0) - return OUTPUT_BUFFER_NOT_FILLED; - - if (inputLength >= frameSize) - { - byte[] inputData = (byte[]) inputBuffer.getData(); - int inputOffset = inputBuffer.getOffset(); - - encoder.processData(inputData, inputOffset, frameSize); - - byte[] buff = new byte[encoder.getProcessedDataByteSize()]; - - encoder.getProcessedData(buff, 0); - - /* - * Do not always allocate a new data array for outBuffer, try to - * reuse the existing one if it is suitable. - */ - Object outputData = outputBuffer.getData(); - byte[] output; - - if (outputData instanceof byte[]) - { - output = (byte[]) outputData; - if (output.length < buff.length) - output = null; - } - else - output = null; - if (output == null) - output = new byte[buff.length]; - - System.arraycopy(buff, 0, output, 0, buff.length); - - outputBuffer.setData(output); - outputBuffer.setFormat(outFormat); - outputBuffer.setLength(output.length); - outputBuffer.setOffset(0); - - if (inputLength > frameSize) - { - inputBuffer.setLength(inputLength - frameSize); - inputBuffer.setOffset(inputOffset + frameSize); - return BUFFER_PROCESSED_OK | INPUT_BUFFER_NOT_CONSUMED; - } - else - return BUFFER_PROCESSED_OK; - } - else - return OUTPUT_BUFFER_NOT_FILLED; - } - - /** - * Returns the output format that matches the supplied input format. - * - * @param in input format - * @return array of formats that match input ones - * @see AbstractCodecExt#getMatchingOutputFormats(Format) - */ - @Override - protected Format[] getMatchingOutputFormats(Format in) - { - AudioFormat af = (AudioFormat) in; - - return - new Format[] - { - new AudioFormat( - Constants.SPEEX_RTP, - af.getSampleRate(), - af.getSampleSizeInBits(), - af.getChannels(), - af.getEndian(), - af.getSigned()) - }; - } - - /** - * Initialize the encoder with the supplied input format. - * @param inFormat the input format. - */ - private void initConverter(AudioFormat inFormat) - { - lastFormat = inFormat; - - AudioFormat oFormat = (AudioFormat)outputFormat; - outFormat = new AudioFormat( - oFormat.getEncoding(), - oFormat.getSampleRate(), - oFormat.getSampleSizeInBits(), - oFormat.getChannels(), - oFormat.getEndian(), - oFormat.getSigned(), - oFormat.getFrameSizeInBits(), - oFormat.getFrameRate(), - oFormat.getDataType()) - { - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * The length in nanoseconds. - */ - @Override - public long computeDuration(long length) - { - // 20ms in nano - return 20 * 1000000; - } - }; - - encoder = new SpeexEncoder(); - - int sampleRate = (int) inFormat.getSampleRate(); - int band = NARROW_BAND; - - if (sampleRate == 16000) - band = WIDE_BAND; - else if (sampleRate == 32000) - band = ULTRA_WIDE_BAND; - - encoder.init(band, 4, sampleRate, 1); - - frameSize = 2 * encoder.getFrameSize(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/Speex.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/Speex.java deleted file mode 100644 index c76f9e882..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/Speex.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.speex; - -/** - * Provides the interface to the native Speex library. - * - * @author Lubomir Marinov - */ -public final class Speex -{ - public static final int SPEEX_GET_FRAME_SIZE = 3; - - public static final int SPEEX_MODEID_NB = 0; - - public static final int SPEEX_MODEID_UWB = 2; - - public static final int SPEEX_MODEID_WB = 1; - - public static final int SPEEX_RESAMPLER_QUALITY_VOIP = 3; - - public static final int SPEEX_SET_ENH = 0; - - public static final int SPEEX_SET_QUALITY = 4; - - public static final int SPEEX_SET_SAMPLING_RATE = 24; - - static - { - System.loadLibrary("jnspeex"); - } - - static void assertSpeexIsFunctional() - { - speex_lib_get_mode(SPEEX_MODEID_NB); - } - - public static native void speex_bits_destroy(long bits); - - public static native long speex_bits_init(); - - public static native int speex_bits_nbytes(long bits); - - public static native void speex_bits_read_from( - long bits, - byte[] bytes, int bytesOffset, - int len); - - public static native int speex_bits_remaining(long bits); - - public static native void speex_bits_reset(long bits); - - public static native int speex_bits_write( - long bits, - byte[] bytes, int bytesOffset, - int max_len); - - public static native int speex_decode_int( - long state, - long bits, - byte[] out, int byteOffset); - - public static native int speex_decoder_ctl(long state, int request); - - public static native int speex_decoder_ctl( - long state, - int request, - int value); - - public static native void speex_decoder_destroy(long state); - - public static native long speex_decoder_init(long mode); - - public static native int speex_encode_int( - long state, - byte[] in, int inOffset, - long bits); - - public static native int speex_encoder_ctl(long state, int request); - - public static native int speex_encoder_ctl( - long state, - int request, - int value); - - public static native void speex_encoder_destroy(long state); - - public static native long speex_encoder_init(long mode); - - public static native long speex_lib_get_mode(int mode); - - public static native void speex_resampler_destroy(long state); - - public static native long speex_resampler_init( - int nb_channels, - int in_rate, - int out_rate, - int quality, - long err); - - public static native int speex_resampler_process_interleaved_int( - long state, - byte[] in, int inOffset, int in_len, - byte[] out, int outOffset, int out_len); - - public static native int speex_resampler_set_rate( - long state, - int in_rate, - int out_rate); - - /** - * Prevents the creation of Speex instances. - */ - private Speex() - { - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/SpeexResampler.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/SpeexResampler.java deleted file mode 100644 index ee85c658b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/speex/SpeexResampler.java +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.speex; - -import java.util.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.sf.fmj.media.*; - -/** - * Implements an audio resampler using Speex. - * - * @author Lyubomir Marinov - */ -public class SpeexResampler - extends AbstractCodecExt -{ - /** - * The list of Formats of audio data supported as input and output - * by SpeexResampler instances. - */ - private static final Format[] SUPPORTED_FORMATS; - - /** - * The list of sample rates of audio data supported as input and output by - * SpeexResampler instances. - */ - private static final double[] SUPPORTED_SAMPLE_RATES - = new double[] - { - 8000, - 11025, - 12000, - 16000, - 22050, - 24000, - 32000, - 44100, - 48000, - Format.NOT_SPECIFIED - }; - - static - { - Speex.assertSpeexIsFunctional(); - - int supportedCount = SUPPORTED_SAMPLE_RATES.length; - - SUPPORTED_FORMATS = new Format[2 * supportedCount]; - for (int i = 0; i < supportedCount; i++) - { - int j = 2 * i; - - SUPPORTED_FORMATS[j] - = new AudioFormat( - AudioFormat.LINEAR, - SUPPORTED_SAMPLE_RATES[i], - 16 /* sampleSizeInBits */, - 1 /* channels */, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED, - Format.byteArray); - SUPPORTED_FORMATS[j + 1] - = new AudioFormat( - AudioFormat.LINEAR, - SUPPORTED_SAMPLE_RATES[i], - 16 /* sampleSizeInBits */, - 1 /* channels */, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED, - Format.shortArray); - } - } - - /** - * The input sample rate configured in {@link #resampler}. - */ - private int inputSampleRate; - - /** - * The output sample rate configured in {@link #resampler}. - */ - private int outputSampleRate; - - /** - * The pointer to the native SpeexResamplerState which is - * represented by this instance. - */ - private long resampler; - - /** - * Initializes a new SpeexResampler instance. - */ - public SpeexResampler() - { - super("Speex Resampler", AudioFormat.class, SUPPORTED_FORMATS); - - inputFormats = SUPPORTED_FORMATS; - } - - /** - * @see AbstractCodecExt#doClose() - */ - protected void doClose() - { - if (resampler != 0) - { - Speex.speex_resampler_destroy(resampler); - resampler = 0; - } - } - - /** - * Opens this Codec and acquires the resources that it needs to - * operate. A call to {@link PlugIn#open()} on this instance will result in - * a call to doOpen only if {@link AbstractCodec#opened} is - * false. All required input and/or output formats are assumed to - * have been set on this Codec before doOpen is called. - * - * @throws ResourceUnavailableException if any of the resources that this - * Codec needs to operate cannot be acquired - * @see AbstractCodecExt#doOpen() - */ - protected void doOpen() - throws ResourceUnavailableException - { - } - - /** - * Resamples audio from a specific input Buffer into a specific - * output Buffer. - * - * @param inputBuffer input Buffer - * @param outputBuffer output Buffer - * @return BUFFER_PROCESSED_OK if inputBuffer has been - * successfully processed - * @see AbstractCodecExt#doProcess(Buffer, Buffer) - */ - protected int doProcess(Buffer inputBuffer, Buffer outputBuffer) - { - Format inputFormat = inputBuffer.getFormat(); - - if ((inputFormat != null) - && (inputFormat != this.inputFormat) - && !inputFormat.equals(this.inputFormat)) - { - if (null == setInputFormat(inputFormat)) - return BUFFER_PROCESSED_FAILED; - } - inputFormat = this.inputFormat; - - AudioFormat inputAudioFormat = (AudioFormat) inputFormat; - int inputSampleRate = (int) inputAudioFormat.getSampleRate(); - AudioFormat outputAudioFormat = (AudioFormat) getOutputFormat(); - int outputSampleRate = (int) outputAudioFormat.getSampleRate(); - - if (inputSampleRate == outputSampleRate) - { - // passthrough - Class inputDataType = inputAudioFormat.getDataType(); - Class outputDataType = outputAudioFormat.getDataType(); - - if (Format.byteArray.equals(inputDataType)) - { - byte[] input = (byte[]) inputBuffer.getData(); - - if (Format.byteArray.equals(outputDataType)) - { - int length = (input == null) ? 0 : input.length; - byte[] output = validateByteArraySize(outputBuffer, length); - - if ((input != null) && (output != null)) - System.arraycopy(input, 0, output, 0, length); - outputBuffer.setFormat(inputBuffer.getFormat()); - outputBuffer.setLength(inputBuffer.getLength()); - outputBuffer.setOffset(inputBuffer.getOffset()); - } - else - { - int inputLength = inputBuffer.getLength(); - int outputOffset = 0; - int outputLength = inputLength / 2; - short[] output - = validateShortArraySize(outputBuffer, outputLength); - - for (int i = inputBuffer.getOffset(), o = outputOffset; - o < outputLength; - o++) - { - output[o] - = (short) - (((input[i++] & 0xFF) - | (input[i++] & 0xFF) << 8)); - } - outputBuffer.setFormat(outputAudioFormat); - outputBuffer.setLength(outputLength); - outputBuffer.setOffset(outputOffset); - } - } - else - { - short[] input = (short[]) inputBuffer.getData(); - - if (Format.byteArray.equals(outputDataType)) - { - int inputLength = inputBuffer.getLength(); - int outputOffset = 0; - int outputLength = inputLength * 2; - byte[] output - = validateByteArraySize(outputBuffer, outputLength); - - for (int i = inputBuffer.getOffset(), o = outputOffset; - o < outputLength; - i++) - { - short s = input[i]; - - output[o++] = (byte) (s & 0x00FF); - output[o++] = (byte) ((s & 0xFF00) >>> 8); - } - outputBuffer.setFormat(outputAudioFormat); - outputBuffer.setLength(outputLength); - outputBuffer.setOffset(outputOffset); - } - else - { - int length = (input == null) ? 0 : input.length; - short[] output - = validateShortArraySize(outputBuffer, length); - - if ((input != null) && (output != null)) - System.arraycopy(input, 0, output, 0, length); - outputBuffer.setFormat(inputBuffer.getFormat()); - outputBuffer.setLength(inputBuffer.getLength()); - outputBuffer.setOffset(inputBuffer.getOffset()); - } - } - } - else - { - if ((this.inputSampleRate != inputSampleRate) - || (this.outputSampleRate != outputSampleRate)) - { - if (resampler == 0) - { - resampler - = Speex.speex_resampler_init( - 1, - inputSampleRate, - outputSampleRate, - Speex.SPEEX_RESAMPLER_QUALITY_VOIP, - 0); - } - else - { - Speex.speex_resampler_set_rate( - resampler, - inputSampleRate, - outputSampleRate); - } - if (resampler != 0) - { - this.inputSampleRate = inputSampleRate; - this.outputSampleRate = outputSampleRate; - } - } - if (resampler == 0) - return BUFFER_PROCESSED_FAILED; - - byte[] input = (byte[]) inputBuffer.getData(); - int inputLength = inputBuffer.getLength(); - int sampleSizeInBytes = inputAudioFormat.getSampleSizeInBits() / 8; - int inputSampleCount = inputLength / sampleSizeInBytes; - int outputLength - = (inputLength * outputSampleRate) / inputSampleRate; - byte[] output = validateByteArraySize(outputBuffer, outputLength); - int outputSampleCount = outputLength / sampleSizeInBytes; - - outputSampleCount - = Speex.speex_resampler_process_interleaved_int( - resampler, - input, inputBuffer.getOffset(), inputSampleCount, - output, 0, outputSampleCount); - outputBuffer.setFormat(outputAudioFormat); - outputBuffer.setLength(outputSampleCount * sampleSizeInBytes); - outputBuffer.setOffset(0); - } - outputBuffer.setDuration(inputBuffer.getDuration()); - outputBuffer.setEOM(inputBuffer.isEOM()); - outputBuffer.setFlags(inputBuffer.getFlags()); - outputBuffer.setHeader(inputBuffer.getHeader()); - outputBuffer.setSequenceNumber(inputBuffer.getSequenceNumber()); - outputBuffer.setTimeStamp(inputBuffer.getTimeStamp()); - return BUFFER_PROCESSED_OK; - } - - /** - * Get the output formats matching a specific input format. - * - * @param inputFormat the input format to get the matching output formats of - * @return the output formats matching the specified input format - * @see AbstractCodecExt#getMatchingOutputFormats(Format) - */ - @Override - protected Format[] getMatchingOutputFormats(Format inputFormat) - { - Class inputFormatDataType = inputFormat.getDataType(); - List matchingOutputFormats = new ArrayList(); - - for (Format supportedFormat : SUPPORTED_FORMATS) - { - if ((Format.byteArray.equals(supportedFormat.getDataType()) - && Format.byteArray.equals(inputFormatDataType)) - || (((AudioFormat) supportedFormat).getSampleRate() - == ((AudioFormat) inputFormat).getSampleRate())) - matchingOutputFormats.add(supportedFormat); - } - return - matchingOutputFormats.toArray( - new Format[matchingOutputFormats.size()]); - } - - /** - * Sets the Format of the media data to be input for processing in - * this Codec. - * - * @param format the Format of the media data to be input for - * processing in this Codec - * @return the Format of the media data to be input for processing - * in this Codec if format is compatible with this - * Codec; otherwise, null - * @see AbstractCodecExt#setInputFormat(Format) - */ - @Override - public Format setInputFormat(Format format) - { - AudioFormat inputFormat = (AudioFormat) super.setInputFormat(format); - - if (inputFormat != null) - { - double outputSampleRate; - Class outputDataType; - - if (outputFormat == null) - { - outputSampleRate = inputFormat.getSampleRate(); - outputDataType = inputFormat.getDataType(); - } - else - { - AudioFormat outputAudioFormat = (AudioFormat) outputFormat; - - outputSampleRate = outputAudioFormat.getSampleRate(); - outputDataType = outputAudioFormat.getDataType(); - /* - * Conversion between data types is only supported when not - * resampling but rather passing through. - */ - if (outputSampleRate != inputFormat.getSampleRate()) - outputDataType = inputFormat.getDataType(); - } - - setOutputFormat( - new AudioFormat( - inputFormat.getEncoding(), - outputSampleRate, - inputFormat.getSampleSizeInBits(), - inputFormat.getChannels(), - inputFormat.getEndian(), - inputFormat.getSigned(), - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED, - outputDataType)); - } - return inputFormat; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ulaw/JavaDecoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/ulaw/JavaDecoder.java deleted file mode 100644 index 674308723..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ulaw/JavaDecoder.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.ulaw; - -import com.sun.media.controls.*; - -import javax.media.*; -import javax.media.format.*; - -public class JavaDecoder - extends com.ibm.media.codec.audio.AudioCodec -{ - static private final byte[] lutTableH = new byte[256]; - - static private final byte[] lutTableL = new byte[256]; - - public JavaDecoder() - { - supportedInputFormats = new AudioFormat[] - { new AudioFormat(AudioFormat.ULAW) }; - defaultOutputFormats = new AudioFormat[] - { new AudioFormat(AudioFormat.LINEAR) }; - PLUGIN_NAME = "Mu-Law Decoder"; - } - - public Object[] getControls() - { - if (controls == null) - { - controls - = new Object[] - { - new SilenceSuppressionAdapter(this, false, false) - }; - } - return controls; - } - - protected Format[] getMatchingOutputFormats(Format in) - { - AudioFormat af = (AudioFormat) in; - - supportedOutputFormats = - new AudioFormat[] - { new AudioFormat(AudioFormat.LINEAR, af.getSampleRate(), 16, - af.getChannels(), AudioFormat.LITTLE_ENDIAN, // isBigEndian(), - AudioFormat.SIGNED // isSigned()); - ) }; - return supportedOutputFormats; - } - - private void initTables() - { - for (int i = 0; i < 256; i++) - { - int input = ~i; - int mantissa = ((input & 0xf) << 3) + 0x84; - int segment = (input & 0x70) >> 4; - int value = mantissa << segment; - - value -= 0x84; - - if ((input & 0x80) != 0) - value = -value; - - lutTableL[i] = (byte) value; - lutTableH[i] = (byte) (value >> 8); - } - } - - /** Initializes the codec. */ - public void open() - { - initTables(); - } - - /** Decodes the buffer */ - public int process(Buffer inputBuffer, Buffer outputBuffer) - { - if (!checkInputBuffer(inputBuffer)) - return BUFFER_PROCESSED_FAILED; - if (isEOM(inputBuffer)) - { - propagateEOM(outputBuffer); - return BUFFER_PROCESSED_OK; - } - - byte[] inData = (byte[]) inputBuffer.getData(); - byte[] outData = validateByteArraySize(outputBuffer, inData.length * 2); - - int inpLength = inputBuffer.getLength(); - int outLength = 2 * inpLength; - - int inOffset = inputBuffer.getOffset(); - int outOffset = outputBuffer.getOffset(); - for (int i = 0; i < inpLength; i++) - { - int temp = inData[inOffset++] & 0xff; - outData[outOffset++] = lutTableL[temp]; - outData[outOffset++] = lutTableH[temp]; - } - - updateOutput(outputBuffer, outputFormat, outLength, - outputBuffer.getOffset()); - - return BUFFER_PROCESSED_OK; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ulaw/JavaEncoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/ulaw/JavaEncoder.java deleted file mode 100644 index c764119d6..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ulaw/JavaEncoder.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.ulaw; - -import javax.media.*; -import javax.media.format.*; - -public class JavaEncoder - extends com.ibm.media.codec.audio.AudioCodec -{ - private boolean downmix = false; - - private int inputBias; - - private int inputSampleSize; - - private Format lastFormat = null; - - private int lsbOffset; - - private int msbOffset; - - private int numberOfInputChannels; - - private int numberOfOutputChannels = 1; - - private int signMask; - - public JavaEncoder() - { - supportedInputFormats = new AudioFormat[] { - new AudioFormat(AudioFormat.LINEAR, Format.NOT_SPECIFIED, 16, - 1, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED), - new AudioFormat(AudioFormat.LINEAR, Format.NOT_SPECIFIED, 16, - 2, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED), - new AudioFormat(AudioFormat.LINEAR, Format.NOT_SPECIFIED, 8, 1, - Format.NOT_SPECIFIED, Format.NOT_SPECIFIED), - new AudioFormat(AudioFormat.LINEAR, Format.NOT_SPECIFIED, 8, 2, - Format.NOT_SPECIFIED, Format.NOT_SPECIFIED) }; // support - // 1/2 - // channels - // and - // 8/16 - // bit - // samples - - defaultOutputFormats = new AudioFormat[] { new AudioFormat( - AudioFormat.ULAW, 8000, 8, 1, Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED) }; - PLUGIN_NAME = "pcm to mu-law converter"; - } - - private int calculateOutputSize(int inputLength) - { - if (inputSampleSize == 16) - inputLength /= 2; - - if (downmix) - inputLength /= 2; - - return inputLength; - } - - private void convert(byte[] input, int inputOffset, int inputLength, - byte[] outData, int outputOffset) - { - int sample, signBit, inputSample; - int i; - - for (i = inputOffset + msbOffset; i < (inputLength + inputOffset);) - { - - if (8 == inputSampleSize) - { - inputSample = input[i++] << 8; - - if (downmix) - inputSample - = ((inputSample & signMask) - + ((input[i++] << 8) & signMask)) - >> 1; - } else - { - inputSample = (input[i] << 8) + (0xff & input[i + lsbOffset]); - i += 2; - - if (downmix) - { - inputSample - = ((inputSample & signMask) + (((input[i] << 8) - + (0xff & input[i + lsbOffset])) & signMask)) - >> 1; - i += 2; - } - } - - sample = (int) ((short) (inputSample + inputBias)); - - if (sample >= 0) - { - signBit = 0x80; // sign bit - } - else - { - sample = -sample; - signBit = 0x00; - } - - sample = (132 + sample) >> 3; // bias - - outData[outputOffset++] = (byte) ((sample < 0x0020) ? (signBit - | (7 << 4) | (31 - (sample >> 0))) - : (sample < 0x0040) ? (signBit | (6 << 4) | (31 - (sample >> 1))) - : (sample < 0x0080) ? (signBit | (5 << 4) | (31 - (sample >> 2))) - : (sample < 0x0100) ? (signBit | (4 << 4) | (31 - (sample >> 3))) - : (sample < 0x0200) ? (signBit - | (3 << 4) | (31 - (sample >> 4))) - : (sample < 0x0400) ? (signBit - | (2 << 4) | (31 - (sample >> 5))) - : (sample < 0x0800) ? (signBit - | (1 << 4) | (31 - (sample >> 6))) - : (sample < 0x1000) ? (signBit - | (0 << 4) | (31 - (sample >> 7))) - : (signBit - | (0 << 4) | (31 - (0xfff >> 7)))); - } - - } - - @Override - protected Format[] getMatchingOutputFormats(Format in) - { - AudioFormat inFormat = (AudioFormat) in; - int channels = inFormat.getChannels(); - int sampleRate = (int) (inFormat.getSampleRate()); - - if (channels == 2) - { - supportedOutputFormats = new AudioFormat[] { - new AudioFormat(AudioFormat.ULAW, sampleRate, 8, 2, - Format.NOT_SPECIFIED, Format.NOT_SPECIFIED), - new AudioFormat(AudioFormat.ULAW, sampleRate, 8, 1, - Format.NOT_SPECIFIED, Format.NOT_SPECIFIED) }; - - } - else - { - supportedOutputFormats = new AudioFormat[] { new AudioFormat( - AudioFormat.ULAW, sampleRate, 8, 1, Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED) }; - - } - return supportedOutputFormats; - } - - private void initConverter(AudioFormat inFormat) - { - lastFormat = inFormat; - numberOfInputChannels = inFormat.getChannels(); - if (outputFormat != null) - numberOfOutputChannels = outputFormat.getChannels(); - inputSampleSize = inFormat.getSampleSizeInBits(); - - if ((inFormat.getEndian() == AudioFormat.BIG_ENDIAN) - || (8 == inputSampleSize)) - { - lsbOffset = 1; - msbOffset = 0; - } - else - { - lsbOffset = -1; - msbOffset = 1; - } - - if (inFormat.getSigned() == AudioFormat.SIGNED) - { - inputBias = 0; - signMask = 0xffffffff; - } - else - { - inputBias = 32768; - signMask = 0x0000ffff; - } - - downmix - = (numberOfInputChannels == 2) && (numberOfOutputChannels == 1); - } - - public int process(Buffer inputBuffer, Buffer outputBuffer) - { - if (!checkInputBuffer(inputBuffer)) - return BUFFER_PROCESSED_FAILED; - if (isEOM(inputBuffer)) - { - propagateEOM(outputBuffer); - return BUFFER_PROCESSED_OK; - } - - Format newFormat = inputBuffer.getFormat(); - - if (lastFormat != newFormat) - initConverter((AudioFormat) newFormat); - - int inpLength = inputBuffer.getLength(); - int outLength = calculateOutputSize(inputBuffer.getLength()); - - byte[] inpData = (byte[]) inputBuffer.getData(); - byte[] outData = validateByteArraySize(outputBuffer, outLength); - - convert(inpData, inputBuffer.getOffset(), inpLength, outData, 0); - - updateOutput(outputBuffer, outputFormat, outLength, 0); - return BUFFER_PROCESSED_OK; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ulaw/Packetizer.java b/src/net/java/sip/communicator/impl/neomedia/codec/audio/ulaw/Packetizer.java deleted file mode 100644 index 5cb42b02a..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/audio/ulaw/Packetizer.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.audio.ulaw; - -/** - * Overrides the ULaw Packetizer with a different packet size. - * - * @author Thomas Hofer - */ -public class Packetizer - extends com.sun.media.codec.audio.ulaw.Packetizer -{ - /** - * Constructs a new ULaw Packetizer. - */ - public Packetizer() - { - // RFC 3551 4.5 Audio Encodings default ms/packet is 20 - packetSize = 160; - setPacketSize(packetSize); - - PLUGIN_NAME = "ULaw Packetizer"; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/AVFrame.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/AVFrame.java deleted file mode 100644 index d007fc347..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/AVFrame.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.video; - -/** - * Represents a pointer to a native FFmpeg AVFrame object. - * - * @author Lubomir Marinov - */ -public class AVFrame -{ - /** - * The pointer to the native FFmpeg AVFrame object represented by - * this instance. - */ - private final long ptr; - - /** - * Initializes a new AVFrame instance which is to represent a - * specific pointer to a native FFmpeg AVFrame object. - * - * @param ptr the pointer to the native FFmpeg AVFrame object to be - * represented by the new instance - */ - public AVFrame(long ptr) - { - if (ptr == 0) - throw new IllegalArgumentException("ptr"); - - this.ptr = ptr; - } - - /** - * Gets the pointer to the native FFmpeg AVFrame object represented - * by this instance. - * - * @return the pointer to the native FFmpeg AVFrame object - * represented by this instance - */ - public long getPtr() - { - return ptr; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/AVFrameFormat.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/AVFrameFormat.java deleted file mode 100644 index dc2bbb4a9..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/AVFrameFormat.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.video; - -import java.awt.*; - -import javax.media.*; -import javax.media.format.*; - -/** - * Implements a VideoFormat for a Buffer carrying - * AVFrame as its data. While the AVFrameFormat class - * is not strictly necessary and VideoFormat could have be directly - * used, it is conceived as an appropriate way to avoid possible matching with - * other VideoFormats and a very obvious one. - * - * @author Lyubomir Marinov - * @author Sebastien Vincent - */ -public class AVFrameFormat - extends VideoFormat -{ - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * The encoding of the AVFrameFormat instances. - */ - public static final String AVFRAME = "AVFrame"; - - /** - * The native device-specific format represented by this instance. It's - * necessary in the cases of multiple device-specific formats corresponding - * to one and the same native FFmpeg format in which JMF is unable to - * differentiate them, yet the device needs to know its device-specific - * format. - */ - private int devicePixFmt; - - /** - * The native FFmpeg format represented by this instance. - */ - private int pixFmt; - - /** - * Initializes a new AVFrameFormat instance with unspecified size, - * frame rate and FFmpeg colorspace. - */ - public AVFrameFormat() - { - this(NOT_SPECIFIED, NOT_SPECIFIED); - } - - /** - * Initializes a new AVFrameFormat instance with a specific FFmpeg - * colorspace and unspecified size and frame rate. - * - * @param pixFmt the FFmpeg colorspace to be represented by the new instance - */ - public AVFrameFormat(int pixFmt) - { - this(pixFmt, NOT_SPECIFIED); - } - - /** - * Initializes a new AVFrameFormat instance with a specific FFmpeg - * colorspace and unspecified size and frame rate. - * - * @param pixFmt the FFmpeg colorspace to be represented by the new instance - * @param devicePixFmt the capture device colorspace to be represented by - * the new instance - */ - public AVFrameFormat(int pixFmt, int devicePixFmt) - { - this(null, NOT_SPECIFIED, pixFmt, devicePixFmt); - } - - /** - * Initializes a new AVFrameFormat instance with specific size, - * frame rate and FFmpeg colorspace. - * - * @param size the Dimension of the new instance - * @param frameRate the frame rate of the new instance - * @param pixFmt the FFmpeg colorspace to be represented by the new instance - * @param devicePixFmt the capture device colorspace to be represented by - * the new instance - */ - public AVFrameFormat( - Dimension size, - float frameRate, - int pixFmt, int devicePixFmt) - { - super(AVFRAME, size, NOT_SPECIFIED, AVFrame.class, frameRate); - - this.pixFmt = pixFmt; - this.devicePixFmt = devicePixFmt; - } - - /** - * Initializes a new AVFrameFormat instance which has the same - * properties as this instance. - * - * @return a new AVFrameFormat instance which has the same - * properties as this instance - */ - @Override - public Object clone() - { - AVFrameFormat f - = new AVFrameFormat( - getSize(), - getFrameRate(), - pixFmt, devicePixFmt); - - f.copy(this); - return f; - } - - /** - * Copies the properties of the specified Format into this - * instance. - * - * @param f the Format the properties of which are to be copied - * into this instance - */ - @Override - protected void copy(Format f) - { - super.copy(f); - - if (f instanceof AVFrameFormat) - { - AVFrameFormat avFrameFormat = (AVFrameFormat) f; - - pixFmt = avFrameFormat.pixFmt; - devicePixFmt = avFrameFormat.devicePixFmt; - } - } - - /** - * Determines whether a specific Object represents a value that is - * equal to the value represented by this instance. - * - * @param obj the Object to be determined whether it represents a - * value that is equal to the value represented by this instance - * @return true if the specified obj represents a value - * that is equal to the value represented by this instance; otherwise, - * false - */ - @Override - public boolean equals(Object obj) - { - if ((obj instanceof AVFrameFormat) && super.equals(obj)) - { - AVFrameFormat avFrameFormat = (AVFrameFormat) obj; - - return (pixFmt == avFrameFormat.pixFmt); - } - else - return false; - } - - /** - * Gets the native FFmpeg format represented by this instance. - * - * @return the native FFmpeg format represented by this instance - */ - public int getPixFmt() - { - return pixFmt; - } - - /** - * Gets the native capture device format represented by this instance. - * - * @return native capture device format represented by this instance - */ - public int getDevicePixFmt() - { - return devicePixFmt; - } - - @Override - public int hashCode() - { - return super.hashCode() + pixFmt; - } - - /** - * Finds the attributes shared by two matching Formats. If the - * specified Format does not match this one, the result is - * undefined. - * - * @param format the matching Format to intersect with this one - * @return a Format with its attributes set to the attributes - * common to this instance and the specified format - */ - @Override - public Format intersects(Format format) - { - Format intersection = super.intersects(format); - - if (intersection != null) - { - AVFrameFormat avFrameFormatIntersection - = (AVFrameFormat) intersection; - - avFrameFormatIntersection.pixFmt - = ((pixFmt == NOT_SPECIFIED) - && (format instanceof AVFrameFormat)) - ? ((AVFrameFormat) format).pixFmt - : pixFmt; - } - return intersection; - } - - /** - * Determines whether a specific format matches this instance i.e. whether - * their attributes match according to the definition of "match" given by - * {@link Format#matches(Format)}. - * - * @param format the Format to compare to this instance - * @return true if the specified format matches this one; - * otherwise, false - */ - @Override - public boolean matches(Format format) - { - boolean matches; - - if (super.matches(format)) - { - if (format instanceof AVFrameFormat) - { - AVFrameFormat avFrameFormat = (AVFrameFormat) format; - - matches - = ((pixFmt == NOT_SPECIFIED) - || (avFrameFormat.pixFmt == NOT_SPECIFIED) - || (pixFmt == avFrameFormat.pixFmt)); - } - else - matches = true; - } - else - matches = false; - return matches; - } - - @Override - public String toString() - { - return super.toString() + ", pixFmt= " + pixFmt; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/ByteBuffer.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/ByteBuffer.java deleted file mode 100644 index 2bb81d59a..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/ByteBuffer.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.video; - -import net.java.sip.communicator.impl.neomedia.codec.*; - -/** - * Represents a buffer of native memory with a specific size/capacity which - * either contains a specific number of bytes of valid data or is free for - * consumption. - * - * @author Lubomir Marinov - */ -public class ByteBuffer -{ - - /** - * The maximum number of bytes which can be written into the native memory - * represented by this instance. - */ - public final int capacity; - - /** - * The indicator which determines whether this instance is free to be - * written bytes into. - */ - private boolean free; - - /** - * The number of bytes of valid data that the native memory represented by - * this instance contains. - */ - private int length; - - /** - * The pointer to the native memory represented by this instance. - */ - public final long ptr; - - /** - * Initializes a new ByteBuffer instance with a specific - * capacity. - * - * @param capacity the maximum number of bytes which can be written into the - * native memory represented by the new instance - */ - public ByteBuffer(int capacity) - { - this.capacity = capacity; - this.ptr = FFmpeg.av_malloc(this.capacity); - - this.free = true; - this.length = 0; - - if (this.ptr == 0) - { - throw - new OutOfMemoryError( - getClass().getSimpleName() - + " with capacity " - + this.capacity); - } - } - - /** - * Gets the number of bytes of valid data that the native memory represented - * by this instance contains. - * - * @return the number of bytes of valid data that the native memory - * represented by this instance contains - */ - public int getLength() - { - return length; - } - - /** - * Determines whether this instance is free to be written bytes into. - * - * @return true if this instance is free to be written bytes into - * or false is the native memory represented by this instance is - * already is use - */ - public boolean isFree() - { - return free; - } - - /** - * Sets the indicator which determines whether this instance is free to be - * written bytes into. - * - * @param free true if this instance is to be made available for - * writing bytes into; otherwise, false - */ - public void setFree(boolean free) - { - this.free = free; - if (this.free) - setLength(0); - } - - /** - * Sets the number of bytes of valid data that the native memory represented - * by this instance contains. - * - * @param length the number of bytes of valid data that the native memory - * represented by this instance contains - */ - public void setLength(int length) - { - this.length = length; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/FinalizableAVFrame.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/FinalizableAVFrame.java deleted file mode 100644 index 6ef4118b4..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/FinalizableAVFrame.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.video; - -import java.awt.*; - -import javax.media.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.*; - -/** - * Represents an AVFrame used to provide captured media data in native - * format without representing the very frame data in the Java heap. Since the - * user may not know when the AVFrame instances are really safe for - * deallocation, FinalizableAVFrame relies on the Java finalization - * mechanism to reclaim the represented native memory. - * - * @author Lubomir Marinov - */ -public class FinalizableAVFrame - extends AVFrame -{ - - /** - * The indicator which determines whether the native memory represented by - * this instance has already been freed/deallocated. - */ - private boolean freed = false; - - /** - * Initializes a new FinalizableAVFrame instance which is to - * allocate a new native FFmpeg AVFrame and represent it. - */ - public FinalizableAVFrame() - { - super(FFmpeg.avcodec_alloc_frame()); - } - - /** - * Deallocates the native memory represented by this instance. - * - * @see Object#finalize() - */ - @Override - protected void finalize() - throws Throwable - { - try - { - if (!freed) - { - long ptr = getPtr(); - long bufferPtr = FFmpeg.avpicture_get_data0(ptr); - - if (bufferPtr != 0) - freeData0(bufferPtr); - FFmpeg.av_free(ptr); - freed = true; - } - } - finally - { - super.finalize(); - } - } - - /** - * Frees the memory pointed to by the data0 member of the native - * AVFrame. - * @param data0 pointer to free - */ - protected void freeData0(long data0) - { - FFmpeg.av_free(data0); - } - - /** - * Read the frame. - * - * @param buffer buffer - * @param format format of the buffer - * @param data the data - * @param byteBufferPool the ByteBuffer pool - */ - public static void read( - Buffer buffer, - Format format, - ByteBuffer data, - final ByteBufferPool byteBufferPool) - { - Object bufferData = buffer.getData(); - AVFrame frame; - long framePtr; - long bufferPtrToReturnFree; - - if (bufferData instanceof AVFrame) - { - frame = (AVFrame) bufferData; - framePtr = frame.getPtr(); - bufferPtrToReturnFree = FFmpeg.avpicture_get_data0(framePtr); - } - else - { - frame - = new FinalizableAVFrame() - { - @Override - protected void freeData0(long data0) - { - byteBufferPool.returnFreeBuffer(data0); - } - }; - buffer.setData(frame); - framePtr = frame.getPtr(); - bufferPtrToReturnFree = 0; - } - - AVFrameFormat frameFormat = (AVFrameFormat) format; - Dimension frameSize = frameFormat.getSize(); - - FFmpeg.avpicture_fill( - framePtr, - data.ptr, - frameFormat.getPixFmt(), - frameSize.width, frameSize.height); - - if (bufferPtrToReturnFree != 0) - byteBufferPool.returnFreeBuffer(bufferPtrToReturnFree); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/HFlip.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/HFlip.java deleted file mode 100644 index 6283e1096..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/HFlip.java +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.video; - -import java.awt.*; - -import javax.media.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.util.*; - -/** - * Implements a video Effect which horizontally flips - * AVFrames. - * - * @author Sebastien Vincent - * @author Lyubomir Marinov - */ -public class HFlip - extends AbstractCodecExt - implements Effect -{ - /** - * The Logger used by the HFlip class and its instances - * for logging output. - */ - private static final Logger logger = Logger.getLogger(HFlip.class); - - /** - * The list of Formats supported by HFlip instances as - * input and output. - */ - private static final Format[] SUPPORTED_FORMATS - = new Format[] { new AVFrameFormat() }; - - /** - * The name of the FFmpeg ffsink video source AVFilter used by - * HFlip. - */ - private static final String VSINK_FFSINK_NAME = "nullsink"; - - /** - * The name of the FFmpeg buffer video source AVFilter used by - * HFlip. - */ - private static final String VSRC_BUFFER_NAME = "buffer"; - - /** - * The pointer to the AVFilterContext in {@link #graph} of the - * FFmpeg video source with the name {@link #VSRC_BUFFER_NAME}. - */ - private long buffer; - - /** - * The pointer to the AVFilterContext in {@link #graph} of the - * FFmpeg video sink with the name {@link #VSINK_FFSINK_NAME}. - */ - private long ffsink; - - /** - * The pointer to the AVFilterGraph instance which contains the - * FFmpeg hflip filter represented by this Effect. - */ - private long graph; - - /** - * The height of {@link #graph}. - */ - private int height; - - /** - * The pointer to the AVFilterBufferRef instance represented as an - * AVFrame by {@link #outputFrame}. - */ - private long outputFilterBufferRef; - - /** - * The pointer to the AVFrame instance which is the output (data) - * of this Effect. - */ - private long outputFrame; - - /** - * The FFmpeg pixel format of {@link #graph}. - */ - private int pixFmt = FFmpeg.PIX_FMT_NONE; - - /** - * The width of {@link #graph}. - */ - private int width; - - /** - * Initializes a new HFlip instance. - */ - public HFlip() - { - super("FFmpeg HFlip Filter", AVFrameFormat.class, SUPPORTED_FORMATS); - } - - /** - * Closes this Effect. - * - * @see AbstractCodecExt#doClose() - */ - protected synchronized void doClose() - { - try - { - if (outputFrame != 0) - { - FFmpeg.av_free(outputFrame); - outputFrame = 0; - } - } - finally - { - reset(); - } - } - - /** - * Opens this Effect. - * - * @throws ResourceUnavailableException if any of the required resource - * cannot be allocated - * @see AbstractCodecExt#doOpen() - */ - protected synchronized void doOpen() - throws ResourceUnavailableException - { - outputFrame = FFmpeg.avcodec_alloc_frame(); - if (outputFrame == 0) - { - String reason = "avcodec_alloc_frame: " + outputFrame; - - logger.error(reason); - throw new ResourceUnavailableException(reason); - } - } - - /** - * Performs the media processing defined by this Effect. - * - * @param inputBuffer the Buffer that contains the media data to be - * processed - * @param outputBuffer the Buffer in which to store the processed - * media data - * @return BUFFER_PROCESSED_OK if the processing is successful - * @see AbstractCodecExt#doProcess(Buffer, Buffer) - */ - protected synchronized int doProcess( - Buffer inputBuffer, - Buffer outputBuffer) - { - /* - * A new frame is about to be output so the old frame is no longer - * necessary. - */ - if (outputFilterBufferRef != 0) - { - FFmpeg.avfilter_unref_buffer(outputFilterBufferRef); - outputFilterBufferRef = 0; - } - - /* - * Make sure the graph is configured with the current Format i.e. size - * and pixFmt. - */ - AVFrameFormat format = (AVFrameFormat) inputBuffer.getFormat(); - Dimension size = format.getSize(); - int pixFmt = format.getPixFmt(); - - if ((this.width != size.width) - || (this.height != size.height) - || (this.pixFmt != pixFmt)) - reset(); - if (graph == 0) - { - String errorReason = null; - int error = 0; - long buffer = 0; - long ffsink = 0; - - graph = FFmpeg.avfilter_graph_alloc(); - if (graph == 0) - errorReason = "avfilter_graph_alloc"; - else - { - String filters - = VSRC_BUFFER_NAME + "=" + size.width + ":" + size.height - + ":" + pixFmt + ":1:1000000:1:1,hflip," - + VSINK_FFSINK_NAME; - long log_ctx = 0; - - error - = FFmpeg.avfilter_graph_parse( - graph, - filters, - 0, 0, - log_ctx); - if (error == 0) - { - /* - * Unfortunately, the name of an AVFilterContext created by - * avfilter_graph_parse is not the name of the AVFilter. - */ - String parsedFilterNameFormat = "Parsed filter %1$d %2$s"; - - buffer - = FFmpeg.avfilter_graph_get_filter( - graph, - String.format( - parsedFilterNameFormat, - 0, - VSRC_BUFFER_NAME)); - if (buffer == 0) - { - errorReason - = "avfilter_graph_get_filter: " + VSRC_BUFFER_NAME; - } - else - { - ffsink - = FFmpeg.avfilter_graph_get_filter( - graph, - String.format( - parsedFilterNameFormat, - 2, - VSINK_FFSINK_NAME)); - if (ffsink == 0) - { - errorReason - = "avfilter_graph_get_filter: " - + VSINK_FFSINK_NAME; - } - else - { - error - = FFmpeg.avfilter_graph_config(graph, log_ctx); - if (error != 0) - errorReason = "avfilter_graph_config"; - } - } - } - else - errorReason = "avfilter_graph_parse"; - if ((errorReason != null) || (error != 0)) - { - FFmpeg.avfilter_graph_free(graph); - graph = 0; - } - } - if (graph == 0) - { - if (errorReason != null) - { - if (error == 0) - logger.error(errorReason); - else - logger.error(errorReason + ": " + error); - } - return BUFFER_PROCESSED_FAILED; - } - else - { - this.width = size.width; - this.height = size.height; - this.pixFmt = pixFmt; - this.buffer = buffer; - this.ffsink = ffsink; - } - } - - /* - * The graph is configured for the current Format, apply its filters to - * the inputFrame. - */ - long inputFrame = ((AVFrame) inputBuffer.getData()).getPtr(); - - outputFilterBufferRef - = FFmpeg.get_filtered_video_frame( - inputFrame, this.width, this.height, this.pixFmt, - buffer, - ffsink, - outputFrame); - if(outputFilterBufferRef == 0) - { - /* - * If get_filtered_video_frame fails, it is likely to fail for any - * frame. Consequently, printing that it has failed will result in a - * lot of repeating logging output. Since the failure in question - * will be visible in the UI anyway, just debug it. - */ - if (logger.isDebugEnabled()) - logger.debug("get_filtered_video_frame"); - return BUFFER_PROCESSED_FAILED; - } - - Object out = outputBuffer.getData(); - - if (!(out instanceof AVFrame) - || (((AVFrame) out).getPtr() != outputFrame)) - { - outputBuffer.setData(new AVFrame(outputFrame)); - } - - outputBuffer.setDiscard(inputBuffer.isDiscard()); - outputBuffer.setDuration(inputBuffer.getDuration()); - outputBuffer.setEOM(inputBuffer.isEOM()); - outputBuffer.setFlags(inputBuffer.getFlags()); - outputBuffer.setFormat(format); - outputBuffer.setHeader(inputBuffer.getHeader()); - outputBuffer.setLength(inputBuffer.getLength()); - outputBuffer.setSequenceNumber(inputBuffer.getSequenceNumber()); - outputBuffer.setTimeStamp(inputBuffer.getTimeStamp()); - return BUFFER_PROCESSED_OK; - } - - /** - * Resets the state of this PlugIn. - */ - @Override - public synchronized void reset() - { - if (outputFilterBufferRef != 0) - { - FFmpeg.avfilter_unref_buffer(outputFilterBufferRef); - outputFilterBufferRef = 0; - } - if (graph != 0) - { - FFmpeg.avfilter_graph_free(graph); - graph = 0; - - width = 0; - height = 0; - pixFmt = FFmpeg.PIX_FMT_NONE; - buffer = 0; - ffsink = 0; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/ImageScaler.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/ImageScaler.java deleted file mode 100644 index 4850460b6..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/ImageScaler.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.video; - -import java.awt.*; -import java.awt.image.*; - -import javax.media.Buffer; -import javax.media.Codec; -import javax.media.Format; -import javax.media.format.RGBFormat; -import javax.media.format.VideoFormat; - -import net.sf.fmj.media.AbstractCodec; -import net.sf.fmj.media.util.BufferToImage; -import net.sf.fmj.media.util.ImageToBuffer; - -/** - * Codec that scales images from one size to another. - * Interestingly, cross-platform JMF does not appear to have a corresponding codec. - * @author Ken Larson - * - * Original from fmj project, changed only output format sizes. - * The sizes are those supported in h263 and h264. - * @author Damian Minkov - * @author Sebastien Vincent - */ -public class ImageScaler - extends AbstractCodec - implements Codec -{ - // TODO: all formats supported by BufferToImage - private final Format[] supportedInputFormats = new Format[] { - new RGBFormat(null, -1, Format.intArray, -1.0f, 32, -1, -1, -1), - }; - private final Format[] supportedOutputFormats = new Format[] { - //new RGBFormat(new Dimension(1280, 1024), -1, Format.intArray, -1.0f, 32, -1, -1, -1), - //new RGBFormat(new Dimension(1280, 800), -1, Format.intArray, -1.0f, 32, -1, -1, -1), - new RGBFormat(new Dimension(1024, 768), -1, Format.intArray, -1.0f, 32, -1, -1, -1), - new RGBFormat(new Dimension(800, 600), -1, Format.intArray, -1.0f, 32, -1, -1, -1), - new RGBFormat(new Dimension(640, 480), -1, Format.intArray, -1.0f, 32, -1, -1, -1), - new RGBFormat(new Dimension(720, 576), -1, Format.intArray, -1.0f, 32, -1, -1, -1), - //P720 - new RGBFormat(new Dimension(720, 480), -1, Format.intArray, -1.0f, 32, -1, -1, -1), - //CIF4 - new RGBFormat(new Dimension(704, 576), -1, Format.intArray, -1.0f, 32, -1, -1, -1), - //CIF - new RGBFormat(new Dimension(352, 288), -1, Format.intArray, -1.0f, 32, -1, -1, -1), - new RGBFormat(new Dimension(320, 240), -1, Format.intArray, -1.0f, 32, -1, -1, -1), - //QCIF - new RGBFormat(new Dimension(176, 144), -1, Format.intArray, -1.0f, 32, -1, -1, -1), - //SQCIF - new RGBFormat(new Dimension(128, 96), -1, Format.intArray, -1.0f, 32, -1, -1, -1), - }; - - private BufferToImage bufferToImage; - - private boolean passthrough; - - @Override - public Format[] getSupportedInputFormats() - { - return supportedInputFormats; - } - - @Override - public Format[] getSupportedOutputFormats(Format input) - { -// if (input == null) - return supportedOutputFormats; -// VideoFormat inputCast = (VideoFormat) input; -// final Format[] result = new Format[] { -// new RGBFormat(DIMENSION, -1, Format.intArray, -1.0f, 32, -1, -1, -1)}; -// // TODO: we have to specify the RGB, etc. in the output format. -// return result; - } - - @Override - public Format setInputFormat(Format format) - { - final VideoFormat videoFormat = (VideoFormat) format; - if (videoFormat.getSize() == null) - return null; // must set a size. - - // TODO: check VideoFormat and compatibility - bufferToImage = new BufferToImage(videoFormat); - - format = super.setInputFormat(format); - updatePassthrough(); - return format; - } - - @Override - public Format setOutputFormat(Format format) - { - format = super.setOutputFormat(format); - updatePassthrough(); - return format; - } - - private void updatePassthrough() - { - Format outputFormat = getOutputFormat(); - if (outputFormat != null) - { - Dimension outputSize = ((VideoFormat) outputFormat).getSize(); - if (outputSize != null) - { - Format inputFormat = getInputFormat(); - passthrough = - (inputFormat != null) - && outputSize.equals( - ((VideoFormat) inputFormat).getSize()); - return; - } - } - passthrough = false; - } - - @Override - public int process(Buffer input, Buffer output) - { - if (!checkInputBuffer(input)) - { - return BUFFER_PROCESSED_FAILED; - } - - if (isEOM(input)) - { - propagateEOM(output); // TODO: what about data? can there be any? - return BUFFER_PROCESSED_OK; - } - - // sometimes format sizes are the same but some other field is different - // and jmf use the scaler (in my case length field was not sent in - // one of the formats) the check for sizes is made in method - // setInputFormat - if(passthrough) - { - output.setData(input.getData()); - output.setLength(input.getLength()); - output.setOffset(input.getOffset()); - return BUFFER_PROCESSED_OK; - } - - final BufferedImage image = (BufferedImage) bufferToImage.createImage(input); -/* - final Dimension inputSize = ((VideoFormat) inputFormat).getSize(); - final Dimension outputSize = ((VideoFormat) outputFormat).getSize(); - final double scaleX = ((double) outputSize.width) / ((double) inputSize.width); - final double scaleY = ((double) outputSize.height) / ((double) inputSize.height); - - final BufferedImage scaled = scale(image, scaleX, scaleY); // TODO: is the size exact? what about rounding errors? -*/ - - final Dimension outputSize = ((VideoFormat) outputFormat).getSize(); - /* rescale by preserving ratio */ - final BufferedImage scaled = scalePreserveRatio(image, outputSize.width, outputSize.height); // TODO: is the size exact? what about rounding errors? - - final Buffer b = ImageToBuffer.createBuffer(scaled, ((VideoFormat) outputFormat).getFrameRate()); - output.setData(b.getData()); - output.setLength(b.getLength()); - output.setOffset(b.getOffset()); - output.setFormat(b.getFormat()); - // TODO: what about format? - - return BUFFER_PROCESSED_OK; - } - - /** - * Get a scaled BufferedImage that preserves ratio and puts black - * borders if the ratio of the source image is different than the ratio of - * the scaled image. - *

- * Mainly inspired by - * http://java.developpez.com/faq/gui/?page=graphique_general_images - * #GRAPHIQUE_IMAGE_redimensionner - *

- * - * @param src the BufferedImage to scale - * @param width width of the scaled image - * @param height height of scaled image - * @return the BufferedImage which represents src scaled - * to width and height - */ - public static BufferedImage scalePreserveRatio(BufferedImage src, - int width, - int height) - { - BufferedImage buf = new BufferedImage(width, height, src.getType()); - double ratioSrc = (double)src.getWidth() / (double)src.getHeight(); - double ratioDst = width / height; - int startWidth = 0; - int startHeight = 0; - - if(Double.compare(ratioSrc, ratioDst) != 0) - { - /* adjust ratio */ - int newWidth = 0; - int newHeight = ((src.getHeight() * width) / src.getWidth()); - - /* first try to adjust height */ - startHeight = (height - newHeight) / 2; - - if(startHeight < 0) - { - /* rescale width */ - newWidth = ((src.getWidth() * height) / src.getHeight()); - startWidth = (width - newWidth) / 2; - - startHeight = 0; - width = newWidth; - } - else - { - height = newHeight; - } - } - - Graphics2D g2d = buf.createGraphics(); - g2d.setBackground(Color.BLACK); - g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, - RenderingHints.VALUE_INTERPOLATION_BILINEAR); - g2d.drawImage(src, startWidth, startHeight, width, height, null); - g2d.dispose(); - return buf; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/SwScaler.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/SwScaler.java deleted file mode 100644 index 3abf18431..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/SwScaler.java +++ /dev/null @@ -1,663 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.video; - -import java.awt.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.control.*; -import net.java.sip.communicator.util.*; -import net.sf.fmj.media.*; - -/** - * Implements a Codec which uses libswscale to scale images and convert - * between color spaces (typically, RGB and YUV). - * - * @author Sebastien Vincent - * @author Lyubomir Marinov - */ -public class SwScaler - extends AbstractCodec -{ - - /** - * The Logger used by the SwScaler class and its instances - * for logging output. - */ - private static final Logger logger = Logger.getLogger(SwScaler.class); - - /** - * The minimum height and/or width of the input and/or output to be passed - * to sws_scale in order to prevent its crashing. - */ - private static final int MIN_SWS_SCALE_HEIGHT_OR_WIDTH = 4; - - /** - * The indicator which determines whether this scaler will attempt to keep - * the width and height of YUV 420 output even. - */ - private final boolean fixOddYuv420Size; - - /** - * The FrameProcessingControl of this Codec which allows - * JMF to instruct it to drop frames because it's behind schedule. - */ - private final FrameProcessingControlImpl frameProcessingControl - = new FrameProcessingControlImpl(); - - /** - * Supported output formats. - */ - private Format[] supportedOutputFormats = new Format[] - { - new YUVFormat(null, -1, Format.byteArray, -1.0f, YUVFormat.YUV_420, - -1, -1, 0, -1, -1), - new YUVFormat(null, -1, Format.intArray, -1.0f, YUVFormat.YUV_420, - -1, -1, 0, -1, -1), - new YUVFormat(null, -1, Format.shortArray, -1.0f, YUVFormat.YUV_420, - -1, -1, 0, -1, -1), - new RGBFormat(null, -1, Format.byteArray, -1.0f, 32, -1, -1, -1), - new RGBFormat(null, -1, Format.intArray, -1.0f, 32, -1, -1, -1), - new RGBFormat(null, -1, Format.shortArray, -1.0f, 32, -1, -1, -1), - new RGBFormat(null, -1, Format.byteArray, -1.0f, 24, -1, -1, -1), - new RGBFormat(null, -1, Format.intArray, -1.0f, 24, -1, -1, -1), - new RGBFormat(null, -1, Format.shortArray, -1.0f, 24, -1, -1, -1), - }; - - /** - * Libswscale context pointer. - */ - private long swsContext = 0; - - /** - * Initializes a new SwScaler instance which doesn't have an output - * size and will use a default one when it becomes necessary unless an - * explicit one is specified in the meantime. - */ - public SwScaler() - { - this(false); - } - - /** - * Initializes a new SwScaler instance which can optionally attempt - * to keep the width and height of YUV 420 output even. - * - * @param fixOddYuv420Size true to keep the width and height of YUV - * 420 output even; otherwise, false - */ - protected SwScaler(boolean fixOddYuv420Size) - { - this.fixOddYuv420Size = fixOddYuv420Size; - - inputFormats = new Format[] - { - new AVFrameFormat(), - new RGBFormat(null, -1, Format.byteArray, -1.0f, 32, -1, -1, -1), - new RGBFormat(null, -1, Format.intArray, -1.0f, 32, -1, -1, -1), - new RGBFormat(null, -1, Format.shortArray, -1.0f, 32, -1, -1, -1), - new RGBFormat(null, -1, Format.byteArray, -1.0f, 24, -1, -1, -1), - new RGBFormat(null, -1, Format.intArray, -1.0f, 24, -1, -1, -1), - new RGBFormat(null, -1, Format.shortArray, -1.0f, 24, -1, -1, -1), - new YUVFormat(null, -1, Format.byteArray, -1.0f, YUVFormat.YUV_420, - -1, -1, 0, -1, -1), - new YUVFormat(null, -1, Format.intArray, -1.0f, YUVFormat.YUV_420, - -1, -1, 0, -1, -1), - new YUVFormat(null, -1, Format.shortArray, -1.0f, YUVFormat.YUV_420, - -1, -1, 0, -1, -1), - }; - - addControl(frameProcessingControl); - } - - /** - * Close codec. - */ - @Override - public void close() - { - try - { - if (swsContext != 0) - { - FFmpeg.sws_freeContext(swsContext); - swsContext = 0; - } - } - finally - { - super.close(); - } - } - - /** - * Gets the Format in which this Codec is currently - * configured to accept input media data. - *

- * Makes the protected super implementation public. - *

- * - * @return the Format in which this Codec is currently - * configured to accept input media data - * @see AbstractCodec#getInputFormat() - */ - @Override - public Format getInputFormat() - { - return super.getInputFormat(); - } - - /** - * Gets native (FFmpeg) RGB format. - * - * @param rgb JMF RGBFormat - * @return native RGB format - */ - public static int getNativeRGBFormat(RGBFormat rgb) - { - int fmt; - - if(rgb.getBitsPerPixel() == 32) - switch(rgb.getRedMask()) - { - case 1: - case 0xff: - fmt = FFmpeg.PIX_FMT_BGR32; - break; - case 2: - case (0xff << 8): - fmt = FFmpeg.PIX_FMT_BGR32_1; - break; - case 3: - case (0xff << 16): - fmt = FFmpeg.PIX_FMT_RGB32; - break; - case 4: - case (0xff << 24): - fmt = FFmpeg.PIX_FMT_RGB32_1; - break; - default: - /* assume ARGB ? */ - fmt = FFmpeg.PIX_FMT_RGB32; - break; - } - else - fmt = FFmpeg.PIX_FMT_RGB24; - - return fmt; - } - - /** - * Gets the output size. - * - * @return the output size - */ - public Dimension getOutputSize() - { - Format outputFormat = getOutputFormat(); - - if (outputFormat == null) - { - // They all have one and the same size. - outputFormat = supportedOutputFormats[0]; - } - return ((VideoFormat) outputFormat).getSize(); - } - - /** - * Gets the supported output formats for an input one. - * - * @param input input format to get supported output ones for - * @return array of supported output formats - */ - @Override - public Format[] getSupportedOutputFormats(Format input) - { - if(input == null) - return supportedOutputFormats; - - /* if size is set for element 0 (YUVFormat), it is also set - * for element 1 (RGBFormat) and so on... - */ - Dimension size = ((VideoFormat) supportedOutputFormats[0]).getSize(); - - /* no specified size set so return the same size as input - * in output format supported - */ - VideoFormat videoInput = (VideoFormat) input; - - if(size == null) - size = videoInput.getSize(); - - float frameRate = videoInput.getFrameRate(); - - return - new Format[] - { - new YUVFormat(size, -1, Format.byteArray, frameRate, - YUVFormat.YUV_420, -1, -1, 0, -1, -1), - new YUVFormat(size, -1, Format.intArray, frameRate, - YUVFormat.YUV_420, -1, -1, 0, -1, -1), - new YUVFormat(size, -1, Format.shortArray, frameRate, - YUVFormat.YUV_420, -1, -1, 0, -1, -1), - new RGBFormat(size, -1, Format.byteArray, frameRate, 32, -1, -1, - -1), - new RGBFormat(size, -1, Format.intArray, frameRate, 32, -1, -1, - -1), - new RGBFormat(size, -1, Format.shortArray, frameRate, 32, -1, - -1, -1), - new RGBFormat(size, -1, Format.byteArray, frameRate, 24, -1, -1, - -1), - new RGBFormat(size, -1, Format.intArray, frameRate, 24, -1, -1, - -1), - new RGBFormat(size, -1, Format.shortArray, frameRate, 24, -1, - -1, -1) - }; - } - - /** - * Processes (converts color space and/or scales) a buffer. - * - * @param input input buffer - * @param output output buffer - * @return BUFFER_PROCESSED_OK if buffer has been successfully - * processed - */ - @Override - public int process(Buffer input, Buffer output) - { - if (!checkInputBuffer(input)) - return BUFFER_PROCESSED_FAILED; - if (isEOM(input)) - { - propagateEOM(output); - return BUFFER_PROCESSED_OK; - } - if (input.isDiscard() || frameProcessingControl.isMinimalProcessing()) - { - output.setDiscard(true); - return BUFFER_PROCESSED_OK; - } - - // Determine the input Format. - VideoFormat inputFormat = (VideoFormat) input.getFormat(); - Format thisInputFormat = getInputFormat(); - - if ((inputFormat != thisInputFormat) - && !inputFormat.equals(thisInputFormat)) - setInputFormat(inputFormat); - - // Determine the output Format and size. - VideoFormat outputFormat = (VideoFormat) getOutputFormat(); - - if (outputFormat == null) - { - /* - * The format of the output Buffer is not documented to be used as - * input to the #process method. Anyway, we're trying to use it in - * case this Codec doesn't have an outputFormat set which is - * unlikely to ever happen. - */ - outputFormat = (VideoFormat) output.getFormat(); - if (outputFormat == null) - return BUFFER_PROCESSED_FAILED; - } - - Dimension outputSize = outputFormat.getSize(); - - if (outputSize == null) - { - outputSize = inputFormat.getSize(); - if (outputSize == null) - return BUFFER_PROCESSED_FAILED; - } - - int outputWidth = outputSize.width; - int outputHeight = outputSize.height; - - if ((outputWidth < MIN_SWS_SCALE_HEIGHT_OR_WIDTH) - || (outputHeight <= MIN_SWS_SCALE_HEIGHT_OR_WIDTH)) - return OUTPUT_BUFFER_NOT_FILLED; // sws_scale will crash - - // Apply the outputSize to the outputFormat of the output Buffer. - outputFormat = setSize(outputFormat, outputSize); - if (outputFormat == null) - return BUFFER_PROCESSED_FAILED; - - int dstFmt; - int dstLength; - - if (outputFormat instanceof YUVFormat) - { - dstFmt = FFmpeg.PIX_FMT_YUV420P; - /* YUV420P is 12 bits per pixel i.e. 1.5 bytes. */ - dstLength = (int) (outputWidth * outputHeight * 1.5); - } - else /* RGB format */ - { - dstFmt - = OSUtils.IS_ANDROID - ? getNativeRGBFormat((RGBFormat) outputFormat) - : FFmpeg.PIX_FMT_RGB32; - dstLength = (outputWidth * outputHeight * 4); - } - - Class outputDataType = outputFormat.getDataType(); - Object dst = output.getData(); - - if (Format.byteArray.equals(outputDataType)) - { - if(dst == null || ((byte[])dst).length < dstLength) - dst = new byte[dstLength]; - } - else if (Format.intArray.equals(outputDataType)) - { - /* Java int is always 4 bytes. */ - dstLength = dstLength / 4 + ((dstLength % 4 == 0) ? 0 : 1); - if(dst == null || ((int[])dst).length < dstLength) - dst = new int[dstLength]; - } - else if (Format.shortArray.equals(outputDataType)) - { - /* Java short is always 2 bytes. */ - dstLength = dstLength / 2 + ((dstLength % 2 == 0) ? 0 : 1); - if(dst == null || ((short[])dst).length < dstLength) - dst = new short[dstLength]; - } - else - { - logger.error("Unknown data type " + outputDataType); - return BUFFER_PROCESSED_FAILED; - } - - Dimension inputSize = inputFormat.getSize(); - - if (inputSize == null) - return BUFFER_PROCESSED_FAILED; - - int inputWidth = inputSize.width; - int inputHeight = inputSize.height; - - if ((inputWidth < MIN_SWS_SCALE_HEIGHT_OR_WIDTH) - || (inputHeight < MIN_SWS_SCALE_HEIGHT_OR_WIDTH)) - return OUTPUT_BUFFER_NOT_FILLED; // sws_scale will crash - - Object src = input.getData(); - int srcFmt; - long srcPicture; - - if (src instanceof AVFrame) - { - srcFmt = ((AVFrameFormat) inputFormat).getPixFmt(); - srcPicture = ((AVFrame) src).getPtr(); - } - else - { - srcFmt - = (inputFormat instanceof YUVFormat) - ? FFmpeg.PIX_FMT_YUV420P - : getNativeRGBFormat((RGBFormat) inputFormat); - srcPicture = 0; - } - - swsContext - = FFmpeg.sws_getCachedContext( - swsContext, - inputWidth, inputHeight, srcFmt, - outputWidth, outputHeight, dstFmt, - FFmpeg.SWS_BICUBIC); - - if (srcPicture == 0) - { - FFmpeg.sws_scale( - swsContext, - src, srcFmt, inputWidth, inputHeight, 0, inputHeight, - dst, dstFmt, outputWidth, outputHeight); - } - else - { - FFmpeg.sws_scale( - swsContext, - srcPicture, 0, inputHeight, - dst, dstFmt, outputWidth, outputHeight); - } - - output.setData(dst); - output.setDuration(input.getDuration()); - output.setFlags(input.getFlags()); - output.setFormat(outputFormat); - output.setLength(dstLength); - output.setOffset(0); - output.setSequenceNumber(input.getSequenceNumber()); - output.setTimeStamp(input.getTimeStamp()); - - // flags - int inFlags = input.getFlags(); - int outFlags = output.getFlags(); - - if ((inFlags & Buffer.FLAG_LIVE_DATA) != 0) - outFlags |= Buffer.FLAG_LIVE_DATA; - if ((inFlags & Buffer.FLAG_NO_WAIT) != 0) - outFlags |= Buffer.FLAG_NO_WAIT; - if ((inFlags & Buffer.FLAG_RELATIVE_TIME) != 0) - outFlags |= Buffer.FLAG_RELATIVE_TIME; - if ((inFlags & Buffer.FLAG_RTP_TIME) != 0) - outFlags |= Buffer.FLAG_RTP_TIME; - if ((inFlags & Buffer.FLAG_SYSTEM_TIME) != 0) - outFlags |= Buffer.FLAG_SYSTEM_TIME; - output.setFlags(outFlags); - - return BUFFER_PROCESSED_OK; - } - - /** - * Sets the input format. - * - * @param format format to set - * @return format - */ - @Override - public Format setInputFormat(Format format) - { - Format inputFormat - = (format instanceof VideoFormat) - ? super.setInputFormat(format) - : null /* A size is not required, the input must be video. */; - - if (inputFormat != null) - { - if (logger.isDebugEnabled()) - logger.debug("SwScaler set to input in " + inputFormat); - } - return inputFormat; - } - - /** - * Sets the Format in which this Codec is to output media - * data. - * - * @param format the Format in which this Codec is to - * output media data - * @return the Format in which this Codec is currently - * configured to output media data or null if format was - * found to be incompatible with this Codec - */ - @Override - public Format setOutputFormat(Format format) - { - if (fixOddYuv420Size && (format instanceof YUVFormat)) - { - YUVFormat yuvFormat = (YUVFormat) format; - - if (YUVFormat.YUV_420 == yuvFormat.getYuvType()) - { - Dimension size = yuvFormat.getSize(); - - if ((size != null) && (size.width > 2) && (size.height > 2)) - { - int width = (size.width >> 1) << 1; - int height = (size.height >> 1) << 1; - - if ((width != size.width) || (height != size.height)) - { - format - = new YUVFormat( - new Dimension(width, height), - Format.NOT_SPECIFIED, - yuvFormat.getDataType(), - yuvFormat.getFrameRate(), - yuvFormat.getYuvType(), - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED, - 0, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED); - } - } - } - } - - Format outputFormat = super.setOutputFormat(format); - - if (logger.isDebugEnabled() && (outputFormat != null)) - logger.debug("SwScaler set to output in " + outputFormat); - return outputFormat; - } - - /** - * Sets the size i.e. width and height of the current outputFormat - * of this SwScaler - * - * @param size the size i.e. width and height to be set on the current - * outputFormat of this SwScaler - */ - private void setOutputFormatSize(Dimension size) - { - VideoFormat outputFormat = (VideoFormat) getOutputFormat(); - - if (outputFormat != null) - { - outputFormat = setSize(outputFormat, size); - if (outputFormat != null) - setOutputFormat(outputFormat); - } - } - - /** - * Sets the output size. - * - * @param size the size to set as the output size - */ - public void setOutputSize(Dimension size) - { - supportedOutputFormats[0] - = new YUVFormat(size, -1, Format.byteArray, -1.0f, - YUVFormat.YUV_420, -1, -1, 0, -1, -1); - supportedOutputFormats[1] - = new YUVFormat(size, -1, Format.intArray, -1.0f, YUVFormat.YUV_420, - -1, -1, 0, -1, -1); - supportedOutputFormats[2] - = new YUVFormat(size, -1, Format.shortArray, -1.0f, - YUVFormat.YUV_420, -1, -1, 0, -1, -1); - supportedOutputFormats[3] - = new RGBFormat(size, -1, Format.byteArray, -1.0f, 32, -1, -1, -1); - supportedOutputFormats[4] - = new RGBFormat(size, -1, Format.intArray, -1.0f, 32, -1, -1, -1); - supportedOutputFormats[5] - = new RGBFormat(size, -1, Format.shortArray, -1.0f, 32, -1, -1, -1); - supportedOutputFormats[6] - = new RGBFormat(size, -1, Format.byteArray, -1.0f, 24, -1, -1, -1); - supportedOutputFormats[7] - = new RGBFormat(size, -1, Format.intArray, -1.0f, 24, -1, -1, -1); - supportedOutputFormats[8] - = new RGBFormat(size, -1, Format.shortArray, -1.0f, 24, -1, -1, -1); - - // Set the size to the outputFormat as well. - setOutputFormatSize(size); - } - - /** - * Gets a VideoFormat with a specific size i.e. width and height - * using a specific VideoFormat as a template. - * - * @param format the VideoFormat which is the template for the - * VideoFormat to be returned - * @param size the size i.e. width and height of the VideoFormat to - * be returned - * @return a VideoFormat with the specified size and based - * on the specified format - */ - private static VideoFormat setSize(VideoFormat format, Dimension size) - { - /* - * Since the size of the Format has changed, its size-related properties - * should change as well. Format#intersects doesn't seem to be cool - * because it preserves them and thus the resulting Format is - * inconsistent. - */ - if (format instanceof RGBFormat) - { - RGBFormat rgbFormat = (RGBFormat) format; - Class dataType = format.getDataType(); - int bitsPerPixel = rgbFormat.getBitsPerPixel(); - int pixelStride = rgbFormat.getPixelStride(); - - if ((pixelStride == Format.NOT_SPECIFIED) - && (dataType != null) - && (bitsPerPixel != Format.NOT_SPECIFIED)) - pixelStride - = dataType.equals(Format.byteArray) - ? (bitsPerPixel / 8) - : 1; - format - = new RGBFormat( - size, - Format.NOT_SPECIFIED, - dataType, - format.getFrameRate(), - bitsPerPixel, - rgbFormat.getRedMask(), - rgbFormat.getGreenMask(), - rgbFormat.getBlueMask(), - pixelStride, - ((pixelStride == Format.NOT_SPECIFIED) - || (size == null)) - ? Format.NOT_SPECIFIED - : (pixelStride * size.width) /* lineStride */, - rgbFormat.getFlipped(), - rgbFormat.getEndian()); - } - else if (format instanceof YUVFormat) - { - YUVFormat yuvFormat = (YUVFormat) format; - - format - = new YUVFormat( - size, - Format.NOT_SPECIFIED, - format.getDataType(), - format.getFrameRate(), - yuvFormat.getYuvType(), - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED, - 0, - Format.NOT_SPECIFIED, - Format.NOT_SPECIFIED); - } - else if (format != null) - { - logger.warn( - "SwScaler outputFormat of type " - + format.getClass().getName() - + " is not supported for optimized scaling."); - } - return format; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/h263p/DePacketizer.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/h263p/DePacketizer.java deleted file mode 100644 index e910bca34..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/h263p/DePacketizer.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.video.h263p; - -import java.util.Arrays; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.util.Logger; -import net.sf.fmj.media.*; - -/** - * Depacketizes H.263+ RTP packets in in accord with RFC 4529 "RTP Payload - * Format for ITU-T Rec. H.263 Video". - * - * @author Sebastien Vincent - * @author Lubomir Marinov - */ -public class DePacketizer - extends AbstractCodecExt -{ - /** - * The Logger used by the DePacketizer class and its - * instances for logging output. - */ - private static final Logger logger = Logger.getLogger(DePacketizer.class); - - /** - * The size of the padding at the end of the output data of this - * DePacketizer expected by the H.263+ decoder. - */ - private final int outputPaddingSize = FFmpeg.FF_INPUT_BUFFER_PADDING_SIZE; - - /** - * Keeps track of last (input) sequence number in order to avoid - * inconsistent data. - */ - private long lastSequenceNumber = -1; - - /** - * The indicator which determines whether incomplete buffer packets are - * output from the H.263+ DePacketizer to the decoder. - */ - private static final boolean OUTPUT_INCOMPLETE_BUFFER = true; - - /** - * Initializes a new DePacketizer instance which is to depacketize - * H.263+ RTP packet. - */ - public DePacketizer() - { - super( - "H263+ DePacketizer", - VideoFormat.class, - new VideoFormat[] { new VideoFormat(Constants.H263P) }); - - inputFormats - = new VideoFormat[] { new VideoFormat(Constants.H263P_RTP) }; - } - - /** - * Close the Codec. - */ - protected void doClose() - { - } - - /** - * Opens this Codec and acquires the resources that it needs to - * operate. A call to {@link PlugIn#open()} on this instance will result in - * a call to doOpen only if {@link AbstractCodec#opened} is - * false. All required input and/or output formats are assumed to - * have been set on this Codec before doOpen is called. - * - * @throws ResourceUnavailableException if any of the resources that this - * Codec needs to operate cannot be acquired - * @see AbstractCodecExt#doOpen() - */ - protected void doOpen() - throws ResourceUnavailableException - { - } - - /** - * Processes (depacketizes) a buffer. - * - * @param inBuffer input buffer - * @param outBuffer output buffer - * @return BUFFER_PROCESSED_OK if buffer has been successfully - * processed - */ - protected int doProcess(Buffer inBuffer, Buffer outBuffer) - { - long sequenceNumber = inBuffer.getSequenceNumber(); - - if ((lastSequenceNumber != -1) - && ((sequenceNumber - lastSequenceNumber) != 1)) - { - int ret = 0; - - /* maybe we lost a frame somewhere or the sequence number reach - * its maximum number - */ - if (logger.isTraceEnabled()) - logger.trace( - "Dropped RTP packets upto sequenceNumber " - + lastSequenceNumber - + " and continuing with sequenceNumber " - + sequenceNumber); - - ret = reset(outBuffer); - - if ((ret & OUTPUT_BUFFER_NOT_FILLED) == 0) - { - lastSequenceNumber = -1; - return ret; - } - } - - lastSequenceNumber = sequenceNumber; - - byte[] in = (byte[]) inBuffer.getData(); - int inLength = inBuffer.getLength(); - int inOffset = inBuffer.getOffset(); - int outOffset = outBuffer.getOffset(); - - if(inLength < 3) - { - return BUFFER_PROCESSED_FAILED; - } - - boolean pBit = ((in[inOffset] & 0x04) > 0); - boolean vBit = ((in[inOffset] & 0x02) > 0);; - int plen = ((in[inOffset] & 0x01) << 5) + - ((in[inOffset + 1] & 0xF8) >> 3); - int dataLength = inLength - plen - (vBit ? 1 : 0) - (pBit ? 0 : 2); - - byte out[] = validateByteArraySize(outBuffer, outOffset + dataLength + - outputPaddingSize); - - if(pBit) - { - out[0] = 0x00; - out[1] = 0x00; - } - - if(vBit) - { - /* ignore VRC */ - } - - if(plen > 0) - { - if(logger.isInfoEnabled()) - { - logger.info("Extra picture header present PLEN=" + plen); - } - } - - System.arraycopy(in, inOffset + 2 + (vBit ? 1 : 0) + plen, - out, outOffset + (pBit ? 2 : 0), dataLength - (pBit ? 2 : 0)); - - padOutput(out, outOffset + dataLength); - - outBuffer.setLength(outOffset + dataLength); - outBuffer.setSequenceNumber(sequenceNumber); - - /* - * The RTP marker bit is set for the very last packet of the access unit - * indicated by the RTP time stamp to allow an efficient playout buffer - * handling. Consequently, we have to output it as well. - */ - if ((inBuffer.getFlags() & Buffer.FLAG_RTP_MARKER) != 0) - { - outBuffer.setFlags(outBuffer.getFlags() | Buffer.FLAG_RTP_MARKER); - outBuffer.setOffset(0); - return BUFFER_PROCESSED_OK; - } - else - { - outBuffer.setOffset(outOffset + dataLength); - return OUTPUT_BUFFER_NOT_FILLED; - } - } - - /** - * Appends {@link #outputPaddingSize} number of bytes to out - * beginning at index outOffset. The specified out is - * expected to be large enough to accommodate the mentioned number of bytes. - * - * @param out the buffer in which outputPaddingSize number of bytes - * are to be written - * @param outOffset the index in outOffset at which the writing of - * outputPaddingSize number of bytes is to begin - */ - private void padOutput(byte[] out, int outOffset) - { - Arrays.fill(out, outOffset, outOffset + outputPaddingSize, (byte) 0); - } - - /** - * Resets the states of this DePacketizer and a specific output - * Buffer so that they are ready to have this DePacketizer - * process input RTP payloads. - * - * @param outBuffer the output Buffer to be reset - * @return the flags such as BUFFER_PROCESSED_OK and - * OUTPUT_BUFFER_NOT_FILLED to be returned by - * {@link #process(Buffer, Buffer)} - */ - private int reset(Buffer outBuffer) - { - if (OUTPUT_INCOMPLETE_BUFFER && outBuffer.getLength() > 0) - { - Object outData = outBuffer.getData(); - - if (outData instanceof byte[]) - { - return (BUFFER_PROCESSED_OK | INPUT_BUFFER_NOT_CONSUMED); - } - } - - outBuffer.setLength(0); - return OUTPUT_BUFFER_NOT_FILLED; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/h263p/JNIDecoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/h263p/JNIDecoder.java deleted file mode 100644 index f17e97c7f..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/h263p/JNIDecoder.java +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.video.h263p; - -import java.awt.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.codec.video.*; -import net.sf.fmj.media.*; - -/** - * Implements a H.263+ decoder. - * - * @author Sebastien Vincent - * @author Lubomir Marinov - */ -public class JNIDecoder - extends AbstractCodec -{ - /** - * Plugin name. - */ - private static final String PLUGIN_NAME = "H.263+ Decoder"; - - /** - * The default output VideoFormat. - */ - private static final VideoFormat[] DEFAULT_OUTPUT_FORMATS - = new VideoFormat[] { new AVFrameFormat() }; - - /** - * Array of output VideoFormats. - */ - private final VideoFormat[] outputFormats; - - /** - * If decoder has got a picture. - */ - private final boolean[] got_picture = new boolean[1]; - - /** - * The codec context native pointer we will use. - */ - private long avcontext = 0; - - /** - * The decoded data is stored in avpicture in native ffmpeg format (YUV). - */ - private long avframe = 0; - - /** - * The last known width of {@link #avcontext} i.e. the video output by this - * JNIDecoder. Used to detect changes in the output size. - */ - private int width = 0; - - /** - * The last known height of {@link #avcontext} i.e. the video output by this - * JNIDecoder. Used to detect changes in the output size. - */ - private int height = 0; - - /** - * Initializes a new JNIDecoder instance which is to decode H.263+ - * encoded data into frames in YUV format. - */ - public JNIDecoder() - { - inputFormats - = new VideoFormat[] { new VideoFormat(Constants.H263P) }; - outputFormats - = new VideoFormat[] - { - new AVFrameFormat( - new Dimension( - Constants.VIDEO_WIDTH, - Constants.VIDEO_HEIGHT), - ensureFrameRate(Format.NOT_SPECIFIED), - FFmpeg.PIX_FMT_YUV420P, - Format.NOT_SPECIFIED) - }; - - Dimension outputSize = outputFormats[0].getSize(); - - width = outputSize.width; - height = outputSize.height; - } - - /** - * Check Format. - * - * @param format Format to check - * @return true if Format is H263P_RTP - */ - public boolean checkFormat(Format format) - { - return format.getEncoding().equals(Constants.H263P_RTP); - } - - /** - * Close Codec. - */ - @Override - public synchronized void close() - { - if (opened) - { - opened = false; - super.close(); - - FFmpeg.avcodec_close(avcontext); - FFmpeg.av_free(avcontext); - avcontext = 0; - - FFmpeg.av_free(avframe); - avframe = 0; - } - } - - /** - * Ensure frame rate. - * - * @param frameRate frame rate - * @return frame rate - */ - private float ensureFrameRate(float frameRate) - { - return frameRate; - } - - /** - * Get matching outputs for a specified input Format. - * - * @param in input Format - * @return array of matching outputs or null if there are no matching - * outputs. - */ - protected Format[] getMatchingOutputFormats(Format in) - { - VideoFormat ivf = (VideoFormat) in; - Dimension inSize = ivf.getSize(); - Dimension outSize; - - // return the default size/currently decoder and encoder - // set to transmit/receive at this size - if (inSize == null) - { - VideoFormat ovf = outputFormats[0]; - - if (ovf == null) - return null; - else - outSize = ovf.getSize(); - } - else - outSize = inSize; // Output in same size as input. - - return - new Format[] - { - new AVFrameFormat( - outSize, - ensureFrameRate(ivf.getFrameRate()), - FFmpeg.PIX_FMT_YUV420P, - Format.NOT_SPECIFIED) - }; - } - - /** - * Get plugin name. - * - * @return "H.263+ Decoder" - */ - @Override - public String getName() - { - return PLUGIN_NAME; - } - - /** - * Get all supported output Formats. - * - * @param in input Format to determine corresponding output - * Format/tt>s - * @return array of supported Format - */ - public Format[] getSupportedOutputFormats(Format in) - { - if (in == null) - return DEFAULT_OUTPUT_FORMATS; - - // mismatch input format - if (!(in instanceof VideoFormat) - || (AbstractCodecExt.matches(in, inputFormats) == null)) - return new Format[0]; - - // match input format - return getMatchingOutputFormats(in); - } - - /** - * Inits the codec instances. - * - * @throws ResourceUnavailableException if codec initialization failed - */ - @Override - public synchronized void open() - throws ResourceUnavailableException - { - if (opened) - return; - - /* from ffmpeg -formats output: "For example, the h263 decoder - * corresponds to the h263 and h263p encoders". That's why we use - * CODEC_ID_H263 for the decoder side (instead of CODEC_ID_H263P). - */ - long avcodec = FFmpeg.avcodec_find_decoder(FFmpeg.CODEC_ID_H263); - - avcontext = FFmpeg.avcodec_alloc_context(); - FFmpeg.avcodeccontext_set_workaround_bugs(avcontext, - FFmpeg.FF_BUG_AUTODETECT); - - if (FFmpeg.avcodec_open(avcontext, avcodec) < 0) - throw new RuntimeException("Could not open codec CODEC_ID_H263"); - - avframe = FFmpeg.avcodec_alloc_frame(); - - opened = true; - super.open(); - } - - /** - * Decodes H.263+ media data read from a specific input Buffer into - * a specific output Buffer. - * - * @param inBuffer input Buffer - * @param outBuffer output Buffer - * @return BUFFER_PROCESSED_OK if inBuffer has been - * successfully processed - */ - public synchronized int process(Buffer inBuffer, Buffer outBuffer) - { - if (!checkInputBuffer(inBuffer)) - return BUFFER_PROCESSED_FAILED; - - if (isEOM(inBuffer) || !opened) - { - propagateEOM(outBuffer); - return BUFFER_PROCESSED_OK; - } - - if (inBuffer.isDiscard()) - { - outBuffer.setDiscard(true); - return BUFFER_PROCESSED_OK; - } - - // Ask FFmpeg to decode. - got_picture[0] = false; - // TODO Take into account the offset of inputBuffer. - FFmpeg.avcodec_decode_video( - avcontext, - avframe, - got_picture, - (byte[]) inBuffer.getData(), inBuffer.getLength()); - - if (!got_picture[0]) - { - outBuffer.setDiscard(true); - return BUFFER_PROCESSED_OK; - } - - // format - int width = FFmpeg.avcodeccontext_get_width(avcontext); - int height = FFmpeg.avcodeccontext_get_height(avcontext); - - if ((width > 0) - && (height > 0) - && ((this.width != width) || (this.height != height))) - { - this.width = width; - this.height = height; - - // Output in same size and frame rate as input. - Dimension outSize = new Dimension(this.width, this.height); - VideoFormat inFormat = (VideoFormat) inBuffer.getFormat(); - float outFrameRate = ensureFrameRate(inFormat.getFrameRate()); - - outputFormat - = new AVFrameFormat( - outSize, - outFrameRate, - FFmpeg.PIX_FMT_YUV420P, - Format.NOT_SPECIFIED); - } - outBuffer.setFormat(outputFormat); - - // data - Object out = outBuffer.getData(); - - if (!(out instanceof AVFrame) || (((AVFrame) out).getPtr() != avframe)) - outBuffer.setData(new AVFrame(avframe)); - - // timeStamp - long pts = FFmpeg.AV_NOPTS_VALUE; // TODO avframe_get_pts(avframe); - - if (pts == FFmpeg.AV_NOPTS_VALUE) - outBuffer.setTimeStamp(Buffer.TIME_UNKNOWN); - else - { - outBuffer.setTimeStamp(pts); - - int outFlags = outBuffer.getFlags(); - - outFlags |= Buffer.FLAG_RELATIVE_TIME; - outFlags &= ~(Buffer.FLAG_RTP_TIME | Buffer.FLAG_SYSTEM_TIME); - outBuffer.setFlags(outFlags); - } - - return BUFFER_PROCESSED_OK; - } - - /** - * Sets the Format of the media data to be input for processing in - * this Codec. - * - * @param format the Format of the media data to be input for - * processing in this Codec - * @return the Format of the media data to be input for processing - * in this Codec if format is compatible with this - * Codec; otherwise, null - */ - @Override - public Format setInputFormat(Format format) - { - Format setFormat = super.setInputFormat(format); - - if (setFormat != null) - reset(); - return setFormat; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/h263p/JNIEncoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/h263p/JNIEncoder.java deleted file mode 100644 index 13d9d3098..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/h263p/JNIEncoder.java +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.video.h263p; - -import java.awt.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.sf.fmj.media.*; - -/** - * Implements a H.263+ encoder. - * - * @author Sebastien Vincent - * @author Lubomir Marinov - */ -public class JNIEncoder - extends AbstractCodec -{ - /** - * The frame rate to be assumed by JNIEncoder instance in the - * absence of any other frame rate indication. - */ - private static final int DEFAULT_FRAME_RATE = 30; - - /** - * Default output formats. - */ - private static final Format[] DEFAULT_OUTPUT_FORMATS - = { new VideoFormat(Constants.H263P) }; - - /** - * Key frame every 300 frames. - */ - private static final int IFRAME_INTERVAL = 300; - - /** - * Name of the code. - */ - private static final String PLUGIN_NAME = "H.263+ Encoder"; - - /** - * The codec we will use. - */ - private long avcontext = 0; - - /** - * The encoded data is stored in avpicture. - */ - private long avframe = 0; - - /** - * We use this buffer to supply data to encoder. - */ - private byte[] encFrameBuffer = null; - - /** - * The supplied data length. - */ - private int encFrameLen = 0; - - /** - * The raw frame buffer. - */ - private long rawFrameBuffer = 0; - - /** - * Next interval for an automatic keyframe. - */ - private int framesSinceLastIFrame = IFRAME_INTERVAL + 1; - - /** - * Initializes a new JNIEncoder instance. - */ - public JNIEncoder() - { - inputFormats - = new Format[] - { - new YUVFormat( - null, - Format.NOT_SPECIFIED, - Format.byteArray, - DEFAULT_FRAME_RATE, - YUVFormat.YUV_420, - Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, - 0, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED) - }; - - inputFormat = null; - outputFormat = null; - } - - /** - * Closes this Codec. - */ - @Override - public synchronized void close() - { - if (opened) - { - opened = false; - super.close(); - - FFmpeg.avcodec_close(avcontext); - FFmpeg.av_free(avcontext); - avcontext = 0; - - FFmpeg.av_free(avframe); - avframe = 0; - FFmpeg.av_free(rawFrameBuffer); - rawFrameBuffer = 0; - - encFrameBuffer = null; - } - } - - /** - * Gets the matching output formats for a specific format. - * - * @param in input format - * @return array for formats matching input format - */ - private Format[] getMatchingOutputFormats(Format in) - { - VideoFormat videoIn = (VideoFormat) in; - - return - new VideoFormat[] - { - new VideoFormat( - Constants.H263P, - videoIn.getSize(), - Format.NOT_SPECIFIED, - Format.byteArray, - videoIn.getFrameRate()) - }; - } - - /** - * Gets the name of this Codec. - * - * @return codec name - */ - @Override - public String getName() - { - return PLUGIN_NAME; - } - - /** - * Returns the list of formats supported at the output. - * - * @param in input Format to determine corresponding output - * Format/tt>s - * @return array of formats supported at output - */ - public Format[] getSupportedOutputFormats(Format in) - { - // null input format - if (in == null) - return DEFAULT_OUTPUT_FORMATS; - - // mismatch input format - if (!(in instanceof VideoFormat) - || (null == AbstractCodecExt.matches(in, inputFormats))) - return new Format[0]; - - return getMatchingOutputFormats(in); - } - - /** - * Opens this Codec. - */ - @Override - public synchronized void open() - throws ResourceUnavailableException - { - if (opened) - return; - - if (inputFormat == null) - throw new ResourceUnavailableException("No input format selected"); - if (outputFormat == null) - throw new ResourceUnavailableException("No output format selected"); - - VideoFormat outputVideoFormat = (VideoFormat) outputFormat; - Dimension size = outputVideoFormat.getSize(); - int width = size.width; - int height = size.height; - - long avcodec = FFmpeg.avcodec_find_encoder(FFmpeg.CODEC_ID_H263P); - - avcontext = FFmpeg.avcodec_alloc_context(); - - FFmpeg.avcodeccontext_set_pix_fmt(avcontext, FFmpeg.PIX_FMT_YUV420P); - FFmpeg.avcodeccontext_set_size(avcontext, width, height); - FFmpeg.avcodeccontext_set_qcompress(avcontext, 0.6f); - - int bitRate = 256000; - int frameRate = (int) outputVideoFormat.getFrameRate(); - - if (frameRate == Format.NOT_SPECIFIED) - frameRate = DEFAULT_FRAME_RATE; - - // average bit rate - FFmpeg.avcodeccontext_set_bit_rate(avcontext, bitRate); - FFmpeg.avcodeccontext_set_bit_rate_tolerance(avcontext, - bitRate / (frameRate - 1)); - //FFmpeg.avcodeccontext_set_rc_max_rate(avcontext, bitRate); - //FFmpeg.avcodeccontext_set_sample_aspect_ratio(avcontext, 0, 0); - - // time_base should be 1 / frame rate - FFmpeg.avcodeccontext_set_time_base(avcontext, 1, frameRate); - //FFmpeg.avcodeccontext_set_quantizer(avcontext, 10, 51, 4); - - FFmpeg.avcodeccontext_set_mb_decision(avcontext, - FFmpeg.FF_MB_DECISION_SIMPLE); - - //FFmpeg.avcodeccontext_set_rc_eq(avcontext, "blurCplx^(1-qComp)"); - - FFmpeg.avcodeccontext_add_flags(avcontext, - FFmpeg.CODEC_FLAG_LOOP_FILTER); - FFmpeg.avcodeccontext_add_flags(avcontext, - FFmpeg.CODEC_FLAG_AC_PRED); - FFmpeg.avcodeccontext_add_flags(avcontext, - FFmpeg.CODEC_FLAG_H263P_UMV); - FFmpeg.avcodeccontext_add_flags(avcontext, - FFmpeg.CODEC_FLAG_H263P_SLICE_STRUCT); - - FFmpeg.avcodeccontext_set_me_method(avcontext, 6); - FFmpeg.avcodeccontext_set_me_subpel_quality(avcontext, 2); - FFmpeg.avcodeccontext_set_me_range(avcontext, 18); - FFmpeg.avcodeccontext_set_me_cmp(avcontext, FFmpeg.FF_CMP_CHROMA); - FFmpeg.avcodeccontext_set_scenechange_threshold(avcontext, 40); - - // Constant quality mode (also known as constant ratefactor) - //FFmpeg.avcodeccontext_set_crf(avcontext, 0); - //FFmpeg.avcodeccontext_set_rc_buffer_size(avcontext, 0); - FFmpeg.avcodeccontext_set_gop_size(avcontext, IFRAME_INTERVAL); - //FFmpeg.avcodeccontext_set_i_quant_factor(avcontext, 1f / 1.4f); - - //FFmpeg.avcodeccontext_set_refs(avcontext, 2); - //FFmpeg.avcodeccontext_set_trellis(avcontext, 2); - - if (FFmpeg.avcodec_open(avcontext, avcodec) < 0) - { - throw - new ResourceUnavailableException( - "Could not open codec. (size= " - + width + "x" + height - + ")"); - } - - encFrameLen = (width * height * 3) / 2; - - rawFrameBuffer = FFmpeg.av_malloc(encFrameLen); - - avframe = FFmpeg.avcodec_alloc_frame(); - - int sizeInBytes = width * height; - - FFmpeg.avframe_set_data( - avframe, - rawFrameBuffer, - sizeInBytes, - sizeInBytes / 4); - FFmpeg.avframe_set_linesize(avframe, width, width / 2, width / 2); - - encFrameBuffer = new byte[encFrameLen]; - - opened = true; - - super.open(); - } - - /** - * Processes/encodes a buffer. - * - * @param inBuffer input buffer - * @param outBuffer output buffer - * @return BUFFER_PROCESSED_OK if buffer has been successfully - * processed - */ - public synchronized int process(Buffer inBuffer, Buffer outBuffer) - { - if (isEOM(inBuffer)) - { - propagateEOM(outBuffer); - reset(); - return BUFFER_PROCESSED_OK; - } - if (inBuffer.isDiscard()) - { - outBuffer.setDiscard(true); - reset(); - return BUFFER_PROCESSED_OK; - } - - Format inFormat = inBuffer.getFormat(); - - if ((inFormat != inputFormat) && !inFormat.matches(inputFormat)) - setInputFormat(inFormat); - - if (inBuffer.getLength() < 3) - { - outBuffer.setDiscard(true); - reset(); - return BUFFER_PROCESSED_OK; - } - - // copy data to avframe - FFmpeg.memcpy( - rawFrameBuffer, - (byte[]) inBuffer.getData(), inBuffer.getOffset(), - encFrameLen); - - if (framesSinceLastIFrame >= IFRAME_INTERVAL) - { - FFmpeg.avframe_set_key_frame(avframe, true); - framesSinceLastIFrame = 0; - } - else - { - framesSinceLastIFrame++; - FFmpeg.avframe_set_key_frame(avframe, false); - } - - // encode data - int encLen - = FFmpeg.avcodec_encode_video( - avcontext, - encFrameBuffer, encFrameLen, - avframe); - - /* - * Do not always allocate a new data array for outBuffer, try to reuse - * the existing one if it is suitable. - */ - Object outData = outBuffer.getData(); - byte[] out; - - if (outData instanceof byte[]) - { - out = (byte[]) outData; - if (out.length < encLen) - out = null; - } - else - out = null; - if (out == null) - out = new byte[encLen]; - - System.arraycopy(encFrameBuffer, 0, out, 0, encLen); - - outBuffer.setData(out); - outBuffer.setLength(encLen); - outBuffer.setOffset(0); - outBuffer.setTimeStamp(inBuffer.getTimeStamp()); - - return BUFFER_PROCESSED_OK; - } - - /** - * Sets the input format. - * - * @param in format to set - * @return format - */ - @Override - public Format setInputFormat(Format in) - { - // mismatch input format - if (!(in instanceof VideoFormat) - || (null == AbstractCodecExt.matches(in, inputFormats))) - return null; - - YUVFormat yuv = (YUVFormat) in; - - if (yuv.getOffsetU() > yuv.getOffsetV()) - return null; - - Dimension size = yuv.getSize(); - - if (size == null) - size = new Dimension(Constants.VIDEO_WIDTH, Constants.VIDEO_HEIGHT); - - int strideY = size.width; - int strideUV = strideY / 2; - int offsetU = strideY * size.height; - int offsetV = offsetU + strideUV * size.height / 2; - - int yuvMaxDataLength = (strideY + strideUV) * size.height; - - inputFormat - = new YUVFormat( - size, - yuvMaxDataLength + FFmpeg.FF_INPUT_BUFFER_PADDING_SIZE, - Format.byteArray, - yuv.getFrameRate(), - YUVFormat.YUV_420, - strideY, strideUV, - 0, offsetU, offsetV); - - // Return the selected inputFormat - return inputFormat; - } - - /** - * Sets the Format in which this Codec is to output media - * data. - * - * @param out the Format in which this Codec is to - * output media data - * @return the Format in which this Codec is currently - * configured to output media data or null if format was - * found to be incompatible with this Codec - */ - @Override - public Format setOutputFormat(Format out) - { - // mismatch output format - if (!(out instanceof VideoFormat) - || (null - == AbstractCodecExt.matches( - out, - getMatchingOutputFormats(inputFormat)))) - return null; - - VideoFormat videoOut = (VideoFormat) out; - Dimension outSize = videoOut.getSize(); - - if (outSize == null) - { - Dimension inSize = ((VideoFormat) inputFormat).getSize(); - - outSize - = (inSize == null) - ? new Dimension( - Constants.VIDEO_WIDTH, - Constants.VIDEO_HEIGHT) - : inSize; - } - - outputFormat - = new VideoFormat( - videoOut.getEncoding(), - outSize, - Format.NOT_SPECIFIED, - Format.byteArray, - videoOut.getFrameRate()); - - // Return the selected outputFormat - return outputFormat; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/h263p/Packetizer.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/h263p/Packetizer.java deleted file mode 100644 index 3267022a8..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/h263p/Packetizer.java +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.video.h263p; - -import java.awt.*; -import java.util.*; -import java.util.List; // disambiguation - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.sf.fmj.media.*; - -/** - * Packetizes H.263+ encoded data into RTP packets in accord with RFC 4529 - * "RTP Payload Format for ITU-T Rec. H.263 Video". - * - * @author Sebastien Vincent - * @author Lubomir Marinov - */ -public class Packetizer - extends AbstractPacketizer -{ - /** - * Array of default output formats. - */ - private static final Format[] DEFAULT_OUTPUT_FORMATS - = { new VideoFormat(Constants.H263P_RTP) }; - - /** - * Maximum payload size without the headers. - */ - public static final int MAX_PAYLOAD_SIZE = 1024; - - /** - * Name of the plugin. - */ - private static final String PLUGIN_NAME = "H263+ Packetizer"; - - /** - * The sequence number of the next RTP packet to be output by this - * Packetizer. - */ - private int sequenceNumber = 0; - - /** - * The list of H263+ "Start code" video packets to be sent as payload in RTP - * packets. - */ - private final List videoPkts = new LinkedList(); - - /** - * The timeStamp of the RTP packets in which H263+ packets are to be sent. - */ - private long timeStamp = 0; - - /** - * Initializes a new Packetizer instance which is to packetize - * H.263+ encoded data into RTP packets in accord with - * RFC 4529 "RTP Payload Format for ITU-T Rec. H.263 Video". - */ - public Packetizer() - { - inputFormats = new Format[] { new VideoFormat(Constants.H263P) }; - - inputFormat = null; - outputFormat = null; - } - - /** - * Get the matching output formats for a specific format. - * - * @param in input format - * @return array for formats matching input format - */ - private Format[] getMatchingOutputFormats(Format in) - { - VideoFormat videoIn = (VideoFormat) in; - Dimension inSize = videoIn.getSize(); - - return - new VideoFormat[] - { - new VideoFormat( - Constants.H263P_RTP, - inSize, - Format.NOT_SPECIFIED, - Format.byteArray, - videoIn.getFrameRate()) - }; - } - - /** - * Get codec name. - * - * @return codec name - */ - @Override - public String getName() - { - return PLUGIN_NAME; - } - - /** - * Return the list of formats supported at the output. - * @param in input Format to determine corresponding output - * Format/tt>s - * @return array of formats supported at output - */ - public Format[] getSupportedOutputFormats(Format in) - { - // null input format - if (in == null) - return DEFAULT_OUTPUT_FORMATS; - - // mismatch input format - if (!(in instanceof VideoFormat) - || (null == AbstractCodecExt.matches(in, inputFormats))) - { - return new Format[0]; - } - - return getMatchingOutputFormats(in); - } - - /** - * Open this Packetizer. - * - * @throws ResourceUnavailableException if something goes wrong during - * initialization of the Packetizer. - */ - @Override - public synchronized void open() - throws ResourceUnavailableException - { - if (!opened) - { - videoPkts.clear(); - sequenceNumber = 0; - - super.open(); - opened = true; - } - } - - /** - * Close this Packetizer. - */ - @Override - public synchronized void close() - { - if (opened) - { - videoPkts.clear(); - opened = false; - super.close(); - } - } - - /** - * Sets the input format. - * - * @param in format to set - * @return format - */ - @Override - public Format setInputFormat(Format in) - { - /* - * Return null if the specified input Format is incompatible with this - * Packetizer. - */ - if (!(in instanceof VideoFormat) - || null == AbstractCodecExt.matches(in, inputFormats)) - return null; - - inputFormat = in; - return in; - } - - /** - * Sets the Format in which this Codec is to output media - * data. - * - * @param out the Format in which this Codec is to - * output media data - * @return the Format in which this Codec is currently - * configured to output media data or null if format was - * found to be incompatible with this Codec - */ - @Override - public Format setOutputFormat(Format out) - { - /* - * Return null if the specified output Format is incompatible with this - * Packetizer. - */ - if (!(out instanceof VideoFormat) - || (null - == AbstractCodecExt.matches( - out, - getMatchingOutputFormats(inputFormat)))) - return null; - - VideoFormat videoOut = (VideoFormat) out; - Dimension outSize = videoOut.getSize(); - - if (outSize == null) - { - Dimension inSize = ((VideoFormat) inputFormat).getSize(); - - outSize - = (inSize == null) - ? new Dimension( - Constants.VIDEO_WIDTH, - Constants.VIDEO_HEIGHT) - : inSize; - } - - outputFormat - = new VideoFormat( - videoOut.getEncoding(), - outSize, - outSize.width * outSize.height, - Format.byteArray, - videoOut.getFrameRate()); - - // Return the outputFormat which is actually set. - return outputFormat; - } - - /** - * Processes (packetize) a buffer. - * - * @param inBuffer input buffer - * @param outBuffer output buffer - * @return BUFFER_PROCESSED_OK if buffer has been successfully - * processed - */ - @Override - public int process(Buffer inBuffer, Buffer outBuffer) - { - int inLength = inBuffer.getLength(); - byte inData[] = (byte[])inBuffer.getData(); - int inOffset = inBuffer.getOffset(); - boolean pktAdded = false; - - if (videoPkts.size() > 0) - { - byte[] pktData = videoPkts.remove(0); - - // Send the packet. - outBuffer.setData(pktData); - outBuffer.setLength(pktData.length); - outBuffer.setOffset(0); - outBuffer.setTimeStamp(timeStamp); - outBuffer.setSequenceNumber(sequenceNumber++); - - // If there are other packets, send them as well. - if(videoPkts.size() > 0) - { - return (BUFFER_PROCESSED_OK | INPUT_BUFFER_NOT_CONSUMED); - } - else - { - // It's the last packet of the current frame so mark it. - outBuffer.setFlags( - outBuffer.getFlags() | Buffer.FLAG_RTP_MARKER); - - return BUFFER_PROCESSED_OK; - } - } - - if (isEOM(inBuffer)) - { - propagateEOM(outBuffer); - reset(); - return BUFFER_PROCESSED_OK; - } - - if (inBuffer.isDiscard()) - { - outBuffer.setDiscard(true); - reset(); - return BUFFER_PROCESSED_OK; - } - - Format inFormat = inBuffer.getFormat(); - - if ((inFormat != inputFormat) && !inFormat.matches(inputFormat)) - setInputFormat(inFormat); - - int endIndex = inOffset + inLength; - int beginIndex = findStartcode(inData, inOffset, endIndex); - - if (beginIndex < endIndex) - { - for (int nextBeginIndex; - beginIndex < endIndex; - beginIndex = nextBeginIndex + 3) - { - nextBeginIndex = findStartcode(inData, beginIndex + 3, - endIndex); - int length = nextBeginIndex - beginIndex; - - if (length > 0) - { - pktAdded - = packetize(inData, beginIndex, length) - || pktAdded; - beginIndex += length; - } - } - } - - timeStamp = inBuffer.getTimeStamp(); - - if(pktAdded) - { - return process(inBuffer, outBuffer); - } - else - { - /* first frame is not a synchronization point, discard ?*/ - return BUFFER_PROCESSED_FAILED; - } - } - - /** - * Packetizes H.263+ encoded data so that it becomes ready to be sent as the - * payload of RTP packets. - * - * @param data the bytes which contain the H.263+ encoded data to be - * packetized - * @param offset the offset of H.263+ encoded data to be packetized begins - * @param length the length of the H.263+ encoded data starting at offset - * @return true if at least one RTP packet payload has been - * packetized i.e. prepared for sending; otherwise, false - */ - private boolean packetize(byte[] data, int offset, int length) - { - boolean pktAdded = false; - - while(length > 0) - { - boolean isPsc = false; - int pos = 0; - int maxPayloadLength = MAX_PAYLOAD_SIZE; - byte pkt[] = null; - int payloadLength = 0; - - /* is we are at synchronization point (PSC, GSBC, EOS, EOSBS) */ - if(data.length > 3 && data[offset] == 0x00 && - data[offset + 1] == 0x00) - { - isPsc = true; - pos = 2; - } - else - { - maxPayloadLength -= 2; - } - - if(length > maxPayloadLength) - { - payloadLength = maxPayloadLength; - } - else - { - payloadLength = length; - } - - pkt = new byte[payloadLength + (isPsc ? 0 : 2)]; - - /* add H263+ payload header */ - /* no VRC and no extra picture header */ - pkt[0] = (byte)(isPsc ? 0x04 : 0x00); - pkt[1] = 0x00; - - System.arraycopy(data, offset + pos, pkt, 2, payloadLength - pos); - pktAdded = videoPkts.add(pkt) || pktAdded; - - offset += payloadLength; - length -= payloadLength; - } - - return pktAdded; - } - - /** - * Finds the index in byteStream at which a Picture Start code - * begins. - * - * @param byteStream the H.263+ encoded byte stream - * @param beginIndex the inclusive index in byteStream at which the - * search is to begin - * @param endIndex the exclusive index in byteStream at which the - * search is to end - * @return the index in byteStream at which the Picture Start code - * begins, otherwise, endIndex - */ - private static int findStartcode(byte[] byteStream, int beginIndex, - int endIndex) - { - for (; beginIndex < (endIndex - 3); beginIndex++) - if((byteStream[beginIndex] == 0) - && (byteStream[beginIndex + 1] == 0) - && ((byteStream[beginIndex + 2] & (byte)0x80) == -128)) - { - return beginIndex; - } - return endIndex; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/ConfigurationPanel.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/ConfigurationPanel.java index f8c4db197..fcc710647 100644 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/ConfigurationPanel.java +++ b/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/ConfigurationPanel.java @@ -12,11 +12,13 @@ import javax.swing.*; import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.neomedia.control.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.impl.neomedia.codec.video.h264.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.neomedia.control.*; +import org.jitsi.service.resources.*; + /** * Implements the H.264 configuration form (panel). * diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/DePacketizer.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/DePacketizer.java deleted file mode 100644 index de200011e..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/DePacketizer.java +++ /dev/null @@ -1,753 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.video.h264; - -import java.util.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.service.neomedia.control.*; -import net.java.sip.communicator.util.*; -import net.sf.fmj.media.*; - -/** - * Implements Codec to represent a depacketizer of H.264 RTP packets - * into NAL units. - * - * @author Lyubomir Marinov - * @author Damian Minkov - */ -public class DePacketizer - extends AbstractCodecExt -{ - - /** - * The Logger used by the DePacketizer class and its - * instances for logging output. - */ - private static final Logger logger = Logger.getLogger(DePacketizer.class); - - /** - * The bytes to prefix any NAL unit to be output by this - * DePacketizer and given to a H.264 decoder. Includes - * start_code_prefix_one_3bytes. According to "B.1 Byte stream NAL unit - * syntax and semantics" of "ITU-T Rec. H.264 Advanced video coding for - * generic audiovisual services", zero_byte "shall be present" when "the - * nal_unit_type within the nal_unit() is equal to 7 (sequence parameter - * set) or 8 (picture parameter set)" or "the byte stream NAL unit syntax - * structure contains the first NAL unit of an access unit in decoding - * order". - */ - private static final byte[] NAL_PREFIX = { 0, 0, 1 }; - - /** - * The indicator which determines whether incomplete NAL units are output - * from the H.264 DePacketizer to the decoder. It is advisable to - * output incomplete NAL units because the FFmpeg H.264 decoder is able to - * decode them. If false, incomplete NAL units will be discarded - * and, consequently, the video quality will be worse (e.g. if the last RTP - * packet of a fragmented NAL unit carrying a keyframe does not arrive from - * the network, the whole keyframe will be discarded and thus all NAL units - * upto the next keyframe will be useless). - */ - private static final boolean OUTPUT_INCOMPLETE_NAL_UNITS = true; - - /** - * The interval of time in milliseconds between two consecutive requests for - * a key frame from the remote peer associated with the - * {@link #keyFrameControl} of DePacketizer. - */ - private static final long TIME_BETWEEN_REQUEST_KEY_FRAME = 500; - - /** - * The interval of time in milliseconds from the time of the last received - * key frame to the time at which a key frame will be requested from the - * remote peer associated with the {@link #keyFrameControl} of - * DePacketizer. The value at the time of this writing is the - * default time between two consecutive key frames generated by - * {@link JNIDecoder} with an addition of a certain fraction of that time in - * the role of a leeway to prevent DePacketizer from requesting key - * frames from JNIEncoder in the scenario of perfect transmission. - */ - private static final long TIME_FROM_KEY_FRAME_TO_REQUEST_KEY_FRAME - = ((JNIEncoder.IFRAME_INTERVAL * 4) - / (JNIEncoder.DEFAULT_FRAME_RATE * 3)) - * 1000; - - /** - * The Unspecified nal_unit_type as defined by the ITU-T - * Recommendation for H.264. - */ - private static final int UNSPECIFIED_NAL_UNIT_TYPE = 0; - - /** - * The indicator which determines whether this DePacketizer has - * successfully processed an RTP packet with payload representing a - * "Fragmentation Unit (FU)" with its Start bit set and has not encountered - * one with its End bit set. - */ - private boolean fuaStartedAndNotEnded = false; - - /** - * The KeyFrameControl used by this DePacketizer to - * control its key frame-related logic. - */ - private KeyFrameControl keyFrameControl; - - /** - * The time stamp of the last received key frame. - */ - private long lastKeyFrameTime = -1; - - /** - * The time of the last request for a key frame from the remote peer - * associated with {@link #keyFrameControl} performed by this - * DePacketizer. - */ - private long lastRequestKeyFrameTime = -1; - - /** - * Keeps track of last (input) sequence number in order to avoid - * inconsistent data. - */ - private long lastSequenceNumber = -1; - - /** - * The nal_unit_type as defined by the ITU-T Recommendation for - * H.264 of the last NAL unit given to this DePacketizer for - * processing. In the case of processing a fragmentation unit, the value is - * equal to the nal_unit_type of the fragmented NAL unit. - */ - private int nal_unit_type; - - /** - * The size of the padding at the end of the output data of this - * DePacketizer expected by the H.264 decoder. - */ - private final int outputPaddingSize - = FFmpeg.FF_INPUT_BUFFER_PADDING_SIZE; - - /** - * The indicator which determines whether this DePacketizer is to - * request a key frame from the remote peer associated with - * {@link #keyFrameControl}. - */ - private boolean requestKeyFrame = false; - - /** - * The Thread which is to asynchronously request key frames from - * the remote peer associated with {@link #keyFrameControl} on behalf of - * this DePacketizer and in accord with {@link #requestKeyFrame}. - */ - private Thread requestKeyFrameThread; - - /** - * Initializes a new DePacketizer instance which is to depacketize - * H.264 RTP packets into NAL units. - */ - public DePacketizer() - { - super( - "H264 DePacketizer", - VideoFormat.class, - new VideoFormat[] { new VideoFormat(Constants.H264) }); - - List inputFormats = new ArrayList(); - - inputFormats.add(new VideoFormat(Constants.H264_RTP)); - /* - * Apart from the generic Constants.H264_RTP VideoFormat, add the - * possible respective ParameterizedVideoFormats because - * ParameterizedVideoFormat will not match every VideoFormat due to the - * fact that a missing packetization-mode format parameter is - * interpreted as it having a value of 0. - */ - Collections.addAll(inputFormats, Packetizer.SUPPORTED_OUTPUT_FORMATS); - this.inputFormats = inputFormats.toArray(new Format[inputFormats.size()]); - } - - /** - * Extracts a fragment of a NAL unit from a specific FU-A RTP packet - * payload. - * - * @param in the payload of the RTP packet from which a FU-A fragment of a - * NAL unit is to be extracted - * @param inOffset the offset in in at which the payload begins - * @param inLength the length of the payload in in beginning at - * inOffset - * @param outBuffer the Buffer which is to receive the extracted - * FU-A fragment of a NAL unit - * @return the flags such as BUFFER_PROCESSED_OK and - * OUTPUT_BUFFER_NOT_FILLED to be returned by - * {@link #process(Buffer, Buffer)} - */ - private int dePacketizeFUA( - byte[] in, int inOffset, int inLength, - Buffer outBuffer) - { - byte fu_indicator = in[inOffset]; - - inOffset++; - inLength--; - - byte fu_header = in[inOffset]; - - inOffset++; - inLength--; - - int nal_unit_type = fu_header & 0x1F; - - this.nal_unit_type = nal_unit_type; - - boolean start_bit = (fu_header & 0x80) != 0; - boolean end_bit = (fu_header & 0x40) != 0; - int outOffset = outBuffer.getOffset(); - int newOutLength = inLength; - int octet; - - if (start_bit) - { - /* - * The Start bit and End bit MUST NOT both be set in the same FU - * header. - */ - if (end_bit) - { - outBuffer.setDiscard(true); - return BUFFER_PROCESSED_OK; - } - - fuaStartedAndNotEnded = true; - - newOutLength += NAL_PREFIX.length + 1 /* octet */; - octet - = (fu_indicator & 0xE0) /* forbidden_zero_bit & NRI */ - | nal_unit_type; - } - else if (!fuaStartedAndNotEnded) - { - outBuffer.setDiscard(true); - return BUFFER_PROCESSED_OK; - } - else - { - int outLength = outBuffer.getLength(); - - outOffset += outLength; - newOutLength += outLength; - octet = 0; // Ignored later on. - } - - byte[] out - = validateByteArraySize( - outBuffer, - outBuffer.getOffset() + newOutLength + outputPaddingSize); - - if (start_bit) - { - // Copy in the NAL start sequence and the (reconstructed) octet. - System.arraycopy(NAL_PREFIX, 0, out, outOffset, NAL_PREFIX.length); - outOffset += NAL_PREFIX.length; - - out[outOffset] = (byte) (octet & 0xFF); - outOffset++; - } - System.arraycopy(in, inOffset, out, outOffset, inLength); - outOffset += inLength; - - padOutput(out, outOffset); - - outBuffer.setLength(newOutLength); - - if (end_bit) - { - fuaStartedAndNotEnded = false; - return BUFFER_PROCESSED_OK; - } - else - return OUTPUT_BUFFER_NOT_FILLED; - } - - /** - * Extract a single (complete) NAL unit from RTP payload. - * - * @param nal_unit_type unit type of NAL - * @param in the payload of the RTP packet - * @param inOffset the offset in in at which the payload begins - * @param inLength the length of the payload in in beginning at - * inOffset - * @param outBuffer the Buffer which is to receive the extracted - * NAL unit - * @return the flags such as BUFFER_PROCESSED_OK and - * OUTPUT_BUFFER_NOT_FILLED to be returned by - * {@link #process(Buffer, Buffer)} - */ - private int dePacketizeSingleNALUnitPacket( - int nal_unit_type, - byte[] in, int inOffset, int inLength, - Buffer outBuffer) - { - this.nal_unit_type = nal_unit_type; - - int outOffset = outBuffer.getOffset(); - int newOutLength = NAL_PREFIX.length + inLength; - byte[] out - = validateByteArraySize( - outBuffer, - outOffset + newOutLength + outputPaddingSize); - - System.arraycopy(NAL_PREFIX, 0, out, outOffset, NAL_PREFIX.length); - outOffset += NAL_PREFIX.length; - - System.arraycopy(in, inOffset, out, outOffset, inLength); - outOffset += inLength; - - padOutput(out, outOffset); - - outBuffer.setLength(newOutLength); - - return BUFFER_PROCESSED_OK; - } - - /** - * Close the Codec. - */ - protected synchronized void doClose() - { - // If requestKeyFrameThread is running, tell it to perish. - requestKeyFrameThread = null; - notifyAll(); - } - - /** - * Opens this Codec and acquires the resources that it needs to - * operate. A call to {@link PlugIn#open()} on this instance will result in - * a call to doOpen only if {@link AbstractCodec#opened} is - * false. All required input and/or output formats are assumed to - * have been set on this Codec before doOpen is called. - * - * @throws ResourceUnavailableException if any of the resources that this - * Codec needs to operate cannot be acquired - * @see AbstractCodecExt#doOpen() - */ - protected synchronized void doOpen() - throws ResourceUnavailableException - { - fuaStartedAndNotEnded = false; - lastKeyFrameTime = -1; - lastRequestKeyFrameTime = -1; - lastSequenceNumber = -1; - nal_unit_type = UNSPECIFIED_NAL_UNIT_TYPE; - requestKeyFrame = false; - requestKeyFrameThread = null; - } - - /** - * Processes (depacketizes) a buffer. - * - * @param inBuffer input buffer - * @param outBuffer output buffer - * @return BUFFER_PROCESSED_OK if buffer has been successfully - * processed - */ - @SuppressWarnings("fallthrough") - protected int doProcess(Buffer inBuffer, Buffer outBuffer) - { - /* - * We'll only be depacketizing, we'll not act as an H.264 parser. - * Consequently, we'll only care about the rules of - * packetizing/depacketizing. For example, we'll have to make sure that - * no packets are lost and no other packets are received when - * depacketizing FU-A Fragmentation Units (FUs). - */ - long sequenceNumber = inBuffer.getSequenceNumber(); - int ret; - boolean requestKeyFrame = (lastKeyFrameTime == -1); - - if ((lastSequenceNumber != -1) - && ((sequenceNumber - lastSequenceNumber) != 1)) - { - /* - * Even if (the new) sequenceNumber is less than lastSequenceNumber, - * we have to use it because the received sequence numbers may have - * reached their maximum value and wrapped around starting from - * their minimum value again. - */ - if (logger.isTraceEnabled()) - logger.trace( - "Dropped RTP packets upto sequenceNumber " - + lastSequenceNumber - + " and continuing with sequenceNumber " - + sequenceNumber); - - /* - * If a frame has been lost, then we may be in a need of a key - * frame. - */ - requestKeyFrame = true; - - ret = reset(outBuffer); - - if ((ret & OUTPUT_BUFFER_NOT_FILLED) == 0) - { - /* - * TODO Do we have to reset the nal_unit_type field of this - * DePacketizer to UNSPECIFIED_NAL_UNIT_TYPE here? If ret - * contains INPUT_BUFFER_NOT_CONSUMED, it seems safe to not - * reset it because the input Buffer will be returned for - * processing during the next call. - */ - - setRequestKeyFrame(requestKeyFrame); - - return ret; - } - } - - /* - * Ignore the RTP time stamp reported by JMF because it is not the - * actual RTP packet time stamp send by the remote peer but some locally - * calculated JMF value. - */ - - lastSequenceNumber = sequenceNumber; - - byte[] in = (byte[]) inBuffer.getData(); - int inOffset = inBuffer.getOffset(); - byte octet = in[inOffset]; - - /* - * NRI equal to the binary value 00 indicates that the content of the - * NAL unit is not used to reconstruct reference pictures for inter - * picture prediction. Such NAL units can be discarded without risking - * the integrity of the reference pictures. However, it is not the place - * of the DePacketizer to take the decision to discard them but of the - * H.264 decoder. - */ - - /* - * The nal_unit_type of the NAL unit given to this DePacketizer for - * processing. In the case of processing a fragmentation unit, the value - * is equal to the nal_unit_type of the fragmentation unit, not the - * fragmented NAL unit and is thus in contrast with the value of the - * nal_unit_type field of this DePacketizer. - */ - int nal_unit_type = octet & 0x1F; - - // Single NAL Unit Packet - if ((nal_unit_type >= 1) && (nal_unit_type <= 23)) - { - fuaStartedAndNotEnded = false; - ret - = dePacketizeSingleNALUnitPacket( - nal_unit_type, - in, inOffset, inBuffer.getLength(), - outBuffer); - } - else if (nal_unit_type == 28) // FU-A Fragmentation unit (FU) - { - ret = dePacketizeFUA(in, inOffset, inBuffer.getLength(), outBuffer); - if (outBuffer.isDiscard()) - fuaStartedAndNotEnded = false; - } - else - { - logger.warn( - "Dropping NAL unit of unsupported type " + nal_unit_type); - this.nal_unit_type = nal_unit_type; - - fuaStartedAndNotEnded = false; - outBuffer.setDiscard(true); - ret = BUFFER_PROCESSED_OK; - } - - outBuffer.setSequenceNumber(sequenceNumber); - - /* - * The RTP marker bit is set for the very last packet of the access unit - * indicated by the RTP time stamp to allow an efficient playout buffer - * handling. Consequently, we have to output it as well. - */ - if ((inBuffer.getFlags() & Buffer.FLAG_RTP_MARKER) != 0) - outBuffer.setFlags(outBuffer.getFlags() | Buffer.FLAG_RTP_MARKER); - - // Should we request a key frame. - switch (this.nal_unit_type) - { - case 5 /* Coded slice of an IDR picture */: - lastKeyFrameTime = System.currentTimeMillis(); - // Do fall through to prevent the request of a key frame. - - /* - * While it seems natural to not request a key frame in the presence of - * 5, 7 and 8 often seem to be followed by 5 so do not request a key - * frame if either 7 or 8 is present. - */ - case 7 /* Sequence parameter set */: - case 8 /* Picture parameter set */: - requestKeyFrame = false; - break; - default: - break; - } - setRequestKeyFrame(requestKeyFrame); - - return ret; - } - - /** - * Appends {@link #outputPaddingSize} number of bytes to out - * beginning at index outOffset. The specified out is - * expected to be large enough to accommodate the mentioned number of bytes. - * - * @param out the buffer in which outputPaddingSize number of bytes - * are to be written - * @param outOffset the index in outOffset at which the writing of - * outputPaddingSize number of bytes is to begin - */ - private void padOutput(byte[] out, int outOffset) - { - Arrays.fill(out, outOffset, outOffset + outputPaddingSize, (byte) 0); - } - - /** - * Requests a key frame from the remote peer associated with this - * DePacketizer using the logic of DePacketizer. - * - * @param urgent true if the caller has determined that the need - * for a key frame is urgent and should not obey all constraints with - * respect to time between two subsequent requests for key frames - * @return true if a key frame was indeed requested in response to - * the call; otherwise, false - */ - public synchronized boolean requestKeyFrame(boolean urgent) - { - lastKeyFrameTime = -1; - setRequestKeyFrame(true); - return true; - } - - /** - * Resets the states of this DePacketizer and a specific output - * Buffer so that they are ready to have this DePacketizer - * process input RTP payloads. If the specified output Buffer - * contains an incomplete NAL unit, its forbidden_zero_bit will be turned on - * and the NAL unit in question will be output by this - * DePacketizer. - * - * @param outBuffer the output Buffer to be reset - * @return the flags such as BUFFER_PROCESSED_OK and - * OUTPUT_BUFFER_NOT_FILLED to be returned by - * {@link #process(Buffer, Buffer)} - */ - private int reset(Buffer outBuffer) - { - /* - * We need the octet at the very least. Additionally, it does not make - * sense to output a NAL unit with zero payload because such NAL units - * are only given meaning for the purposes of the network and not the - * H.264 decoder. - */ - if (OUTPUT_INCOMPLETE_NAL_UNITS - && fuaStartedAndNotEnded - && (outBuffer.getLength() >= (NAL_PREFIX.length + 1 + 1))) - { - Object outData = outBuffer.getData(); - - if (outData instanceof byte[]) - { - byte[] out = (byte[]) outData; - int octetIndex = outBuffer.getOffset() + NAL_PREFIX.length; - - out[octetIndex] |= 0x80; // Turn on the forbidden_zero_bit. - fuaStartedAndNotEnded = false; - return (BUFFER_PROCESSED_OK | INPUT_BUFFER_NOT_CONSUMED); - } - } - - fuaStartedAndNotEnded = false; - outBuffer.setLength(0); - return OUTPUT_BUFFER_NOT_FILLED; - } - - /** - * Requests key frames from the remote peer associated with - * {@link #keyFrameControl} in {@link #requestKeyFrameThread}. - */ - private void runInRequestKeyFrameThread() - { - while (true) - { - synchronized (this) - { - if (requestKeyFrameThread != Thread.currentThread()) - break; - - long now = System.currentTimeMillis(); - long timeout; - - if (requestKeyFrame) - { - /* - * If we have received at least one key frame, we may - * receive a new one later. So allow a certain amount of - * time for the new key frame to arrive without DePacketizer - * requesting it. - */ - long nextKeyFrameTime - = lastKeyFrameTime - + TIME_FROM_KEY_FRAME_TO_REQUEST_KEY_FRAME; - - if (now >= nextKeyFrameTime) - { - /* - * In order to not have the requests for key frames - * overwhelm the remote peer, make sure two consecutive - * requests are separated by a certain amount of time. - */ - long nextRequestKeyFrameTime - = lastRequestKeyFrameTime - + TIME_BETWEEN_REQUEST_KEY_FRAME; - - if (now >= nextRequestKeyFrameTime) - { - // Request a key frame from the remote peer now. - timeout = -1; - } - else - { - /* - * Too little time has passed from our last attempt - * to request a key frame from the remote peer. If - * we do not wait, we risk intruding. - */ - timeout = nextRequestKeyFrameTime - now; - } - } - else - { - /* - * Too little time has passed from the last receipt of a - * key frame to make us think that the remote peer will - * not send a key frame without us requesting it. - */ - timeout = nextKeyFrameTime - now; - } - } - else - { - /* - * This DePacketizer has not expressed its desire to request - * a key frame from the remote peer so we will have to wait - * until it expresses the desire in question. - */ - timeout = 0; - } - - if (timeout >= 0) - { - try - { - wait(timeout); - } - catch (InterruptedException ie) - { - } - continue; - } - } - - KeyFrameControl keyFrameControl = this.keyFrameControl; - - if (keyFrameControl != null) - { - List keyFrameRequesters - = keyFrameControl.getKeyFrameRequesters(); - - if (keyFrameRequesters != null) - { - for (KeyFrameControl.KeyFrameRequester keyFrameRequester - : keyFrameRequesters) - { - try - { - if (keyFrameRequester.requestKeyFrame()) - break; - } - catch (Exception e) - { - /* - * A KeyFrameRequester has malfunctioned, do not let - * it interfere with the others. - */ - } - } - } - } - lastRequestKeyFrameTime = System.currentTimeMillis(); - } - } - - /** - * Sets the KeyFrameControl to be used by this - * DePacketizer as a means of control over its key frame-related - * logic. - * - * @param keyFrameControl the KeyFrameControl to be used by this - * DePacketizer as a means of control over its key frame-related - * logic - */ - public void setKeyFrameControl(KeyFrameControl keyFrameControl) - { - this.keyFrameControl = keyFrameControl; - } - - /** - * Sets the indicator which determines whether this DePacketizer is - * to request a key frame from the remote peer associated with - * {@link #keyFrameControl}. - * - * @param requestKeyFrame true if this DePacketizer is to - * request a key frame from the remote peer associated with - * {@link #keyFrameControl} - */ - private synchronized void setRequestKeyFrame(boolean requestKeyFrame) - { - if (this.requestKeyFrame != requestKeyFrame) - { - this.requestKeyFrame = requestKeyFrame; - - if ((this.requestKeyFrame) && (requestKeyFrameThread == null)) - { - requestKeyFrameThread - = new Thread() - { - public void run() - { - try - { - runInRequestKeyFrameThread(); - } - finally - { - synchronized (DePacketizer.this) - { - if (requestKeyFrameThread - == Thread.currentThread()) - requestKeyFrameThread = null; - } - } - } - }; - requestKeyFrameThread.start(); - } - notifyAll(); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/JNIDecoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/JNIDecoder.java deleted file mode 100644 index 24fb471f2..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/JNIDecoder.java +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.video.h264; - -import java.awt.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.codec.video.*; -import net.java.sip.communicator.service.neomedia.control.*; -import net.sf.fmj.media.*; - -/** - * Decodes H.264 NAL units and returns the resulting frames as FFmpeg - * AVFrames (i.e. in YUV format). - * - * @author Damian Minkov - * @author Lyubomir Marinov - * @author Sebastien Vincent - */ -public class JNIDecoder - extends AbstractCodec -{ - /** - * Plugin name. - */ - private static final String PLUGIN_NAME = "H.264 Decoder"; - - /** - * The default output VideoFormat. - */ - private static final VideoFormat[] DEFAULT_OUTPUT_FORMATS - = new VideoFormat[] { new AVFrameFormat() }; - - /** - * The codec context native pointer we will use. - */ - private long avctx; - - /** - * The decoded data is stored in avpicture in native ffmpeg format (YUV). - */ - private long avframe; - - /** - * If decoder has got a picture. - */ - private final boolean[] got_picture = new boolean[1]; - - private boolean gotPictureAtLeastOnce; - - /** - * The last known height of {@link #avctx} i.e. the video output by this - * JNIDecoder. Used to detect changes in the output size. - */ - private int height; - - /** - * The KeyFrameControl used by this JNIDecoder to - * control its key frame-related logic. - */ - private KeyFrameControl keyFrameControl; - - /** - * Array of output VideoFormats. - */ - private final VideoFormat[] outputFormats; - - /** - * The last known width of {@link #avctx} i.e. the video output by this - * JNIDecoder. Used to detect changes in the output size. - */ - private int width; - - /** - * Initializes a new JNIDecoder instance which is to decode H.264 - * NAL units into frames in YUV format. - */ - public JNIDecoder() - { - inputFormats - = new VideoFormat[] { new VideoFormat(Constants.H264) }; - outputFormats - = new VideoFormat[] - { - new AVFrameFormat( - new Dimension( - Constants.VIDEO_WIDTH, - Constants.VIDEO_HEIGHT), - ensureFrameRate(Format.NOT_SPECIFIED), - FFmpeg.PIX_FMT_YUV420P, - Format.NOT_SPECIFIED) - }; - - Dimension outputSize = outputFormats[0].getSize(); - - width = outputSize.width; - height = outputSize.height; - } - - /** - * Check Format. - * - * @param format Format to check - * @return true if Format is H264_RTP - */ - public boolean checkFormat(Format format) - { - return format.getEncoding().equals(Constants.H264_RTP); - } - - /** - * Close Codec. - */ - @Override - public synchronized void close() - { - if (opened) - { - opened = false; - super.close(); - - FFmpeg.avcodec_close(avctx); - FFmpeg.av_free(avctx); - avctx = 0; - - FFmpeg.av_free(avframe); - avframe = 0; - - gotPictureAtLeastOnce = false; - } - } - - /** - * Ensure frame rate. - * - * @param frameRate frame rate - * @return frame rate - */ - private float ensureFrameRate(float frameRate) - { - return frameRate; - } - - /** - * Get matching outputs for a specified input Format. - * - * @param in input Format - * @return array of matching outputs or null if there are no matching - * outputs. - */ - protected Format[] getMatchingOutputFormats(Format in) - { - VideoFormat ivf = (VideoFormat) in; - Dimension inSize = ivf.getSize(); - Dimension outSize; - - // return the default size/currently decoder and encoder - // set to transmit/receive at this size - if (inSize == null) - { - VideoFormat ovf = outputFormats[0]; - - if (ovf == null) - return null; - else - outSize = ovf.getSize(); - } - else - outSize = inSize; // Output in same size as input. - - return - new Format[] - { - new AVFrameFormat( - outSize, - ensureFrameRate(ivf.getFrameRate()), - FFmpeg.PIX_FMT_YUV420P, - Format.NOT_SPECIFIED) - }; - } - - /** - * Get plugin name. - * - * @return "H.264 Decoder" - */ - @Override - public String getName() - { - return PLUGIN_NAME; - } - - /** - * Get all supported output Formats. - * - * @param inputFormat input Format to determine corresponding - * output Format/tt>s - * @return an array of supported output Formats - */ - public Format[] getSupportedOutputFormats(Format inputFormat) - { - Format[] supportedOutputFormats; - - if (inputFormat == null) - supportedOutputFormats = DEFAULT_OUTPUT_FORMATS; - else - { - // mismatch input format - if (!(inputFormat instanceof VideoFormat) - || (AbstractCodecExt.matches(inputFormat, inputFormats) - == null)) - supportedOutputFormats = new Format[0]; - else - { - // match input format - supportedOutputFormats = getMatchingOutputFormats(inputFormat); - } - } - return supportedOutputFormats; - } - - /** - * Inits the codec instances. - * - * @throws ResourceUnavailableException if codec initialization failed - */ - @Override - public synchronized void open() - throws ResourceUnavailableException - { - if (opened) - return; - - long avcodec = FFmpeg.avcodec_find_decoder(FFmpeg.CODEC_ID_H264); - - avctx = FFmpeg.avcodec_alloc_context(); - FFmpeg.avcodeccontext_set_workaround_bugs(avctx, - FFmpeg.FF_BUG_AUTODETECT); - - /* allow to pass incomplete frame to decoder */ - FFmpeg.avcodeccontext_add_flags2(avctx, - FFmpeg.CODEC_FLAG2_CHUNKS); - - if (FFmpeg.avcodec_open(avctx, avcodec) < 0) - throw new RuntimeException("Could not open codec CODEC_ID_H264"); - - avframe = FFmpeg.avcodec_alloc_frame(); - - gotPictureAtLeastOnce = false; - - opened = true; - super.open(); - } - - /** - * Decodes H.264 media data read from a specific input Buffer into - * a specific output Buffer. - * - * @param inBuffer input Buffer - * @param outBuffer output Buffer - * @return BUFFER_PROCESSED_OK if inBuffer has been - * successfully processed - */ - public synchronized int process(Buffer inBuffer, Buffer outBuffer) - { - if (!checkInputBuffer(inBuffer)) - return BUFFER_PROCESSED_FAILED; - if (isEOM(inBuffer) || !opened) - { - propagateEOM(outBuffer); - return BUFFER_PROCESSED_OK; - } - if (inBuffer.isDiscard()) - { - outBuffer.setDiscard(true); - return BUFFER_PROCESSED_OK; - } - - // Ask FFmpeg to decode. - got_picture[0] = false; - // TODO Take into account the offset of inputBuffer. - FFmpeg.avcodec_decode_video( - avctx, - avframe, - got_picture, - (byte[]) inBuffer.getData(), inBuffer.getLength()); - - if (!got_picture[0]) - { - if ((inBuffer.getFlags() & Buffer.FLAG_RTP_MARKER) != 0) - { - if (keyFrameControl != null) - keyFrameControl.requestKeyFrame(!gotPictureAtLeastOnce); - } - - outBuffer.setDiscard(true); - return BUFFER_PROCESSED_OK; - } - gotPictureAtLeastOnce = true; - - // format - int width = FFmpeg.avcodeccontext_get_width(avctx); - int height = FFmpeg.avcodeccontext_get_height(avctx); - - if ((width > 0) - && (height > 0) - && ((this.width != width) || (this.height != height))) - { - this.width = width; - this.height = height; - - // Output in same size and frame rate as input. - Dimension outSize = new Dimension(this.width, this.height); - VideoFormat inFormat = (VideoFormat) inBuffer.getFormat(); - float outFrameRate = ensureFrameRate(inFormat.getFrameRate()); - - outputFormat - = new AVFrameFormat( - outSize, - outFrameRate, - FFmpeg.PIX_FMT_YUV420P, - Format.NOT_SPECIFIED); - } - outBuffer.setFormat(outputFormat); - - // data - Object out = outBuffer.getData(); - - if (!(out instanceof AVFrame) || (((AVFrame) out).getPtr() != avframe)) - outBuffer.setData(new AVFrame(avframe)); - - // timeStamp - long pts = FFmpeg.AV_NOPTS_VALUE; // TODO avframe_get_pts(avframe); - - if (pts == FFmpeg.AV_NOPTS_VALUE) - outBuffer.setTimeStamp(Buffer.TIME_UNKNOWN); - else - { - outBuffer.setTimeStamp(pts); - - int outFlags = outBuffer.getFlags(); - - outFlags |= Buffer.FLAG_RELATIVE_TIME; - outFlags &= ~(Buffer.FLAG_RTP_TIME | Buffer.FLAG_SYSTEM_TIME); - outBuffer.setFlags(outFlags); - } - - return BUFFER_PROCESSED_OK; - } - - /** - * Sets the Format of the media data to be input for processing in - * this Codec. - * - * @param format the Format of the media data to be input for - * processing in this Codec - * @return the Format of the media data to be input for processing - * in this Codec if format is compatible with this - * Codec; otherwise, null - */ - @Override - public Format setInputFormat(Format format) - { - Format setFormat = super.setInputFormat(format); - - if (setFormat != null) - reset(); - return setFormat; - } - - /** - * Sets the KeyFrameControl to be used by this - * DePacketizer as a means of control over its key frame-related - * logic. - * - * @param keyFrameControl the KeyFrameControl to be used by this - * DePacketizer as a means of control over its key frame-related - * logic - */ - public void setKeyFrameControl(KeyFrameControl keyFrameControl) - { - this.keyFrameControl = keyFrameControl; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/JNIEncoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/JNIEncoder.java deleted file mode 100644 index 4599207c6..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/JNIEncoder.java +++ /dev/null @@ -1,794 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.video.h264; - -import java.awt.*; -import java.util.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.format.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.neomedia.control.*; -import net.java.sip.communicator.service.neomedia.event.*; -import net.java.sip.communicator.util.*; -import net.sf.fmj.media.*; - -/** - * Implements a H.264 encoder. - * - * @author Damian Minkov - * @author Lyubomir Marinov - * @author Sebastien Vincent - */ -public class JNIEncoder - extends AbstractCodec - implements RTCPFeedbackListener -{ - /** - * The logger used by the JNIEncoder class and its instances for - * logging output. - */ - private static final Logger logger = Logger.getLogger(JNIEncoder.class); - - /** - * The name of the baseline H.264 (encoding) profile. - */ - public static final String BASELINE_PROFILE = "baseline"; - - /** - * The frame rate to be assumed by JNIEncoder instance in the - * absence of any other frame rate indication. - */ - static final int DEFAULT_FRAME_RATE = 15; - - /** - * The name of the ConfigurationService property which specifies - * the H.264 (encoding) profile to be used in the absence of negotiation. - * Though it seems that RFC 3984 "RTP Payload Format for H.264 Video" - * specifies the baseline profile as the default, we have till the time of - * this writing defaulted to the main profile and we do not currently want - * to change from the main to the base profile unless we really have to. - */ - public static final String DEFAULT_PROFILE_PNAME - = "net.java.sip.communicator.impl.neomedia.codec.video.h264." - + "defaultProfile"; - - /** - * Key frame every 150 frames. - */ - static final int IFRAME_INTERVAL = 150; - - /** - * The name of the main H.264 (encoding) profile. - */ - public static final String MAIN_PROFILE = "main"; - - /** - * The default value of the {@link #DEFAULT_PROFILE_PNAME} - * ConfigurationService property. - */ - public static final String DEFAULT_DEFAULT_PROFILE = MAIN_PROFILE; - - /** - * The name of the format parameter which specifies the packetization mode - * of H.264 RTP payload. - */ - public static final String PACKETIZATION_MODE_FMTP = "packetization-mode"; - - /** - * Minimum interval between two PLI request processing (in milliseconds). - */ - private static final long PLI_INTERVAL = 3000; - - /** - * Name of the code. - */ - private static final String PLUGIN_NAME = "H.264 Encoder"; - - /** - * The list of Formats supported by JNIEncoder instances - * as output. - */ - static final Format[] SUPPORTED_OUTPUT_FORMATS - = { - new ParameterizedVideoFormat( - Constants.H264, - PACKETIZATION_MODE_FMTP, "0"), - new ParameterizedVideoFormat( - Constants.H264, - PACKETIZATION_MODE_FMTP, "1") - }; - - /** - * The codec we will use. - */ - private long avctx; - - /** - * The encoded data is stored in avpicture. - */ - private long avframe; - - /** - * We use this buffer to supply data to encoder. - */ - private byte[] encFrameBuffer; - - /** - * The supplied data length. - */ - private int encFrameLen; - - /** - * Force encoder to send a key frame. - * First frame have to be a keyframe. - */ - private boolean forceKeyFrame = true; - - /** - * Next interval for an automatic keyframe. - */ - private int framesSinceLastIFrame = IFRAME_INTERVAL + 1; - - /** - * The KeyFrameControl used by this JNIEncoder to - * control its key frame-related logic. - */ - private KeyFrameControl keyFrameControl; - - private KeyFrameControl.KeyFrameRequestee keyFrameRequestee; - - /** - * The time in milliseconds of the last request for a key frame from the - * remote peer to this local peer. - */ - private long lastKeyFrameRequestTime = System.currentTimeMillis(); - - /** - * The packetization mode to be used for the H.264 RTP payload output by - * this JNIEncoder and the associated packetizer. RFC 3984 "RTP - * Payload Format for H.264 Video" says that "[w]hen the value of - * packetization-mode is equal to 0 or packetization-mode is not present, - * the single NAL mode, as defined in section 6.2 of RFC 3984, MUST be - * used." - */ - private String packetizationMode; - - /** - * The raw frame buffer. - */ - private long rawFrameBuffer; - - /** - * Peer that receive stream from latest ffmpeg/x264 aware peer does not - * manage to decode the first keyframe and must wait for the next periodic - * intra refresh to display the video to the user. - * - * Temporary solution for this problem: send the two first frames as - * keyframes to display video stream. - */ - private boolean secondKeyFrame = true; - - /** - * Additional codec settings. - */ - private Map additionalSettings = null; - - /** - * Initializes a new JNIEncoder instance. - */ - public JNIEncoder() - { - inputFormats - = new Format[] - { - new YUVFormat( - null, - Format.NOT_SPECIFIED, - Format.byteArray, - DEFAULT_FRAME_RATE, - YUVFormat.YUV_420, - Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, - 0, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED) - }; - - inputFormat = null; - outputFormat = null; - } - - /** - * Closes this Codec. - */ - @Override - public synchronized void close() - { - if (opened) - { - opened = false; - super.close(); - - FFmpeg.avcodec_close(avctx); - FFmpeg.av_free(avctx); - avctx = 0; - - FFmpeg.av_free(avframe); - avframe = 0; - FFmpeg.av_free(rawFrameBuffer); - rawFrameBuffer = 0; - - encFrameBuffer = null; - - if (keyFrameRequestee != null) - { - if (keyFrameControl != null) - keyFrameControl.removeKeyFrameRequestee(keyFrameRequestee); - keyFrameRequestee = null; - } - } - } - - /** - * Event fired when RTCP feedback message is received. - * - * @param event RTCPFeedbackEvent - */ - public void feedbackReceived(RTCPFeedbackEvent event) - { - /* - * If RTCP message is a Picture Loss Indication (PLI) or a - * Full Intra-frame Request (FIR) the encoder will force the next frame - * to be a keyframe. - */ - if (event.getPayloadType() == RTCPFeedbackEvent.PT_PS) - { - switch (event.getFeedbackMessageType()) - { - case RTCPFeedbackEvent.FMT_PLI: - case RTCPFeedbackEvent.FMT_FIR: - keyFrameRequest(); - break; - default: - break; - } - } - } - - /** - * Gets the matching output formats for a specific format. - * - * @param in input format - * @return array for formats matching input format - */ - private Format[] getMatchingOutputFormats(Format in) - { - VideoFormat videoIn = (VideoFormat) in; - - String[] packetizationModes - = (this.packetizationMode == null) - ? new String[] { "0", "1" } - : new String[] { this.packetizationMode }; - Format[] matchingOutputFormats = new Format[packetizationModes.length]; - Dimension size = videoIn.getSize(); - float frameRate = videoIn.getFrameRate(); - - for (int index = packetizationModes.length - 1; index >= 0; index--) - { - matchingOutputFormats[index] - = new ParameterizedVideoFormat( - Constants.H264, - size, - Format.NOT_SPECIFIED, - Format.byteArray, - frameRate, - ParameterizedVideoFormat.toMap( - PACKETIZATION_MODE_FMTP, - packetizationModes[index])); - } - return matchingOutputFormats; - } - - /** - * Gets the name of this Codec. - * - * @return codec name - */ - @Override - public String getName() - { - return PLUGIN_NAME; - } - - /** - * Returns the list of formats supported at the output. - * - * @param in input Format to determine corresponding output - * Formats - * @return array of formats supported at output - */ - public Format[] getSupportedOutputFormats(Format in) - { - Format[] supportedOutputFormats; - - // null input format - if (in == null) - supportedOutputFormats = SUPPORTED_OUTPUT_FORMATS; - // mismatch input format - else if (!(in instanceof VideoFormat) - || (null == AbstractCodecExt.matches(in, inputFormats))) - supportedOutputFormats = new Format[0]; - else - supportedOutputFormats = getMatchingOutputFormats(in); - return supportedOutputFormats; - } - - /** - * Notifies this JNIEncoder that the remote peer has requested a - * key frame from this local peer. - * - * @return true if this JNIEncoder has honored the request - * for a key frame; otherwise, false - */ - private boolean keyFrameRequest() - { - if (System.currentTimeMillis() - > (lastKeyFrameRequestTime + PLI_INTERVAL)) - { - lastKeyFrameRequestTime = System.currentTimeMillis(); - forceKeyFrame = true; - } - return true; - } - - /** - * Opens this Codec. - */ - @Override - public synchronized void open() - throws ResourceUnavailableException - { - if (opened) - return; - - if (inputFormat == null) - throw new ResourceUnavailableException("No input format selected"); - if (outputFormat == null) - throw new ResourceUnavailableException("No output format selected"); - - VideoFormat outputVideoFormat = (VideoFormat) outputFormat; - Dimension size = outputVideoFormat.getSize(); - int width = size.width; - int height = size.height; - boolean useIntraRefresh = true; - boolean useCustomProfile = false; - String customProfile = null; - - if(additionalSettings != null) - { - for(Map.Entry entry : additionalSettings.entrySet()) - { - String key = entry.getKey(); - String value = entry.getValue(); - - if(key.equals("h264.intrarefresh") && value.equals("false")) - { - useIntraRefresh = false; - } - else if(key.equals("h264.profile")) - { - if(value.equals(MAIN_PROFILE) || - value.equals(BASELINE_PROFILE)) - { - useCustomProfile = true; - customProfile = value; - } - } - } - } - - long avcodec = FFmpeg.avcodec_find_encoder(FFmpeg.CODEC_ID_H264); - - avctx = FFmpeg.avcodec_alloc_context(); - - FFmpeg.avcodeccontext_set_pix_fmt(avctx, FFmpeg.PIX_FMT_YUV420P); - FFmpeg.avcodeccontext_set_size(avctx, width, height); - - FFmpeg.avcodeccontext_set_qcompress(avctx, 0.6f); - - int bitRate = 128000; - int frameRate = (int) outputVideoFormat.getFrameRate(); - - if (frameRate == Format.NOT_SPECIFIED) - frameRate = DEFAULT_FRAME_RATE; - - // average bit rate - FFmpeg.avcodeccontext_set_bit_rate(avctx, bitRate); - // so to be 1 in x264 - FFmpeg.avcodeccontext_set_bit_rate_tolerance(avctx, (bitRate / - frameRate)); - FFmpeg.avcodeccontext_set_rc_max_rate(avctx, bitRate); - FFmpeg.avcodeccontext_set_sample_aspect_ratio(avctx, 0, 0); - FFmpeg.avcodeccontext_set_thread_count(avctx, 1); - - // time_base should be 1 / frame rate - FFmpeg.avcodeccontext_set_time_base(avctx, 1, frameRate); - FFmpeg.avcodeccontext_set_ticks_per_frame(avctx, 2); - FFmpeg.avcodeccontext_set_quantizer(avctx, 30, 31, 4); - - // avctx.chromaoffset = -2; - - FFmpeg.avcodeccontext_add_partitions(avctx, 0x111); - // X264_PART_I4X4 0x001 - // X264_PART_P8X8 0x010 - // X264_PART_B8X8 0x100 - - FFmpeg.avcodeccontext_set_mb_decision(avctx, - FFmpeg.FF_MB_DECISION_SIMPLE); - - FFmpeg.avcodeccontext_set_rc_eq(avctx, "blurCplx^(1-qComp)"); - - FFmpeg.avcodeccontext_add_flags(avctx, - FFmpeg.CODEC_FLAG_LOOP_FILTER); - if(useIntraRefresh) - FFmpeg.avcodeccontext_add_flags2(avctx, - FFmpeg.CODEC_FLAG2_INTRA_REFRESH); - FFmpeg.avcodeccontext_set_me_method(avctx, 7); - FFmpeg.avcodeccontext_set_me_subpel_quality(avctx, 2); - FFmpeg.avcodeccontext_set_me_range(avctx, 16); - FFmpeg.avcodeccontext_set_me_cmp(avctx, FFmpeg.FF_CMP_CHROMA); - FFmpeg.avcodeccontext_set_scenechange_threshold(avctx, 40); - // Constant quality mode (also known as constant ratefactor) - FFmpeg.avcodeccontext_set_crf(avctx, 0); - FFmpeg.avcodeccontext_set_rc_buffer_size(avctx, 10); - FFmpeg.avcodeccontext_set_gop_size(avctx, IFRAME_INTERVAL); - FFmpeg.avcodeccontext_set_i_quant_factor(avctx, 1f / 1.4f); - - FFmpeg.avcodeccontext_set_refs(avctx, 1); - //FFmpeg.avcodeccontext_set_trellis(avctx, 2); - - FFmpeg.avcodeccontext_set_keyint_min(avctx, 0); - - if ((null == packetizationMode) || "0".equals(packetizationMode)) - { - FFmpeg.avcodeccontext_set_rtp_payload_size(avctx, - Packetizer.MAX_PAYLOAD_SIZE); - } - - /* - * XXX We do not currently negotiate the profile so, regardless of the - * many AVCodecContext properties we have set above, force the default - * profile configuration. - */ - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - String profile - = (cfg == null) - ? null - : cfg.getString(DEFAULT_PROFILE_PNAME, DEFAULT_DEFAULT_PROFILE); - - if(useCustomProfile) - { - profile = customProfile; - } - - try - { - FFmpeg.avcodeccontext_set_profile(avctx, - BASELINE_PROFILE.equalsIgnoreCase(profile) - ? FFmpeg.FF_PROFILE_H264_BASELINE - : FFmpeg.FF_PROFILE_H264_MAIN); - } - catch (UnsatisfiedLinkError ule) - { - logger.warn("The FFmpeg JNI library is out-of-date."); - } - - if (FFmpeg.avcodec_open(avctx, avcodec) < 0) - { - throw - new ResourceUnavailableException( - "Could not open codec. (size= " - + width + "x" + height - + ")"); - } - - encFrameLen = (width * height * 3) / 2; - - rawFrameBuffer = FFmpeg.av_malloc(encFrameLen); - avframe = FFmpeg.avcodec_alloc_frame(); - - int sizeInBytes = width * height; - - FFmpeg.avframe_set_data( - avframe, - rawFrameBuffer, - sizeInBytes, - sizeInBytes / 4); - FFmpeg.avframe_set_linesize(avframe, width, width / 2, width / 2); - - encFrameBuffer = new byte[encFrameLen]; - - /* - * Implement the ability to have the remote peer request key frames from - * this local peer. - */ - if (keyFrameRequestee == null) - { - keyFrameRequestee = new KeyFrameControl.KeyFrameRequestee() - { - public boolean keyFrameRequest() - { - return JNIEncoder.this.keyFrameRequest(); - } - }; - } - if (keyFrameControl != null) - keyFrameControl.addKeyFrameRequestee(-1, keyFrameRequestee); - - opened = true; - super.open(); - } - - /** - * Processes/encodes a buffer. - * - * @param inBuffer input buffer - * @param outBuffer output buffer - * @return BUFFER_PROCESSED_OK if buffer has been successfully - * processed - */ - public synchronized int process(Buffer inBuffer, Buffer outBuffer) - { - if (isEOM(inBuffer)) - { - propagateEOM(outBuffer); - reset(); - return BUFFER_PROCESSED_OK; - } - if (inBuffer.isDiscard()) - { - outBuffer.setDiscard(true); - reset(); - return BUFFER_PROCESSED_OK; - } - - Format inFormat = inBuffer.getFormat(); - - if ((inFormat != inputFormat) && !inFormat.matches(inputFormat)) - setInputFormat(inFormat); - - if (inBuffer.getLength() < 10) - { - outBuffer.setDiscard(true); - reset(); - return BUFFER_PROCESSED_OK; - } - - // copy data to avframe - FFmpeg.memcpy( - rawFrameBuffer, - (byte[]) inBuffer.getData(), inBuffer.getOffset(), - encFrameLen); - - if (/* framesSinceLastIFrame >= IFRAME_INTERVAL || */ forceKeyFrame) - { - FFmpeg.avframe_set_key_frame(avframe, true); - framesSinceLastIFrame = 0; - - /* send keyframe for the first two frames */ - if(secondKeyFrame) - { - secondKeyFrame = false; - forceKeyFrame = true; - } - else - { - forceKeyFrame = false; - } - } - else - { - framesSinceLastIFrame++; - FFmpeg.avframe_set_key_frame(avframe, false); - } - - // encode data - int encLen - = FFmpeg.avcodec_encode_video( - avctx, - encFrameBuffer, encFrameLen, - avframe); - - /* - * Do not always allocate a new data array for outBuffer, try to reuse - * the existing one if it is suitable. - */ - Object outData = outBuffer.getData(); - byte[] out; - - if (outData instanceof byte[]) - { - out = (byte[]) outData; - if (out.length < encLen) - out = null; - } - else - out = null; - if (out == null) - out = new byte[encLen]; - - System.arraycopy(encFrameBuffer, 0, out, 0, encLen); - - outBuffer.setData(out); - outBuffer.setLength(encLen); - outBuffer.setOffset(0); - outBuffer.setTimeStamp(inBuffer.getTimeStamp()); - return BUFFER_PROCESSED_OK; - } - - /** - * Sets the input format. - * - * @param in format to set - * @return format - */ - @Override - public Format setInputFormat(Format in) - { - // mismatch input format - if (!(in instanceof VideoFormat) - || (null == AbstractCodecExt.matches(in, inputFormats))) - return null; - - YUVFormat yuv = (YUVFormat) in; - - if (yuv.getOffsetU() > yuv.getOffsetV()) - return null; - - Dimension size = yuv.getSize(); - - if (size == null) - size = new Dimension(Constants.VIDEO_WIDTH, Constants.VIDEO_HEIGHT); - - int strideY = size.width; - int strideUV = strideY / 2; - int offsetU = strideY * size.height; - int offsetV = offsetU + strideUV * size.height / 2; - - int yuvMaxDataLength = (strideY + strideUV) * size.height; - - inputFormat - = new YUVFormat( - size, - yuvMaxDataLength + FFmpeg.FF_INPUT_BUFFER_PADDING_SIZE, - Format.byteArray, - yuv.getFrameRate(), - YUVFormat.YUV_420, - strideY, strideUV, - 0, offsetU, offsetV); - - // Return the selected inputFormat - return inputFormat; - } - - /** - * Sets the KeyFrameControl to be used by this - * JNIEncoder as a means of control over its key frame-related - * logic. - * - * @param keyFrameControl the KeyFrameControl to be used by this - * JNIEncoder as a means of control over its key frame-related - * logic - */ - public void setKeyFrameControl(KeyFrameControl keyFrameControl) - { - if (this.keyFrameControl != keyFrameControl) - { - if ((this.keyFrameControl != null) && (keyFrameRequestee != null)) - this.keyFrameControl.removeKeyFrameRequestee(keyFrameRequestee); - - this.keyFrameControl = keyFrameControl; - - if ((this.keyFrameControl != null) && (keyFrameRequestee != null)) - this.keyFrameControl.addKeyFrameRequestee(-1, keyFrameRequestee); - } - } - - /** - * Sets the Format in which this Codec is to output media - * data. - * - * @param out the Format in which this Codec is to - * output media data - * @return the Format in which this Codec is currently - * configured to output media data or null if format was - * found to be incompatible with this Codec - */ - @Override - public Format setOutputFormat(Format out) - { - // mismatch output format - if (!(out instanceof VideoFormat) - || (null - == AbstractCodecExt.matches( - out, - getMatchingOutputFormats(inputFormat)))) - return null; - - VideoFormat videoOut = (VideoFormat) out; - Dimension outSize = videoOut.getSize(); - - if (outSize == null) - { - Dimension inSize = ((VideoFormat) inputFormat).getSize(); - - outSize - = (inSize == null) - ? new Dimension( - Constants.VIDEO_WIDTH, - Constants.VIDEO_HEIGHT) - : inSize; - } - - Map fmtps = null; - - if (out instanceof ParameterizedVideoFormat) - fmtps = ((ParameterizedVideoFormat) out).getFormatParameters(); - if (fmtps == null) - fmtps = new HashMap(); - if (packetizationMode != null) - fmtps.put(PACKETIZATION_MODE_FMTP, packetizationMode); - - outputFormat - = new ParameterizedVideoFormat( - videoOut.getEncoding(), - outSize, - Format.NOT_SPECIFIED, - Format.byteArray, - videoOut.getFrameRate(), - fmtps); - - // Return the selected outputFormat - return outputFormat; - } - - /** - * Sets the packetization mode to be used for the H.264 RTP payload output - * by this JNIEncoder and the associated packetizer. - * - * @param packetizationMode the packetization mode to be used for the H.264 - * RTP payload output by this JNIEncoder and the associated - * packetizer - */ - public void setPacketizationMode(String packetizationMode) - { - /* - * RFC 3984 "RTP Payload Format for H.264 Video" says that "[w]hen the - * value of packetization-mode is equal to 0 or packetization-mode is - * not present, the single NAL mode, as defined in section 6.2 of RFC - * 3984, MUST be used." - */ - if ((packetizationMode == null) || "0".equals(packetizationMode)) - this.packetizationMode = "0"; - else if ("1".equals(packetizationMode)) - this.packetizationMode = "1"; - else - throw new IllegalArgumentException("packetizationMode"); - } - - /** - * Sets additional settings for the codec. - * - * @param settings additional settings - */ - public void setAdditionalCodecSettings(Map settings) - { - additionalSettings = settings; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/Packetizer.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/Packetizer.java deleted file mode 100644 index 00cf91b04..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/Packetizer.java +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.codec.video.h264; - -import java.awt.Dimension; // disambiguation -import java.util.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.format.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.sf.fmj.media.*; - -/** - * Packetizes H.264 encoded data/NAL units into RTP packets in accord with RFC - * 3984 "RTP Payload Format for H.264 Video". - * - * @author Damian Minkov - * @author Lyubomir Marinov - */ -public class Packetizer - extends AbstractPacketizer -{ - /** - * Maximum payload size without the headers. - */ - public static final int MAX_PAYLOAD_SIZE = 1024; - - /** - * Name of the plugin. - */ - private static final String PLUGIN_NAME = "H264 Packetizer"; - - /** - * The Formats supported by Packetizer instances as - * output. - */ - static final Format[] SUPPORTED_OUTPUT_FORMATS - = { - new ParameterizedVideoFormat( - Constants.H264_RTP, - JNIEncoder.PACKETIZATION_MODE_FMTP, "0"), - new ParameterizedVideoFormat( - Constants.H264_RTP, - JNIEncoder.PACKETIZATION_MODE_FMTP, "1") - }; - - /** - * The list of NAL units to be sent as payload in RTP packets. - */ - private final List nals = new LinkedList(); - - /** - * The timeStamp of the RTP packets in which nals are to be sent. - */ - private long nalsTimeStamp; - - /** - * The sequence number of the next RTP packet to be output by this - * Packetizer. - */ - private int sequenceNumber; - - /** - * Initializes a new Packetizer instance which is to packetize - * H.264 encoded data/NAL units into RTP packets in accord with RFC 3984 - * "RTP Payload Format for H.264 Video". - */ - public Packetizer() - { - inputFormats = JNIEncoder.SUPPORTED_OUTPUT_FORMATS; - - inputFormat = null; - outputFormat = null; - } - - /** - * Close this Packetizer. - */ - @Override - public synchronized void close() - { - if (opened) - { - opened = false; - super.close(); - } - } - - /** - * Finds the index in byteStream at which the - * start_code_prefix_one_3bytes of a NAL unit begins. - * - * @param byteStream the H.264 encoded byte stream composed of NAL units in - * which the index of the beginning of the start_code_prefix_one_3bytes of a - * NAL unit is to be found - * @param beginIndex the inclusive index in byteStream at which the - * search is to begin - * @param endIndex the exclusive index in byteStream at which the - * search is to end - * @return the index in byteStream at which the - * start_code_prefix_one_3bytes of a NAL unit begins if it is found; - * otherwise, endIndex - */ - private static int ff_avc_find_startcode( - byte[] byteStream, - int beginIndex, - int endIndex) - { - for (; beginIndex < (endIndex - 3); beginIndex++) - if((byteStream[beginIndex] == 0) - && (byteStream[beginIndex + 1] == 0) - && (byteStream[beginIndex + 2] == 1)) - return beginIndex; - return endIndex; - } - - /** - * Gets the output formats matching a specific input format. - * - * @param input the input format to get the matching output formats for - * @return an array of output formats matching the specified input format - */ - private Format[] getMatchingOutputFormats(Format input) - { - VideoFormat videoInput = (VideoFormat) input; - Dimension size = videoInput.getSize(); - float frameRate = videoInput.getFrameRate(); - String packetizationMode = getPacketizationMode(input); - - return - new Format[] - { - new ParameterizedVideoFormat( - Constants.H264_RTP, - size, - Format.NOT_SPECIFIED, - Format.byteArray, - frameRate, - ParameterizedVideoFormat.toMap( - JNIEncoder.PACKETIZATION_MODE_FMTP, - packetizationMode)) - }; - } - - /** - * Gets the name of this PlugIn. - * - * @return the name of this PlugIn - */ - @Override - public String getName() - { - return PLUGIN_NAME; - } - - /** - * Gets the value of the packetization-mode format parameter - * assigned by a specific Format. - * - * @param format the Format which assigns a value to the - * packetization-mode format parameter - * @return the value of the packetization-mode format parameter - * assigned by the specified format - */ - private String getPacketizationMode(Format format) - { - String packetizationMode = null; - - if (format instanceof ParameterizedVideoFormat) - packetizationMode - = ((ParameterizedVideoFormat) format).getFormatParameter( - JNIEncoder.PACKETIZATION_MODE_FMTP); - if (packetizationMode == null) - packetizationMode = "0"; - - return packetizationMode; - } - - /** - * Return the list of formats supported at the output. - * @param in input Format to determine corresponding output - * Format/tt>s - * @return array of formats supported at output - */ - public Format[] getSupportedOutputFormats(Format in) - { - // null input format - if (in == null) - return SUPPORTED_OUTPUT_FORMATS; - - // mismatch input format - if (!(in instanceof VideoFormat) - || (null == AbstractCodecExt.matches(in, inputFormats))) - return new Format[0]; - - return getMatchingOutputFormats(in); - } - - /** - * Open this Packetizer. - * - * @throws ResourceUnavailableException if something goes wrong during - * initialization of the Packetizer. - */ - @Override - public synchronized void open() - throws ResourceUnavailableException - { - if (!opened) - { - nals.clear(); - sequenceNumber = 0; - - super.open(); - opened = true; - } - } - - /** - * Packetizes a specific NAL unit of H.264 encoded data so that it becomes - * ready to be sent as the payload of RTP packets. If the specified NAL unit - * does not fit into a single RTP packet i.e. will not become a "Single NAL - * Unit Packet", splits it into "Fragmentation Units (FUs)" of type FU-A. - * - * @param nal the bytes which contain the NAL unit of H.264 encoded data to - * be packetized - * @param nalOffset the offset in nal at which the NAL unit of - * H.264 encoded data to be packetized begins - * @param nalLength the length in nal beginning at - * nalOffset of the NAL unit of H.264 encoded data to be packetized - * @return true if at least one RTP packet payload has been - * packetized i.e. prepared for sending; otherwise, false - */ - private boolean packetizeNAL(byte[] nal, int nalOffset, int nalLength) - { - /* - * If the NAL fits into a "Single NAL Unit Packet", it's already - * packetized. - */ - if (nalLength <= MAX_PAYLOAD_SIZE) - { - byte[] singleNALUnitPacket = new byte[nalLength]; - - System.arraycopy(nal, nalOffset, singleNALUnitPacket, 0, nalLength); - return nals.add(singleNALUnitPacket); - } - - // Otherwise, split it into "Fragmentation Units (FUs)". - byte octet = nal[nalOffset]; - int forbidden_zero_bit = octet & 0x80; - int nri = octet & 0x60; - int nal_unit_type = octet & 0x1F; - - byte fuIndicator - = (byte) - (0xFF - & (forbidden_zero_bit - | nri - | 28 /* nal_unit_type FU-A */)); - byte fuHeader - = (byte) - (0xFF - & (0x80 /* Start bit */ - | 0 /* End bit */ - | 0 /* Reserved bit */ - | nal_unit_type)); - - nalOffset++; - nalLength--; - - int maxFUPayloadLength - = MAX_PAYLOAD_SIZE - 2 /* FU indicator & FU header */; - boolean nalsAdded = false; - - while (nalLength > 0) - { - int fuPayloadLength; - - if (nalLength > maxFUPayloadLength) - fuPayloadLength = maxFUPayloadLength; - else - { - fuPayloadLength = nalLength; - fuHeader |= 0x40; // Turn on the End bit. - } - - /* - * Tests with Asterisk suggest that the fragments of a fragmented - * NAL unit must be with one and the same size. There is also a - * similar question on the x264-devel mailing list but, - * unfortunately, it is unanswered. - */ - byte[] fua - = new byte[ - 2 /* FU indicator & FU header */ + maxFUPayloadLength]; - - fua[0] = fuIndicator; - fua[1] = fuHeader; - System.arraycopy(nal, nalOffset, fua, 2, fuPayloadLength); - nalOffset += fuPayloadLength; - nalLength -= fuPayloadLength; - - nalsAdded = nals.add(fua) || nalsAdded; - - fuHeader &= ~0x80; // Turn off the Start bit. - } - return nalsAdded; - } - - /** - * Processes (packetize) a buffer. - * - * @param inBuffer input buffer - * @param outBuffer output buffer - * @return BUFFER_PROCESSED_OK if buffer has been successfully - * processed - */ - @Override - public int process(Buffer inBuffer, Buffer outBuffer) - { - // if there are some nals we check and send them - if (nals.size() > 0) - { - byte[] nal = nals.remove(0); - - // Send the NAL. - outBuffer.setData(nal); - outBuffer.setLength(nal.length); - outBuffer.setOffset(0); - outBuffer.setTimeStamp(nalsTimeStamp); - outBuffer.setSequenceNumber(sequenceNumber++); - - // If there are other NALs, send them as well. - if(nals.size() > 0) - return (BUFFER_PROCESSED_OK | INPUT_BUFFER_NOT_CONSUMED); - else - { - int flags = outBuffer.getFlags() | Buffer.FLAG_RTP_MARKER; - - /* - * It's the last NAL of the current frame so mark it. In order - * to (at least partially) support feeding this Packetizer one - * NAL at a time, do NOT always mark it i.e. the NALs with - * a value for nal_unit_type which signals that they cannot be - * the last NALs in an access unit should probably NOT be - * marked anyway. - */ - if (nal.length > 0) - { - int nal_unit_type = nal[0] & 0x1F; - - if ((nal_unit_type == 28 /* FU-A */) && (nal.length > 1)) - { - byte fuHeader = nal[1]; - - if ((fuHeader & 0x40 /* End bit */) == 0) - { - /* - * A FU-A without the End bit cannot possibly be the - * last NAL unit of an access unit. - */ - flags &= ~Buffer.FLAG_RTP_MARKER; - } - else - nal_unit_type = fuHeader & 0x1F; - } - - switch (nal_unit_type) - { - case 6 /* Supplemental enhancement information (SEI) */: - case 7 /* Sequence parameter set */: - case 8 /* Picture parameter set */: - case 9 /* Access unit delimiter */: - flags &= ~Buffer.FLAG_RTP_MARKER; - break; - } - } - - outBuffer.setFlags(flags); - return BUFFER_PROCESSED_OK; - } - } - - if (isEOM(inBuffer)) - { - propagateEOM(outBuffer); - reset(); - return BUFFER_PROCESSED_OK; - } - if (inBuffer.isDiscard()) - { - outBuffer.setDiscard(true); - reset(); - return BUFFER_PROCESSED_OK; - } - - Format inFormat = inBuffer.getFormat(); - - if ((inFormat != inputFormat) && !inFormat.matches(inputFormat)) - setInputFormat(inFormat); - - int inLength = inBuffer.getLength(); - - /* - * We need 3 bytes for start_code_prefix_one_3bytes and at least 1 byte - * for the NAL unit i.e. its octet serving as the payload header. - */ - if (inLength < 4) - { - outBuffer.setDiscard(true); - reset(); - return BUFFER_PROCESSED_OK; - } - - byte[] inData = (byte[]) inBuffer.getData(); - int inOffset = inBuffer.getOffset(); - boolean nalsAdded = false; - - /* - * Split the H.264 encoded data into NAL units. Each NAL unit begins - * with start_code_prefix_one_3bytes. Refer to "B.1 Byte stream NAL unit - * syntax and semantics" of "ITU-T Rec. H.264 Advanced video coding for - * generic audiovisual services" for further details. - */ - int endIndex = inOffset + inLength; - int beginIndex = ff_avc_find_startcode(inData, inOffset, endIndex); - - if (beginIndex < endIndex) - { - beginIndex += 3; - - for (int nextBeginIndex; - (beginIndex < endIndex) - && ((nextBeginIndex - = ff_avc_find_startcode( - inData, - beginIndex, endIndex)) - <= endIndex); - beginIndex = nextBeginIndex + 3) - { - int nalLength = nextBeginIndex - beginIndex; - - // Discard any trailing_zero_8bits. - while ((nalLength > 0) - && (inData[beginIndex + nalLength - 1] == 0)) - nalLength--; - - if (nalLength > 0) - nalsAdded - = packetizeNAL(inData, beginIndex, nalLength) - || nalsAdded; - } - } - - nalsTimeStamp = inBuffer.getTimeStamp(); - - return - nalsAdded ? process(inBuffer, outBuffer) : OUTPUT_BUFFER_NOT_FILLED; - } - - /** - * Sets the input format. - * - * @param in format to set - * @return format - */ - @Override - public Format setInputFormat(Format in) - { - /* - * Return null if the specified input Format is incompatible with this - * Packetizer. - */ - if (!(in instanceof VideoFormat) - || null == AbstractCodecExt.matches(in, inputFormats)) - return null; - - inputFormat = in; - return in; - } - - /** - * Sets the Format in which this Codec is to output media - * data. - * - * @param output the Format in which this Codec is to - * output media data - * @return the Format in which this Codec is currently - * configured to output media data or null if format was - * found to be incompatible with this Codec - */ - @Override - public Format setOutputFormat(Format output) - { - /* - * Return null if the specified output Format is incompatible with this - * Packetizer. - */ - if (!(output instanceof VideoFormat) - || (null - == AbstractCodecExt.matches( - output, - getMatchingOutputFormats(inputFormat)))) - return null; - - VideoFormat videoOutput = (VideoFormat) output; - Dimension outputSize = videoOutput.getSize(); - - if (outputSize == null) - { - Dimension inputSize = ((VideoFormat) inputFormat).getSize(); - - outputSize - = (inputSize == null) - ? new Dimension( - Constants.VIDEO_WIDTH, - Constants.VIDEO_HEIGHT) - : inputSize; - } - - Map fmtps = null; - - if (output instanceof ParameterizedVideoFormat) - fmtps = ((ParameterizedVideoFormat) output).getFormatParameters(); - if (fmtps == null) - fmtps = new HashMap(); - if (fmtps.get(JNIEncoder.PACKETIZATION_MODE_FMTP) == null) - fmtps.put( - JNIEncoder.PACKETIZATION_MODE_FMTP, - getPacketizationMode(inputFormat)); - - outputFormat - = new ParameterizedVideoFormat( - videoOutput.getEncoding(), - outputSize, - outputSize.width * outputSize.height, - Format.byteArray, - videoOutput.getFrameRate(), - fmtps); - - // Return the outputFormat which is actually set. - return outputFormat; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/conference/AudioMixer.java b/src/net/java/sip/communicator/impl/neomedia/conference/AudioMixer.java deleted file mode 100644 index e3733c23a..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/conference/AudioMixer.java +++ /dev/null @@ -1,1141 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.conference; - -import java.io.*; -import java.lang.reflect.*; -import java.util.*; - -import javax.media.*; -import javax.media.Controls; // disambiguation -import javax.media.control.*; -import javax.media.format.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.control.*; -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.impl.neomedia.protocol.*; -import net.java.sip.communicator.util.*; - -/** - * Represents an audio mixer which manages the mixing of multiple audio streams - * i.e. it is able to output a single audio stream which contains the audio of - * multiple input audio streams. - *

- * The input audio streams are provided to the AudioMixer through - * {@link #addInputDataSource(DataSource)} in the form of input - * DataSources giving access to one or more input - * SourceStreams. - *

- *

- * The output audio stream representing the mix of the multiple input audio - * streams is provided by the AudioMixer in the form of a - * AudioMixingPushBufferDataSource giving access to a - * AudioMixingPushBufferStream. Such an output is obtained through - * {@link #createOutputDataSource()}. The AudioMixer is able to provide - * multiple output audio streams at one and the same time, though, each of them - * containing the mix of a subset of the input audio streams. - *

- * - * @author Lubomir Marinov - */ -public class AudioMixer -{ - - /** - * The Logger used by the AudioMixer class and its - * instances for logging output. - */ - private static final Logger logger = Logger.getLogger(AudioMixer.class); - - /** - * The default output AudioFormat in which AudioMixer, - * AudioMixingPushBufferDataSource and - * AudioMixingPushBufferStream output audio. - */ - private static final AudioFormat DEFAULT_OUTPUT_FORMAT - = new AudioFormat( - AudioFormat.LINEAR, - 8000, - 16, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED); - - /** - * The BufferControl of this instance and, respectively, its - * AudioMixingPushBufferDataSources. - */ - private BufferControl bufferControl; - - /** - * The CaptureDevice capabilities provided by the - * AudioMixingPushBufferDataSources created by this - * AudioMixer. JMF's - * Manager.createMergingDataSource(DataSource[]) requires the - * interface implementation for audio if it is implemented for video and it - * is indeed the case for our use case of - * AudioMixingPushBufferDataSource. - */ - protected final CaptureDevice captureDevice; - - /** - * The number of output AudioMixingPushBufferDataSources reading - * from this AudioMixer which are connected. When the value is - * greater than zero, this AudioMixer is connected to the input - * DataSources it manages. - */ - private int connected; - - /** - * The collection of input DataSources this instance reads audio - * data from. - */ - private final List inputDataSources - = new ArrayList(); - - /** - * The AudioMixingPushBufferDataSource which contains the mix of - * inputDataSources excluding captureDevice and is thus - * meant for playback on the local peer in a call. - */ - private final AudioMixingPushBufferDataSource localOutputDataSource; - - /** - * The number of output AudioMixingPushBufferDataSources reading - * from this AudioMixer which are started. When the value is - * greater than zero, this AudioMixer is started and so are the - * input DataSources it manages. - */ - private int started; - - /** - * The output AudioMixerPushBufferStream through which this - * instance pushes audio sample data to - * AudioMixingPushBufferStreams to be mixed. - */ - private AudioMixerPushBufferStream outputStream; - - /** - * Initializes a new AudioMixer instance. Because JMF's - * Manager.createMergingDataSource(DataSource[]) requires the - * implementation of CaptureDevice for audio if it is implemented - * for video and it is indeed the cause for our use case of - * AudioMixingPushBufferDataSource, the new AudioMixer - * instance provides specified CaptureDevice capabilities to the - * AudioMixingPushBufferDataSources it creates. The specified - * CaptureDevice is also added as the first input - * DataSource of the new instance. - * - * @param captureDevice the CaptureDevice capabilities to be - * provided to the AudioMixingPushBufferDataSources created by the - * new instance and its first input DataSource - */ - public AudioMixer(CaptureDevice captureDevice) - { - /* - * AudioMixer provides PushBufferDataSources so it needs a way to push - * them. It does the pushing by using the pushes of its CaptureDevice - * i.e. it has to be a PushBufferDataSource. - */ - if (captureDevice instanceof PullBufferDataSource) - { - captureDevice - = new PushBufferDataSourceAdapter( - (PullBufferDataSource) captureDevice); - } - - // Try to enable tracing on captureDevice. - if (logger.isTraceEnabled()) - { - captureDevice - = MediaDeviceImpl.createTracingCaptureDevice( - captureDevice, - logger); - } - - this.captureDevice = captureDevice; - - this.localOutputDataSource = createOutputDataSource(); - addInputDataSource( - (DataSource) this.captureDevice, - this.localOutputDataSource); - } - - /** - * Adds a new input DataSource to the collection of input - * DataSources from which this instance reads audio. If the - * specified DataSource indeed provides audio, the respective - * contributions to the mix are always included. - * - * @param inputDataSource a new DataSource to input audio to this - * instance - */ - public void addInputDataSource(DataSource inputDataSource) - { - addInputDataSource(inputDataSource, null); - } - - /** - * Adds a new input DataSource to the collection of input - * DataSources from which this instance reads audio. If the - * specified DataSource indeed provides audio, the respective - * contributions to the mix will be excluded from the mix output provided - * through a specific AudioMixingPushBufferDataSource. - * - * @param inputDataSource a new DataSource to input audio to this - * instance - * @param outputDataSource the AudioMixingPushBufferDataSource to - * not include the audio contributions of inputDataSource in the - * mix it outputs - */ - void addInputDataSource( - DataSource inputDataSource, - AudioMixingPushBufferDataSource outputDataSource) - { - if (inputDataSource == null) - throw new NullPointerException("inputDataSource"); - - synchronized (inputDataSources) - { - for (InputDataSourceDesc inputDataSourceDesc : inputDataSources) - if (inputDataSource.equals(inputDataSourceDesc.inputDataSource)) - throw new IllegalArgumentException("inputDataSource"); - - InputDataSourceDesc inputDataSourceDesc - = new InputDataSourceDesc( - inputDataSource, - outputDataSource); - boolean added = inputDataSources.add(inputDataSourceDesc); - - if (added) - { - if (logger.isTraceEnabled()) - { - logger.trace( - "Added input DataSource with hashCode " - + inputDataSource.hashCode()); - } - - /* - * If the other inputDataSources have already been connected, - * connect to the new one as well. - */ - if (connected > 0) - { - try - { - inputDataSourceDesc.connect(this); - } - catch (IOException ioex) - { - throw new UndeclaredThrowableException(ioex); - } - } - - // Update outputStream with any new inputStreams. - if (outputStream != null) - getOutputStream(); - - /* - * If the other inputDataSources have been started, start the - * new one as well. - */ - if (started > 0) - { - try - { - inputDataSourceDesc.start(); - } - catch (IOException ioe) - { - throw new UndeclaredThrowableException(ioe); - } - } - } - } - } - - /** - * Notifies this AudioMixer that an output - * AudioMixingPushBufferDataSource reading from it has been - * connected. The first of the many - * AudioMixingPushBufferDataSources reading from this - * AudioMixer which gets connected causes it to connect to the - * input DataSources it manages. - * - * @throws IOException if input/output error occurred - */ - void connect() - throws IOException - { - synchronized (inputDataSources) - { - if (connected == 0) - { - for (InputDataSourceDesc inputDataSourceDesc : inputDataSources) - try - { - inputDataSourceDesc.connect(this); - } - catch (IOException ioe) - { - logger - .error( - "Failed to connect to inputDataSource " - + MediaStreamImpl - .toString( - inputDataSourceDesc - .inputDataSource), - ioe); - throw ioe; - } - - /* - * Since the media of the input streams is to be mixed, their - * bufferLengths have to be equal. After a DataSource is - * connected, its BufferControl is available and its - * bufferLength may change so make sure that the bufferLengths - * of the input streams are equal. - */ - if (outputStream != null) - outputStream.equalizeInputStreamBufferLength(); - } - - connected++; - } - } - - /** - * Connects to a specific DataSource which this AudioMixer - * will read audio from. The specified DataSource is known to exist - * because of a specific DataSource added as an input to this - * instance i.e. it may be an actual input DataSource added to this - * instance or a DataSource transcoding an input - * DataSource added to this instance. - * - * @param dataSource the DataSource to connect to - * @param inputDataSource the DataSource which is the cause for - * dataSource to exist in this AudioMixer - * @throws IOException if anything wrong happens while connecting to - * dataSource - */ - protected void connect(DataSource dataSource, DataSource inputDataSource) - throws IOException - { - dataSource.connect(); - } - - /** - * Notifies this AudioMixer that a specific input - * DataSource has finished its connecting procedure. Primarily - * meant for input DataSource which have their connecting executed - * in a separate thread as are, for example, input DataSources - * which are being transcoded. - * - * @param inputDataSource the InputDataSourceDesc of the input - * DataSource which has finished its connecting procedure - * @throws IOException if anything wrong happens while including - * inputDataSource into the mix - */ - void connected(InputDataSourceDesc inputDataSource) - throws IOException - { - synchronized (inputDataSources) - { - if (inputDataSources.contains(inputDataSource) - && (connected > 0)) - { - if (started > 0) - inputDataSource.start(); - if (outputStream != null) - getOutputStream(); - } - } - } - - /** - * Creates a new InputStreamDesc instance which is to describe a - * specific input SourceStream originating from a specific input - * DataSource given by its InputDataSourceDesc. - * - * @param inputStream the input SourceStream to be described by the - * new instance - * @param inputDataSourceDesc the input DataSource given by its - * InputDataSourceDesc to be described by the new instance - * @return a new InputStreamDesc instance which describes the - * specified input SourceStream and DataSource - */ - private InputStreamDesc createInputStreamDesc( - SourceStream inputStream, - InputDataSourceDesc inputDataSourceDesc) - { - return new InputStreamDesc(inputStream, inputDataSourceDesc); - } - - /** - * Creates a new AudioMixingPushBufferDataSource which gives - * access to a single audio stream representing the mix of the audio streams - * input into this AudioMixer through its input - * DataSources. The returned - * AudioMixingPushBufferDataSource can also be used to include - * new input DataSources in this AudioMixer but - * have their contributions not included in the mix available through the - * returned AudioMixingPushBufferDataSource. - * - * @return a new AudioMixingPushBufferDataSource which gives access - * to a single audio stream representing the mix of the audio streams input - * into this AudioMixer through its input DataSources - */ - public AudioMixingPushBufferDataSource createOutputDataSource() - { - return new AudioMixingPushBufferDataSource(this); - } - - /** - * Creates a DataSource which attempts to transcode the tracks of a - * specific input DataSource into a specific output - * Format. - * - * @param inputDataSourceDesc the InputDataSourceDesc describing - * the input DataSource to be transcoded into the specified output - * Format and to receive the transcoding DataSource - * @param outputFormat the Format in which the tracks of the input - * DataSource are to be transcoded - * @return true if a new transcoding DataSource has been - * created for the input DataSource described by - * inputDataSourceDesc; otherwise, false - * @throws IOException if an error occurs while creating the transcoding - * DataSource, connecting to it or staring it - */ - private boolean createTranscodingDataSource( - InputDataSourceDesc inputDataSourceDesc, - Format outputFormat) - throws IOException - { - if (inputDataSourceDesc.createTranscodingDataSource(outputFormat)) - { - if (connected > 0) - inputDataSourceDesc.connect(this); - if (started > 0) - inputDataSourceDesc.start(); - return true; - } - else - return false; - } - - /** - * Notifies this AudioMixer that an output - * AudioMixingPushBufferDataSource reading from it has been - * disconnected. The last of the many - * AudioMixingPushBufferDataSources reading from this - * AudioMixer which gets disconnected causes it to disconnect - * from the input DataSources it manages. - */ - void disconnect() - { - synchronized (inputDataSources) - { - if (connected <= 0) - return; - - connected--; - - if (connected == 0) - { - for (InputDataSourceDesc inputDataSourceDesc : inputDataSources) - inputDataSourceDesc.disconnect(); - - /* - * XXX Make the outputStream to release the inputStreams. - * Otherwise, the PushBufferStream ones which have been wrapped - * into CachingPushBufferStream may remaing waiting. - */ - outputStream.setInputStreams(null); - outputStream = null; - } - } - } - - /** - * Gets the BufferControl of this instance and, respectively, its - * AudioMixingPushBufferDataSources. - * - * @return the BufferControl of this instance and, respectively, - * its AudioMixingPushBufferDataSources if such a control is - * available for the CaptureDevice of this instance; otherwise, - * null - */ - BufferControl getBufferControl() - { - if ((bufferControl == null) && (captureDevice instanceof Controls)) - { - BufferControl captureDeviceBufferControl - = (BufferControl) - ((Controls) captureDevice) - .getControl(BufferControl.class.getName()); - - if (captureDeviceBufferControl != null) - bufferControl - = new ReadOnlyBufferControlDelegate( - captureDeviceBufferControl); - } - return bufferControl; - } - - /** - * Gets the CaptureDeviceInfo of the CaptureDevice - * this AudioMixer provides through its output - * AudioMixingPushBufferDataSources. - * - * @return the CaptureDeviceInfo of the CaptureDevice this - * AudioMixer provides through its output - * AudioMixingPushBufferDataSources - */ - CaptureDeviceInfo getCaptureDeviceInfo() - { - return captureDevice.getCaptureDeviceInfo(); - } - - /** - * Gets the content type of the data output by this AudioMixer. - * - * @return the content type of the data output by this AudioMixer - */ - String getContentType() - { - return ContentDescriptor.RAW; - } - - /** - * Gets an InputStreamDesc from a specific existing list of - * InputStreamDescs which describes a specific - * SourceStream. If such an InputStreamDesc does not - * exist, returns null. - * - * @param inputStream the SourceStream to locate an - * InputStreamDesc for in existingInputStreamDescs - * @param existingInputStreamDescs the list of existing - * InputStreamDescs in which an InputStreamDesc for - * inputStream is to be located - * @return an InputStreamDesc from - * existingInputStreamDescs which describes inputStream if - * such an InputStreamDesc exists; otherwise, null - */ - private InputStreamDesc getExistingInputStreamDesc( - SourceStream inputStream, - InputStreamDesc[] existingInputStreamDescs) - { - if (existingInputStreamDescs == null) - return null; - - for (InputStreamDesc existingInputStreamDesc - : existingInputStreamDescs) - { - SourceStream existingInputStream - = existingInputStreamDesc.getInputStream(); - - if (existingInputStream == inputStream) - return existingInputStreamDesc; - if ((existingInputStream instanceof BufferStreamAdapter) - && (((BufferStreamAdapter) existingInputStream) - .getStream() - == inputStream)) - return existingInputStreamDesc; - if ((existingInputStream instanceof CachingPushBufferStream) - && (((CachingPushBufferStream) existingInputStream) - .getStream() - == inputStream)) - return existingInputStreamDesc; - } - return null; - } - - /** - * Gets the duration of each one of the output streams produced by this - * AudioMixer. - * - * @return the duration of each one of the output streams produced by this - * AudioMixer - */ - Time getDuration() - { - return ((DataSource) captureDevice).getDuration(); - } - - /** - * Gets the Format in which a specific DataSource - * provides stream data. - * - * @param dataSource the DataSource for which the Format - * in which it provides stream data is to be determined - * @return the Format in which the specified dataSource - * provides stream data if it was determined; otherwise, null - */ - private static Format getFormat(DataSource dataSource) - { - FormatControl formatControl - = (FormatControl) dataSource.getControl( - FormatControl.class.getName()); - - return (formatControl == null) ? null : formatControl.getFormat(); - } - - /** - * Gets the Format in which a specific - * SourceStream provides data. - * - * @param stream - * the SourceStream for which the - * Format in which it provides data is to be - * determined - * @return the Format in which the specified - * SourceStream provides data if it was determined; - * otherwise, null - */ - private static Format getFormat(SourceStream stream) - { - if (stream instanceof PushBufferStream) - return ((PushBufferStream) stream).getFormat(); - if (stream instanceof PullBufferStream) - return ((PullBufferStream) stream).getFormat(); - return null; - } - - /** - * Gets an array of FormatControls for the - * CaptureDevice this AudioMixer provides through - * its output AudioMixingPushBufferDataSources. - * - * @return an array of FormatControls for the - * CaptureDevice this AudioMixer provides - * through its output AudioMixingPushBufferDataSources - */ - FormatControl[] getFormatControls() - { - /* - * Setting the format of the captureDevice once we've started using it - * is likely to wreak havoc so disable it. - */ - FormatControl[] formatControls = captureDevice.getFormatControls(); - - if (!OSUtils.IS_ANDROID && (formatControls != null)) - for (int i = 0; i < formatControls.length; i++) - formatControls[i] - = new ReadOnlyFormatControlDelegate(formatControls[i]); - return formatControls; - } - - /** - * Gets the SourceStreams (in the form of InputStreamDesc) - * of a specific DataSource (provided in the form of - * InputDataSourceDesc) which produce data in a specific - * AudioFormat (or a matching one). - * - * @param inputDataSourceDesc the DataSource (in the form of - * InputDataSourceDesc) which is to be examined for - * SourceStreams producing data in the specified - * AudioFormat - * @param outputFormat the AudioFormat in which the collected - * SourceStreams are to produce data - * @param existingInputStreams the InputStreamDesc instances which - * already exist and which are used to avoid creating multiple - * InputStreamDescs for input SourceStreams which already - * have ones - * @param inputStreams the List of InputStreamDesc in - * which the discovered SourceStreams are to be returned - * @return true if SourceStreams produced by the specified - * input DataSource and outputting data in the specified - * AudioFormat were discovered and reported in - * inputStreams; otherwise, false - */ - private boolean getInputStreamsFromInputDataSource( - InputDataSourceDesc inputDataSourceDesc, - AudioFormat outputFormat, - InputStreamDesc[] existingInputStreams, - List inputStreams) - { - SourceStream[] inputDataSourceStreams - = inputDataSourceDesc.getStreams(); - - if (inputDataSourceStreams != null) - { - boolean added = false; - - for (SourceStream inputStream : inputDataSourceStreams) - { - Format inputFormat = getFormat(inputStream); - - if ((inputFormat != null) - && matches(inputFormat, outputFormat)) - { - InputStreamDesc inputStreamDesc - = getExistingInputStreamDesc( - inputStream, - existingInputStreams); - - if (inputStreamDesc == null) - inputStreamDesc - = createInputStreamDesc( - inputStream, - inputDataSourceDesc); - if (inputStreams.add(inputStreamDesc)) - added = true; - } - } - return added; - } - - DataSource inputDataSource - = inputDataSourceDesc.getEffectiveInputDataSource(); - - if (inputDataSource == null) - return false; - - Format inputFormat = getFormat(inputDataSource); - - if ((inputFormat != null) && !matches(inputFormat, outputFormat)) - { - if (inputDataSource instanceof PushDataSource) - { - for (PushSourceStream inputStream - : ((PushDataSource) inputDataSource).getStreams()) - { - InputStreamDesc inputStreamDesc - = getExistingInputStreamDesc( - inputStream, - existingInputStreams); - - if (inputStreamDesc == null) - inputStreamDesc - = createInputStreamDesc( - new PushBufferStreamAdapter( - inputStream, - inputFormat), - inputDataSourceDesc); - inputStreams.add(inputStreamDesc); - } - return true; - } - if (inputDataSource instanceof PullDataSource) - { - for (PullSourceStream inputStream - : ((PullDataSource) inputDataSource).getStreams()) - { - InputStreamDesc inputStreamDesc - = getExistingInputStreamDesc( - inputStream, - existingInputStreams); - - if (inputStreamDesc == null) - inputStreamDesc - = createInputStreamDesc( - new PullBufferStreamAdapter( - inputStream, - inputFormat), - inputDataSourceDesc); - inputStreams.add(inputStreamDesc); - } - return true; - } - } - return false; - } - - /** - * Gets the SourceStreams (in the form of InputStreamDesc) - * of the DataSources from which this AudioMixer reads - * data which produce data in a specific AudioFormat. When an input - * DataSource does not have such SourceStreams, an attempt - * is made to transcode its tracks so that such SourceStreams can - * be retrieved from it after transcoding. - * - * @param outputFormat the AudioFormat in which the retrieved - * SourceStreams are to produce data - * @param existingInputStreams the SourceStreams which are already - * known to this AudioMixer - * @return a new collection of SourceStreams (in the form of - * InputStreamDesc) retrieved from the input DataSources - * of this AudioMixer and producing data in the specified - * AudioFormat - * @throws IOException if anything wrong goes while retrieving the input - * SourceStreams from the input DataSources - */ - private Collection getInputStreamsFromInputDataSources( - AudioFormat outputFormat, - InputStreamDesc[] existingInputStreams) - throws IOException - { - List inputStreams = new ArrayList(); - - synchronized (inputDataSources) - { - for (InputDataSourceDesc inputDataSourceDesc : inputDataSources) - { - boolean got - = getInputStreamsFromInputDataSource( - inputDataSourceDesc, - outputFormat, - existingInputStreams, - inputStreams); - - if (!got - && createTranscodingDataSource( - inputDataSourceDesc, - outputFormat)) - getInputStreamsFromInputDataSource( - inputDataSourceDesc, - outputFormat, - existingInputStreams, - inputStreams); - } - } - return inputStreams; - } - - /** - * Gets the AudioMixingPushBufferDataSource containing the mix of - * all input DataSources excluding the CaptureDevice of - * this AudioMixer and is thus meant for playback on the local peer - * in a call. - * - * @return the AudioMixingPushBufferDataSource containing the mix - * of all input DataSources excluding the CaptureDevice of - * this AudioMixer and is thus meant for playback on the local peer - * in a call - */ - public AudioMixingPushBufferDataSource getLocalOutputDataSource() - { - return localOutputDataSource; - } - - /** - * Gets the AudioFormat in which the input - * DataSources of this AudioMixer can produce data - * and which is to be the output Format of this - * AudioMixer. - * - * @return the AudioFormat in which the input - * DataSources of this AudioMixer can - * produce data and which is to be the output Format of - * this AudioMixer - */ - private AudioFormat getOutputFormatFromInputDataSources() - { - String formatControlType = FormatControl.class.getName(); - AudioFormat outputFormat = null; - - synchronized (inputDataSources) - { - for (InputDataSourceDesc inputDataSource : inputDataSources) - { - DataSource effectiveInputDataSource - = inputDataSource.getEffectiveInputDataSource(); - - if (effectiveInputDataSource == null) - continue; - - FormatControl formatControl - = (FormatControl) - effectiveInputDataSource.getControl(formatControlType); - - if (formatControl != null) - { - AudioFormat format - = (AudioFormat) formatControl.getFormat(); - - if (format != null) - { - // SIGNED - int signed = format.getSigned(); - - if ((AudioFormat.SIGNED == signed) - || (Format.NOT_SPECIFIED == signed)) - { - // LITTLE_ENDIAN - int endian = format.getEndian(); - - if ((AudioFormat.LITTLE_ENDIAN == endian) - || (Format.NOT_SPECIFIED == endian)) - { - outputFormat = format; - break; - } - } - } - } - } - } - - if (outputFormat == null) - outputFormat = DEFAULT_OUTPUT_FORMAT; - - if (logger.isTraceEnabled()) - { - logger.trace( - "Determined outputFormat of AudioMixer" - + " from inputDataSources to be " - + outputFormat); - } - return outputFormat; - } - - /** - * Gets the AudioMixerPushBufferStream, first creating it if it - * does not exist already, which reads data from the input - * DataSources of this AudioMixer and pushes it to - * output AudioMixingPushBufferStreams for audio mixing. - * - * @return the AudioMixerPushBufferStream which reads data from - * the input DataSources of this - * AudioMixer and pushes it to output - * AudioMixingPushBufferStreams for audio mixing - */ - AudioMixerPushBufferStream getOutputStream() - { - synchronized (inputDataSources) - { - AudioFormat outputFormat - = (outputStream == null) - ? getOutputFormatFromInputDataSources() - : outputStream.getFormat(); - - setOutputFormatToInputDataSources(outputFormat); - - Collection inputStreams; - - try - { - inputStreams - = getInputStreamsFromInputDataSources( - outputFormat, - (outputStream == null) - ? null - : outputStream.getInputStreams()); - } - catch (IOException ioex) - { - throw new UndeclaredThrowableException(ioex); - } - - if (outputStream == null) - outputStream - = new AudioMixerPushBufferStream(this, outputFormat); - outputStream.setInputStreams(inputStreams); - return outputStream; - } - } - - /** - * Determines whether a specific Format matches a specific - * Format in the sense of JMF Format matching. - * Since this AudioMixer and the audio mixing functionality - * related to it can handle varying characteristics of a certain output - * Format, the only requirement for the specified - * Formats to match is for both of them to have one and the - * same encoding. - * - * @param input - * the Format for which it is required to determine - * whether it matches a specific Format - * @param pattern - * the Format against which the specified - * input is to be matched - * @return true if the specified - * input matches the specified pattern in - * the sense of JMF Format matching; otherwise, - * false - */ - private boolean matches(Format input, AudioFormat pattern) - { - return - ((input instanceof AudioFormat) && input.isSameEncoding(pattern)); - } - - /** - * Reads media from a specific PushBufferStream which belongs to - * a specific DataSource into a specific output Buffer. - * Allows extenders to tap into the reading and monitor and customize it. - * - * @param stream the PushBufferStream to read media from and known - * to belong to the specified DataSOurce - * @param buffer the output Buffer in which the media read from the - * specified stream is to be written so that it gets returned to - * the caller - * @param dataSource the DataSource from which stream - * originated - * @throws IOException if anything wrong happens while reading from the - * specified stream - */ - protected void read( - PushBufferStream stream, - Buffer buffer, - DataSource dataSource) - throws IOException - { - stream.read(buffer); - } - - /** - * Removes DataSources accepted by a specific - * DataSourceFilter from the list of input DataSources of - * this AudioMixer from which it reads audio to be mixed. - * - * @param dataSourceFilter the DataSourceFilter which selects the - * DataSources to be removed from the list of input - * DataSources of this AudioMixer from which it reads - * audio to be mixed - */ - public void removeInputDataSources(DataSourceFilter dataSourceFilter) - { - synchronized (inputDataSources) - { - Iterator inputDataSourceIter - = inputDataSources.iterator(); - boolean removed = false; - - while (inputDataSourceIter.hasNext()) - { - if (dataSourceFilter - .accept(inputDataSourceIter.next().inputDataSource)) - { - inputDataSourceIter.remove(); - removed = true; - } - } - if (removed && (outputStream != null)) - getOutputStream(); - } - } - - /** - * Sets a specific AudioFormat, if possible, as the output - * format of the input DataSources of this - * AudioMixer in an attempt to not have to perform explicit - * transcoding of the input SourceStreams. - * - * @param outputFormat - * the AudioFormat in which the input - * DataSources of this AudioMixer are - * to be instructed to output - */ - private void setOutputFormatToInputDataSources(AudioFormat outputFormat) - { - String formatControlType = FormatControl.class.getName(); - - synchronized (inputDataSources) - { - for (InputDataSourceDesc inputDataSourceDesc : inputDataSources) - { - FormatControl formatControl - = (FormatControl) - inputDataSourceDesc.getControl(formatControlType); - - if (formatControl != null) - { - Format inputFormat = formatControl.getFormat(); - - if ((inputFormat == null) - || !matches(inputFormat, outputFormat)) - { - Format setFormat - = formatControl.setFormat(outputFormat); - - if (setFormat == null) - logger - .error( - "Failed to set format of inputDataSource to " - + outputFormat); - else if (setFormat != outputFormat) - logger - .warn( - "Failed to change format of inputDataSource from " - + setFormat - + " to " - + outputFormat); - else if (logger.isTraceEnabled()) - logger - .trace( - "Set format of inputDataSource to " - + setFormat); - } - } - } - } - } - - /** - * Starts the input DataSources of this AudioMixer. - * - * @param outputStream the AudioMixerPushBufferStream which - * requests this AudioMixer to start. If outputStream is - * the current one and only AudioMixerPushBufferStream of this - * AudioMixer, this AudioMixer starts if it hasn't started - * yet. Otherwise, the request is ignored. - * @throws IOException if any of the input DataSources of this - * AudioMixer throws such an exception while attempting to start it - */ - void start(AudioMixerPushBufferStream outputStream) - throws IOException - { - synchronized (inputDataSources) - { - /* - * AudioMixer has only one outputStream at a time and only its - * current outputStream known when it has to start (and stop). - */ - if (this.outputStream != outputStream) - return; - - if (started == 0) - { - for (InputDataSourceDesc inputDataSourceDesc : inputDataSources) - inputDataSourceDesc.start(); - } - - started++; - } - } - - /** - * Stops the input DataSources of this AudioMixer. - * - * @param outputStream the AudioMixerPushBufferStream which - * requests this AudioMixer to stop. If outputStream is - * the current one and only AudioMixerPushBufferStream of this - * AudioMixer, this AudioMixer stops. Otherwise, the - * request is ignored. - * @throws IOException if any of the input DataSources of this - * AudioMixer throws such an exception while attempting to stop it - */ - void stop(AudioMixerPushBufferStream outputStream) - throws IOException - { - synchronized (inputDataSources) - { - /* - * AudioMixer has only one outputStream at a time and only its - * current outputStream known when it has to stop (and start). - */ - if (this.outputStream != outputStream) - return; - - if (started <= 0) - return; - - started--; - - if (started == 0) - { - for (InputDataSourceDesc inputDataSourceDesc : inputDataSources) - inputDataSourceDesc.stop(); - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/conference/AudioMixerPushBufferStream.java b/src/net/java/sip/communicator/impl/neomedia/conference/AudioMixerPushBufferStream.java deleted file mode 100644 index 0008a267f..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/conference/AudioMixerPushBufferStream.java +++ /dev/null @@ -1,1406 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.conference; - -import java.io.*; -import java.lang.ref.*; -import java.lang.reflect.*; -import java.util.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.control.*; -import net.java.sip.communicator.impl.neomedia.protocol.*; -import net.java.sip.communicator.util.*; - -/** - * Represents a PushBufferStream which reads data from the - * SourceStreams of the input DataSources of the associated - * AudioMixer and pushes it to AudioMixingPushBufferStreams - * for audio mixing. - *

- * Pretty much private to AudioMixer but extracted into its own file - * for the sake of clarity. - *

- * - * @author Lyubomir Marinov - */ -class AudioMixerPushBufferStream - extends ControlsAdapter - implements PushBufferStream -{ - /** - * The Logger used by the AudioMixerPushBufferStream class - * and its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(AudioMixerPushBufferStream.class); - - /** - * The factor which scales a short value to an int value. - */ - private static final float INT_TO_SHORT_RATIO - = Integer.MAX_VALUE / (float) Short.MAX_VALUE; - - /** - * The factor which scales an int value to a short value. - */ - private static final float SHORT_TO_INT_RATIO - = Short.MAX_VALUE / (float) Integer.MAX_VALUE; - - /** - * The number of reads from an input stream with no returned samples which - * do not get reported in tracing output. Once the number of such reads from - * an input stream exceeds this limit, it gets reported and the counting is - * restarted. - */ - private static final long TRACE_NON_CONTRIBUTING_READ_COUNT = 0; - - /** - * The AudioMixer which created this - * AudioMixerPushBufferStream. - */ - private final AudioMixer audioMixer; - - /** - * The SourceStreams (in the form of InputStreamDesc so - * that this instance can track back the - * AudioMixingPushBufferDataSource which outputs the mixed audio - * stream and determine whether the associated SourceStream is to - * be included into the mix) from which this instance reads its data. - */ - private InputStreamDesc[] inputStreams; - - /** - * The Object which synchronizes the access to - * {@link #inputStreams}-related members. - */ - private final Object inputStreamsSyncRoot = new Object(); - - /** - * The cache of int arrays managed by this instance for the - * purposes of reducing garbage collection. - */ - private SoftReference> intArrays; - - /** - * The Object which synchronizes the access to {@link #intArrays}. - */ - private final Object intArraysSyncRoot = new Object(); - - /** - * The AudioFormat of the Buffer read during the last read - * from one of the {@link #inputStreams}. Only used for debugging purposes. - */ - private AudioFormat lastReadInputFormat; - - /** - * The AudioFormat of the data this instance outputs. - */ - private final AudioFormat outputFormat; - - /** - * The AudioMixingPushBufferStreams to which this instance pushes - * data for audio mixing. - */ - private final List outputStreams - = new ArrayList(); - - /** - * The BufferTransferHandler through which this instance gets - * notifications from its input SourceStreams that new data is - * available for audio mixing. - */ - private final BufferTransferHandler transferHandler - = new BufferTransferHandler() - { - /** - * The cached Buffer instance to be used during the - * execution of {@link #transferData(PushBufferStream)} in - * order to reduce garbage collection. - */ - private final Buffer buffer = new Buffer(); - - public void transferData(PushBufferStream stream) - { - buffer.setLength(0); - AudioMixerPushBufferStream.this.transferData(buffer); - buffer.setLength(0); - } - }; - - /** - * Initializes a new AudioMixerPushBufferStream instance to output - * data in a specific AudioFormat for a specific - * AudioMixer. - * - * @param audioMixer the AudioMixer which creates this instance and - * for which it is to output data - * @param outputFormat the AudioFormat in which the new instance is - * to output data - */ - public AudioMixerPushBufferStream( - AudioMixer audioMixer, - AudioFormat outputFormat) - { - this.audioMixer = audioMixer; - this.outputFormat = outputFormat; - } - - /** - * Adds a specific AudioMixingPushBufferStream to the collection of - * such streams to which this instance is to push the data for audio mixing - * it reads from its input SourceStreams. - * - * @param outputStream the AudioMixingPushBufferStream to add to - * the collection of such streams to which this instance is to push the data - * for audio mixing it reads from its input SourceStreams - * @throws IOException if outputStream was the first - * AudioMixingPushBufferStream and the AudioMixer failed - * to start - */ - void addOutputStream(AudioMixingPushBufferStream outputStream) - throws IOException - { - if (outputStream == null) - throw new IllegalArgumentException("outputStream"); - - synchronized (outputStreams) - { - if (!outputStreams.contains(outputStream) - && outputStreams.add(outputStream) - && (outputStreams.size() == 1)) - { - boolean started = false; - - try - { - audioMixer.start(this); - started = true; - } - finally - { - if (!started) - outputStreams.remove(outputStream); - } - } - } - } - - public int[] allocateIntArray(int minSize) - { - synchronized (intArraysSyncRoot) - { - List intArrays - = (this.intArrays == null) ? null : this.intArrays.get(); - - if (intArrays != null) - { - Iterator i = intArrays.iterator(); - - while (i.hasNext()) - { - int[] intArray = i.next(); - - if (intArray.length >= minSize) - { - i.remove(); - return intArray; - } - } - } - } - - return new int[minSize]; - } - - public void deallocateIntArray(int[] intArray) - { - if (intArray == null) - return; - - synchronized (intArraysSyncRoot) - { - List intArrays; - - if ((this.intArrays == null) - || ((intArrays = this.intArrays.get()) == null)) - { - intArrays = new LinkedList(); - this.intArrays = new SoftReference>(intArrays); - } - - if (intArrays.size() != 0) - for (int[] element : intArrays) - if (element == intArray) - return; - - intArrays.add(intArray); - } - } - - /** - * Implements {@link SourceStream#endOfStream()}. Delegates to the input - * SourceStreams of this instance. - * - * @return true if all input SourceStreams of this - * instance have reached the end of their content; false, otherwise - */ - public boolean endOfStream() - { - synchronized (inputStreamsSyncRoot) - { - if (inputStreams != null) - for (InputStreamDesc inputStreamDesc : inputStreams) - if (!inputStreamDesc.getInputStream().endOfStream()) - return false; - } - return true; - } - - /** - * Attempts to equalize the length in milliseconds of the buffering - * performed by the inputStreams in order to always read and mix - * one and the same length in milliseconds. - */ - void equalizeInputStreamBufferLength() - { - synchronized (inputStreamsSyncRoot) - { - if ((inputStreams == null) || (inputStreams.length < 1)) - return; - - /* - * The first inputStream is expected to be from the CaptureDevice - * and no custom BufferControl is provided for it so the - * bufferLength is whatever it says. - */ - BufferControl bufferControl = getBufferControl(inputStreams[0]); - long bufferLength - = (bufferControl == null) - ? CachingPushBufferStream.DEFAULT_BUFFER_LENGTH - : bufferControl.getBufferLength(); - - for (int i = 1; i < inputStreams.length; i++) - { - BufferControl inputStreamBufferControl - = getBufferControl(inputStreams[i]); - - if (inputStreamBufferControl != null) - inputStreamBufferControl.setBufferLength(bufferLength); - } - } - } - - /** - * Gets the BufferControl of a specific input stream. The returned - * BufferControl may be available through its input - * DataSource, its transcoding DataSource if any or the - * very input stream. - * - * @param inputStreamDesc an InputStreamDesc which describes the - * input stream and its originating DataSources from which the - * BufferControl is to be retrieved - * @return the BufferControl of the specified input stream found in - * its input DataSource, its transcoding DataSource if any - * or the very input stream if such a control exists; otherwise, - * null - */ - private BufferControl getBufferControl(InputStreamDesc inputStreamDesc) - { - InputDataSourceDesc inputDataSourceDesc - = inputStreamDesc.inputDataSourceDesc; - - // Try the DataSource which directly provides the specified inputStream. - DataSource effectiveInputDataSource - = inputDataSourceDesc.getEffectiveInputDataSource(); - String bufferControlType = BufferControl.class.getName(); - - if (effectiveInputDataSource != null) - { - BufferControl bufferControl - = (BufferControl) - effectiveInputDataSource.getControl(bufferControlType); - - if (bufferControl != null) - return bufferControl; - } - - /* - * If transcoding is taking place and the transcodingDataSource does not - * have a BufferControl, try the inputDataSource which is being - * transcoded. - */ - DataSource inputDataSource = inputDataSourceDesc.inputDataSource; - - if ((inputDataSource != null) - && (inputDataSource != effectiveInputDataSource)) - { - BufferControl bufferControl - = (BufferControl) inputDataSource.getControl(bufferControlType); - - if (bufferControl != null) - return bufferControl; - } - - // If everything else has failed, try the very inputStream. - return - (BufferControl) - inputStreamDesc.getInputStream().getControl(bufferControlType); - } - - /** - * Implements {@link SourceStream#getContentDescriptor()}. Returns a - * ContentDescriptor which describes the content type of this - * instance. - * - * @return a ContentDescriptor which describes the content type of - * this instance - */ - public ContentDescriptor getContentDescriptor() - { - return new ContentDescriptor(audioMixer.getContentType()); - } - - /** - * Implements {@link SourceStream#getContentLength()}. Delegates to the - * input SourceStreams of this instance. - * - * @return the length of the content made available by this instance which - * is the maximum length of the contents made available by its input - * StreamSources - */ - public long getContentLength() - { - long contentLength = 0; - - synchronized (inputStreamsSyncRoot) - { - if (inputStreams != null) - for (InputStreamDesc inputStreamDesc : inputStreams) - { - long inputContentLength - = inputStreamDesc.getInputStream().getContentLength(); - - if (LENGTH_UNKNOWN == inputContentLength) - return LENGTH_UNKNOWN; - if (contentLength < inputContentLength) - contentLength = inputContentLength; - } - } - return contentLength; - } - - /** - * Implements {@link PushBufferStream#getFormat()}. Returns the - * AudioFormat in which this instance was configured to output its - * data. - * - * @return the AudioFormat in which this instance was configured to - * output its data - */ - public AudioFormat getFormat() - { - return outputFormat; - } - - /** - * Gets the SourceStreams (in the form of - * InputStreamDescs) from which this instance reads audio samples. - * - * @return an array of InputStreamDescs which describe the input - * SourceStreams from which this instance reads audio samples - */ - InputStreamDesc[] getInputStreams() - { - synchronized (inputStreamsSyncRoot) - { - return (inputStreams == null) ? null : inputStreams.clone(); - } - } - - /** - * Implements {@link PushBufferStream#read(Buffer)}. Reads audio samples - * from the input SourceStreams of this instance in various - * formats, converts the read audio samples to one and the same format and - * pushes them to the output AudioMixingPushBufferStreams for the - * very audio mixing. - * - * @param buffer the Buffer in which the audio samples read from - * the input SourceStreams are to be returned to the caller - * @throws IOException if any of the input SourceStreams throws - * such an exception while reading from them or anything else goes wrong - */ - public void read(Buffer buffer) - throws IOException - { - InputSampleDesc inputSampleDesc; - int inputStreamCount; - - synchronized (inputStreamsSyncRoot) - { - InputStreamDesc[] thisInputStreams = this.inputStreams; - - if ((thisInputStreams == null) || (thisInputStreams.length == 0)) - return; - else - { - inputSampleDesc = (InputSampleDesc) buffer.getData(); - inputStreamCount = thisInputStreams.length; - if (inputSampleDesc != null) - { - InputStreamDesc[] inputSampleDescInputStreams - = inputSampleDesc.inputStreams; - - if (inputSampleDescInputStreams.length == inputStreamCount) - { - for (int i = 0; i < inputStreamCount; i++) - if (inputSampleDescInputStreams[i] - != thisInputStreams[i]) - { - inputSampleDesc = null; - break; - } - } - else - inputSampleDesc = null; - } - if (inputSampleDesc == null) - { - inputSampleDesc - = new InputSampleDesc( - new int[inputStreamCount][], - thisInputStreams.clone()); - } - } - } - - AudioFormat outputFormat = getFormat(); - int maxInputSampleCount; - - try - { - maxInputSampleCount - = readInputPushBufferStreams(outputFormat, inputSampleDesc); - } - catch (UnsupportedFormatException ufex) - { - IOException ioex = new IOException(); - - ioex.initCause(ufex); - throw ioex; - } - - maxInputSampleCount - = Math.max( - maxInputSampleCount, - readInputPullBufferStreams( - outputFormat, - maxInputSampleCount, - inputSampleDesc)); - - buffer.setData(inputSampleDesc); - buffer.setLength(maxInputSampleCount); - - /* - * Convey the timeStamp so that it can be reported by the Buffers of - * the AudioMixingPushBufferStreams when mixes are read from them. - */ - long timeStamp = inputSampleDesc.getTimeStamp(); - - if (timeStamp != Buffer.TIME_UNKNOWN) - buffer.setTimeStamp(timeStamp); - } - - /** - * Reads audio samples from the input PullBufferStreams of this - * instance and converts them to a specific output AudioFormat. An - * attempt is made to read a specific maximum number of samples from each of - * the PullBufferStreams but the very PullBufferStream may - * not honor the request. - * - * @param outputFormat the AudioFormat in which the audio samples - * read from the PullBufferStreams are to be converted before being - * returned - * @param outputSampleCount the maximum number of audio samples to be read - * from each of the PullBufferStreams but the very - * PullBufferStreams may not honor the request - * @param inputSampleDesc an InputStreamDesc which specifies the - * input streams to be read and the collection of audio samples in which the - * read audio samples are to be returned - * @return the maximum number of audio samples actually read from the input - * PullBufferStreams of this instance - * @throws IOException if anything goes wrong while reading the specified - * input streams - */ - private int readInputPullBufferStreams( - AudioFormat outputFormat, - int outputSampleCount, - InputSampleDesc inputSampleDesc) - throws IOException - { - InputStreamDesc[] inputStreams = inputSampleDesc.inputStreams; - int maxInputSampleCount = 0; - - for (InputStreamDesc inputStream : inputStreams) - if (inputStream.getInputStream() instanceof PullBufferStream) - throw - new UnsupportedOperationException( - AudioMixerPushBufferStream.class.getSimpleName() - + ".readInputPullBufferStreams" - + "(AudioFormat,int,InputSampleDesc)"); - return maxInputSampleCount; - } - - /** - * Reads audio samples from a specific PushBufferStream and - * converts them to a specific output AudioFormat. An attempt is - * made to read a specific maximum number of samples from the specified - * PushBufferStream but the very PushBufferStream may not - * honor the request. - * - * @param inputStreamDesc an InputStreamDesc which specifies the - * input PushBufferStream to read from - * @param outputFormat the AudioFormat to which the samples read - * from inputStream are to be converted before being returned - * @param sampleCount the maximum number of samples which the read operation - * should attempt to read from inputStream but the very - * inputStream may not honor the request - * @param outputBuffer the Buffer into which the array of - * int audio samples read from the specified inputStream - * is to be written - * @throws IOException if anything wrong happens while reading - * inputStream - * @throws UnsupportedFormatException if converting the samples read from - * inputStream to outputFormat fails - */ - private void readInputPushBufferStream( - InputStreamDesc inputStreamDesc, - AudioFormat outputFormat, - int sampleCount, - Buffer outputBuffer) - throws IOException, - UnsupportedFormatException - { - PushBufferStream inputStream - = (PushBufferStream) inputStreamDesc.getInputStream(); - AudioFormat inputStreamFormat - = (AudioFormat) inputStream.getFormat(); - Buffer inputBuffer = inputStreamDesc.getBuffer(true); - - if (sampleCount != 0) - { - Class inputDataType = inputStreamFormat.getDataType(); - - if (Format.byteArray.equals(inputDataType)) - { - Object data = inputBuffer.getData(); - int length - = sampleCount - * (inputStreamFormat.getSampleSizeInBits() / 8); - - if (!(data instanceof byte[]) - || (((byte[]) data).length != length)) - inputBuffer.setData(new byte[length]); - inputBuffer.setLength(0); - inputBuffer.setOffset(0); - } - else - throw new UnsupportedFormatException( - "!Format.getDataType().equals(byte[].class)", - inputStreamFormat); - } - - audioMixer.read( - inputStream, - inputBuffer, - inputStreamDesc.inputDataSourceDesc.inputDataSource); - - /* - * If the media is to be discarded, don't even bother with the - * checks and the conversion. - */ - if (inputBuffer.isDiscard()) - { - outputBuffer.setDiscard(true); - return; - } - - int inputLength = inputBuffer.getLength(); - - if (inputLength <= 0) - { - outputBuffer.setDiscard(true); - return; - } - - AudioFormat inputFormat = (AudioFormat) inputBuffer.getFormat(); - - if (inputFormat == null) - inputFormat = inputStreamFormat; - - if (logger.isTraceEnabled() - && (lastReadInputFormat != null) - && !lastReadInputFormat.matches(inputFormat)) - { - lastReadInputFormat = inputFormat; - logger.trace( - "Read inputSamples in different format " - + lastReadInputFormat); - } - - int inputFormatSigned = inputFormat.getSigned(); - - if ((inputFormatSigned != AudioFormat.SIGNED) - && (inputFormatSigned != Format.NOT_SPECIFIED)) - throw - new UnsupportedFormatException( - "AudioFormat.getSigned()", - inputFormat); - - int inputChannels = inputFormat.getChannels(); - int outputChannels = outputFormat.getChannels(); - - if ((inputChannels != outputChannels) - && (inputChannels != Format.NOT_SPECIFIED) - && (outputChannels != Format.NOT_SPECIFIED)) - { - logger.error( - "Read inputFormat with channels " - + inputChannels - + " while expected outputFormat channels is " - + outputChannels); - throw new UnsupportedFormatException( - "AudioFormat.getChannels()", - inputFormat); - } - - // Warn about different sampleRates. - double inputSampleRate = inputFormat.getSampleRate(); - double outputSampleRate = outputFormat.getSampleRate(); - - if (inputSampleRate != outputSampleRate) - { - logger.warn( - "Read inputFormat with sampleRate " - + inputSampleRate - + " while expected outputFormat sampleRate is " - + outputSampleRate); - } - - Object inputData = inputBuffer.getData(); - - if (inputData == null) - { - outputBuffer.setDiscard(true); - } - else if (inputData instanceof byte[]) - { - int inputSampleSizeInBits = inputFormat.getSampleSizeInBits(); - int outputSampleSizeInBits = outputFormat.getSampleSizeInBits(); - - if (logger.isTraceEnabled() - && (inputSampleSizeInBits != outputSampleSizeInBits)) - { - logger.trace( - "Read inputFormat with sampleSizeInBits " - + inputSampleSizeInBits - + ". Will convert to sampleSizeInBits " - + outputSampleSizeInBits); - } - - byte[] inputSamples = (byte[]) inputData; - int outputLength; - int[] outputSamples; - - switch (inputSampleSizeInBits) - { - case 16: - outputLength = inputLength / 2; - outputSamples - = validateIntArraySize(outputBuffer, outputLength); - for (int i = 0; i < outputLength; i++) - { - int sample = ArrayIOUtils.readInt16(inputSamples, i * 2); - - switch (outputSampleSizeInBits) - { - case 16: - break; - case 32: - sample = Math.round(sample * INT_TO_SHORT_RATIO); - break; - case 8: - case 24: - default: - throw new UnsupportedFormatException( - "AudioFormat.getSampleSizeInBits()", - outputFormat); - } - - outputSamples[i] = sample; - } - break; - case 32: - outputLength = inputSamples.length / 4; - outputSamples - = validateIntArraySize(outputBuffer, outputLength); - for (int i = 0; i < outputLength; i++) - { - int sample = readInt(inputSamples, i * 4); - - switch (outputSampleSizeInBits) - { - case 16: - sample = Math.round(sample * SHORT_TO_INT_RATIO); - break; - case 32: - break; - case 8: - case 24: - default: - throw new UnsupportedFormatException( - "AudioFormat.getSampleSizeInBits()", - outputFormat); - } - - outputSamples[i] = sample; - } - break; - case 8: - case 24: - default: - throw new UnsupportedFormatException( - "AudioFormat.getSampleSizeInBits()", - inputFormat); - } - - outputBuffer.setFlags(inputBuffer.getFlags()); - outputBuffer.setFormat(outputFormat); - outputBuffer.setLength(outputLength); - outputBuffer.setOffset(0); - outputBuffer.setTimeStamp(inputBuffer.getTimeStamp()); - } - else - { - throw new UnsupportedFormatException( - "Format.getDataType().equals(" + inputData.getClass() + ")", - inputFormat); - } - } - - /** - * Reads audio samples from the input PushBufferStreams of this - * instance and converts them to a specific output AudioFormat. - * - * @param outputFormat the AudioFormat in which the audio samples - * read from the PushBufferStreams are to be converted before being - * returned - * @param inputSampleDesc an InputSampleDesc which specifies the - * input streams to be read and the collection of audio samples in which - * the read audio samples are to be returned - * @return the maximum number of audio samples actually read from the input - * PushBufferStreams of this instance - * @throws IOException if anything wrong happens while reading the specified - * input streams - * @throws UnsupportedFormatException if any of the input streams provides - * media in a format different than outputFormat - */ - private int readInputPushBufferStreams( - AudioFormat outputFormat, - InputSampleDesc inputSampleDesc) - throws IOException, - UnsupportedFormatException - { - InputStreamDesc[] inputStreams = inputSampleDesc.inputStreams; - Buffer buffer = inputSampleDesc.getBuffer(true); - int maxInputSampleCount = 0; - int[][] inputSamples = inputSampleDesc.inputSamples; - - for (int i = 0; i < inputStreams.length; i++) - { - InputStreamDesc inputStreamDesc = inputStreams[i]; - SourceStream inputStream = inputStreamDesc.getInputStream(); - - if (inputStream instanceof PushBufferStream) - { - buffer.setDiscard(false); - buffer.setLength(0); - readInputPushBufferStream( - inputStreamDesc, outputFormat, maxInputSampleCount, - buffer); - - int sampleCount; - int[] samples; - - if (buffer.isDiscard()) - { - sampleCount = 0; - samples = null; - } - else - { - sampleCount = buffer.getLength(); - if (sampleCount <= 0) - { - sampleCount = 0; - samples = null; - } - else - { - samples = (int[]) buffer.getData(); - } - } - - if (sampleCount == 0) - { - if ((TRACE_NON_CONTRIBUTING_READ_COUNT > 0) - && logger.isTraceEnabled()) - { - inputStreamDesc.nonContributingReadCount++; - if (inputStreamDesc.nonContributingReadCount - >= TRACE_NON_CONTRIBUTING_READ_COUNT) - { - logger.trace( - "Failed to read actual inputSamples more than " - + inputStreamDesc - .nonContributingReadCount - + " times from inputStream with hash code " - + inputStreamDesc - .getInputStream().hashCode()); - inputStreamDesc.nonContributingReadCount = 0; - } - } - } - else - { - /* - * The int array with the samples will be used via - * inputSamples so the buffer cannot use it anymore. - */ - buffer.setData(null); - - /* - * If the samples array has more elements than sampleCount, - * the elements in question may contain stale samples. - */ - if (samples.length > sampleCount) - Arrays.fill(samples, sampleCount, samples.length, 0); - - inputSamples[i] = samples; - - if (maxInputSampleCount < samples.length) - maxInputSampleCount = samples.length; - - /* - * Convey the timeStamp so that it can be set to the Buffers - * of the AudioMixingPushBufferStreams when mixes are read - * from them. Since the inputStreams will report different - * timeStamps, only use the first meaningful timestamp for - * now. - */ - if (inputSampleDesc.getTimeStamp() == Buffer.TIME_UNKNOWN) - inputSampleDesc.setTimeStamp(buffer.getTimeStamp()); - - continue; - } - } - - inputSamples[i] = null; - } - return maxInputSampleCount; - } - - /** - * Reads an integer from a specific series of bytes starting the reading at - * a specific offset in it. - * - * @param input the series of bytes to read an integer from - * @param inputOffset the offset in input at which the reading of - * the integer is to start - * @return an integer read from the specified series of bytes starting at - * the specified offset in it - */ - private static int readInt(byte[] input, int inputOffset) - { - return - (input[inputOffset + 3] << 24) - | ((input[inputOffset + 2] & 0xFF) << 16) - | ((input[inputOffset + 1] & 0xFF) << 8) - | (input[inputOffset] & 0xFF); - } - - /** - * Removes a specific AudioMixingPushBufferStream from the - * collection of such streams to which this instance pushes the data for - * audio mixing it reads from its input SourceStreams. - * - * @param outputStream the AudioMixingPushBufferStream to remove - * from the collection of such streams to which this instance pushes the - * data for audio mixing it reads from its input SourceStreams - * @throws IOException if outputStream was the last - * AudioMixingPushBufferStream and the AudioMixer failed - * to stop - */ - void removeOutputStream(AudioMixingPushBufferStream outputStream) - throws IOException - { - synchronized (outputStreams) - { - if ((outputStream != null) - && outputStreams.remove(outputStream) - && outputStreams.isEmpty()) - audioMixer.stop(this); - } - } - - /** - * Pushes a copy of a specific set of input audio samples to a specific - * AudioMixingPushBufferStream for audio mixing. Audio samples read - * from input DataSources which the - * AudioMixingPushBufferDataSource owner of the specified - * AudioMixingPushBufferStream has specified to not be included in - * the output mix are not pushed to the - * AudioMixingPushBufferStream. - * - * @param outputStream the AudioMixingPushBufferStream to push the - * specified set of audio samples to - * @param inputSampleDesc the set of audio samples to be pushed to - * outputStream for audio mixing - * @param maxInputSampleCount the maximum number of audio samples available - * in inputSamples - */ - private void setInputSamples( - AudioMixingPushBufferStream outputStream, - InputSampleDesc inputSampleDesc, - int maxInputSampleCount) - { - int[][] inputSamples = inputSampleDesc.inputSamples; - InputStreamDesc[] inputStreams = inputSampleDesc.inputStreams; - - inputSamples = inputSamples.clone(); - - CaptureDevice captureDevice = audioMixer.captureDevice; - AudioMixingPushBufferDataSource outputDataSource - = outputStream.getDataSource(); - boolean outputDataSourceIsSendingDTMF - = (captureDevice instanceof AudioMixingPushBufferDataSource) - ? outputDataSource.isSendingDTMF() - : false; - boolean outputDataSourceIsMute = outputDataSource.isMute(); - - for (int i = 0; i < inputSamples.length; i++) - { - InputStreamDesc inputStreamDesc = inputStreams[i]; - DataSource inputDataSource - = inputStreamDesc.inputDataSourceDesc.inputDataSource; - - if (outputDataSourceIsSendingDTMF - && (inputDataSource == captureDevice)) - { - PushBufferStream inputStream - = (PushBufferStream) inputStreamDesc.getInputStream(); - AudioFormat inputStreamFormat - = (AudioFormat) inputStream.getFormat(); - - double sampleRate = inputStreamFormat.getSampleRate(); - int sampleSizeInBits = inputStreamFormat.getSampleSizeInBits(); - - // Generate the inband DTMF signal. - inputSamples[i] - = outputDataSource.getNextToneSignal( - sampleRate, - sampleSizeInBits); - if (maxInputSampleCount < inputSamples[i].length) - maxInputSampleCount = inputSamples[i].length; - } - else if (outputDataSource.equals( - inputStreamDesc.getOutputDataSource()) - || (outputDataSourceIsMute - && (inputDataSource == captureDevice))) - { - inputSamples[i] = null; - } - } - - outputStream.setInputSamples( - inputSamples, - maxInputSampleCount, - inputSampleDesc.getTimeStamp()); - } - - /** - * Sets the SourceStreams (in the form of InputStreamDesc) - * from which this instance is to read audio samples and push them to the - * AudioMixingPushBufferStreams for audio mixing. - * - * @param inputStreams the SourceStreams (in the form of - * InputStreamDesc) from which this instance is to read audio - * samples and push them to the AudioMixingPushBufferStreams for - * audio mixing - */ - void setInputStreams(Collection inputStreams) - { - InputStreamDesc[] oldValue; - InputStreamDesc[] newValue - = (null == inputStreams) - ? null - : inputStreams.toArray( - new InputStreamDesc[inputStreams.size()]); - - synchronized (inputStreamsSyncRoot) - { - oldValue = this.inputStreams; - - this.inputStreams = newValue; - } - - boolean valueIsChanged = !Arrays.equals(oldValue, newValue); - - if (valueIsChanged) - { - if (oldValue != null) - setTransferHandler(oldValue, null); - - if (newValue == null) - return; - - boolean skippedForTransferHandler = false; - - for (InputStreamDesc inputStreamDesc : newValue) - { - SourceStream inputStream = inputStreamDesc.getInputStream(); - - if (!(inputStream instanceof PushBufferStream)) - continue; - if (!skippedForTransferHandler) - { - skippedForTransferHandler = true; - continue; - } - if (!(inputStream instanceof CachingPushBufferStream)) - { - PushBufferStream cachingInputStream - = new CachingPushBufferStream( - (PushBufferStream) inputStream); - - inputStreamDesc.setInputStream(cachingInputStream); - if (logger.isTraceEnabled()) - logger.trace( - "Created CachingPushBufferStream" - + " with hashCode " - + cachingInputStream.hashCode() - + " for inputStream with hashCode " - + inputStream.hashCode()); - } - } - - setTransferHandler(newValue, transferHandler); - equalizeInputStreamBufferLength(); - - if (logger.isTraceEnabled()) - { - int oldValueLength = (oldValue == null) ? 0 : oldValue.length; - int newValueLength = (newValue == null) ? 0 : newValue.length; - int difference = newValueLength - oldValueLength; - - if (difference > 0) - logger.trace( - "Added " - + difference - + " inputStream(s) and the total is " - + newValueLength); - else if (difference < 0) - logger.trace( - "Removed " - + difference - + " inputStream(s) and the total is " - + newValueLength); - } - } - } - - /** - * Implements - * {@link PushBufferStream#setTransferHandler(BufferTransferHandler)}. - * Because this instance pushes data to multiple output - * AudioMixingPushBufferStreams, a single - * BufferTransferHandler is not sufficient and thus this method is - * unsupported and throws UnsupportedOperationException. - * - * @param transferHandler the BufferTransferHandler to be notified - * by this PushBufferStream when media is available for reading - */ - public void setTransferHandler(BufferTransferHandler transferHandler) - { - throw - new UnsupportedOperationException( - AudioMixerPushBufferStream.class.getSimpleName() - + ".setTransferHandler(BufferTransferHandler)"); - } - - /** - * Sets a specific BufferTransferHandler to a specific collection - * of SourceStreams (in the form of InputStreamDesc) - * abstracting the differences among the various types of - * SourceStreams. - * - * @param inputStreams the input SourceStreams to which the - * specified BufferTransferHandler is to be set - * @param transferHandler the BufferTransferHandler to be set to - * the specified inputStreams - */ - private void setTransferHandler( - InputStreamDesc[] inputStreams, - BufferTransferHandler transferHandler) - { - if ((inputStreams == null) || (inputStreams.length <= 0)) - return; - - boolean transferHandlerIsSet = false; - - for (InputStreamDesc inputStreamDesc : inputStreams) - { - SourceStream inputStream = inputStreamDesc.getInputStream(); - - if (inputStream instanceof PushBufferStream) - { - BufferTransferHandler inputStreamTransferHandler; - PushBufferStream inputPushBufferStream - = (PushBufferStream) inputStream; - - if (transferHandler == null) - inputStreamTransferHandler = null; - else if (transferHandlerIsSet) - inputStreamTransferHandler = new BufferTransferHandler() - { - public void transferData(PushBufferStream stream) - { - /* - * Do nothing because we don't want the associated - * PushBufferStream to cause the transfer of data - * from this AudioMixerPushBufferStream. - */ - } - }; - else - inputStreamTransferHandler - = new StreamSubstituteBufferTransferHandler( - transferHandler, - inputPushBufferStream, - this); - - inputPushBufferStream - .setTransferHandler(inputStreamTransferHandler); - - transferHandlerIsSet = true; - } - } - } - - /** - * Reads audio samples from the input SourceStreams of this - * instance and pushes them to its output - * AudioMixingPushBufferStreams for audio mixing. - * - * @param buffer the cached Buffer instance to be used during the - * execution of the method in order to reduce garbage collection. The - * length of the buffer will be reset to 0 before - * and after the execution of the method. - */ - protected void transferData(Buffer buffer) - { - try - { - read(buffer); - } - catch (IOException ex) - { - throw new UndeclaredThrowableException(ex); - } - - InputSampleDesc inputSampleDesc = (InputSampleDesc) buffer.getData(); - int[][] inputSamples = inputSampleDesc.inputSamples; - int maxInputSampleCount = buffer.getLength(); - - if ((inputSamples == null) - || (inputSamples.length == 0) - || (maxInputSampleCount <= 0)) - return; - - AudioMixingPushBufferStream[] outputStreams; - - synchronized (this.outputStreams) - { - outputStreams - = this.outputStreams.toArray( - new AudioMixingPushBufferStream[ - this.outputStreams.size()]); - } - for (AudioMixingPushBufferStream outputStream : outputStreams) - setInputSamples(outputStream, inputSampleDesc, maxInputSampleCount); - - /* - * The input samples have already been delivered to the output streams - * and are no longer necessary. - */ - for (int i = 0; i < inputSamples.length; i++) - { - deallocateIntArray(inputSamples[i]); - inputSamples[i] = null; - } - } - - private int[] validateIntArraySize(Buffer buffer, int newSize) - { - Object data = buffer.getData(); - int[] intArray; - - if (data instanceof int[]) - { - intArray = (int[]) data; - if (intArray.length < newSize) - { - deallocateIntArray(intArray); - intArray = null; - } - } - else - intArray = null; - if (intArray == null) - { - intArray = allocateIntArray(newSize); - buffer.setData(intArray); - } - return intArray; - } - - /** - * Describes a specific set of audio samples read from a specific set of - * input streams specified by their InputStreamDescs. - */ - private static class InputSampleDesc - { - /** - * The Buffer into which media data is to be read from - * {@link #inputStreams}. - */ - private SoftReference buffer; - - /** - * The set of audio samples read from {@link #inputStreams}. - */ - public final int[][] inputSamples; - - /** - * The set of input streams from which {@link #inputSamples} were read. - */ - public final InputStreamDesc[] inputStreams; - - /** - * The time stamp of inputSamples to be reported in the - * Buffers of the AudioMixingPushBufferStreams when - * mixes are read from them. - */ - private long timeStamp = Buffer.TIME_UNKNOWN; - - /** - * Initializes a new InputSampleDesc instance which is to - * describe a specific set of audio samples read from a specific set of - * input streams specified by their InputStreamDescs. - * - * @param inputSamples the set of audio samples read from - * inputStreams - * @param inputStreams the set of input streams from which - * inputSamples were read - */ - public InputSampleDesc( - int[][] inputSamples, - InputStreamDesc[] inputStreams) - { - this.inputSamples = inputSamples; - this.inputStreams = inputStreams; - } - - /** - * Gets the Buffer into which media data is to be read from the - * input streams associated with this instance. - * - * @param create the indicator which determines whether the - * Buffer is to be created in case it does not exist - * @return the Buffer into which media data is to be read from - * the input streams associated with this instance - */ - public Buffer getBuffer(boolean create) - { - Buffer buffer = (this.buffer == null) ? null : this.buffer.get(); - - if ((buffer == null) && create) - { - buffer = new Buffer(); - setBuffer(buffer); - } - return buffer; - } - - /** - * Gets the time stamp of inputSamples to be reported in the - * Buffers of the AudioMixingPushBufferStreams when - * mixes are read from them. - * - * @return the time stamp of inputSamples to be reported in the - * Buffers of the AudioMixingPushBufferStreams when - * mixes are read from them - */ - public long getTimeStamp() - { - return timeStamp; - } - - /** - * Sets the Buffer into which media data is to be read from the - * input streams associated with this instance. - * - * @param buffer the Buffer into which media data is to be read - * from the input streams associated with this instance - */ - public void setBuffer(Buffer buffer) - { - this.buffer - = (buffer == null) ? null : new SoftReference(buffer); - } - - /** - * Sets the time stamp of inputSamples to be reported in the - * Buffers of the AudioMixingPushBufferStreams when - * mixes are read from them. - * - * @param timeStamp the time stamp of inputSamples to be - * reported in the Buffers of the - * AudioMixingPushBufferStreams when mixes are read from them - */ - public void setTimeStamp(long timeStamp) - { - if (this.timeStamp == Buffer.TIME_UNKNOWN) - this.timeStamp = timeStamp; - else - { - /* - * Setting the timeStamp more than once does not make sense - * because the inputStreams will report different timeStamps so - * only one should be picked up where the very reading from - * inputStreams takes place. - */ - throw new IllegalStateException("timeStamp"); - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/conference/AudioMixingPushBufferDataSource.java b/src/net/java/sip/communicator/impl/neomedia/conference/AudioMixingPushBufferDataSource.java deleted file mode 100644 index b7587c687..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/conference/AudioMixingPushBufferDataSource.java +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.conference; - -import java.io.*; -import java.lang.reflect.*; -import java.util.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.control.*; -import net.java.sip.communicator.impl.neomedia.protocol.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.util.*; - -/** - * Represents a PushBufferDataSource which provides a single - * PushBufferStream containing the result of the audio mixing of - * DataSources. - * - * @author Lubomir Marinov - */ -public class AudioMixingPushBufferDataSource - extends PushBufferDataSource - implements CaptureDevice, - MuteDataSource, - InbandDTMFDataSource -{ - - /** - * The Logger used by the AudioMixingPushBufferDataSource - * class and its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(AudioMixingPushBufferDataSource.class); - - /** - * The AudioMixer performing the audio mixing, managing the input - * DataSources and pushing the data of this output - * PushBufferDataSource. - */ - private final AudioMixer audioMixer; - - /** - * The indicator which determines whether this DataSource is - * connected. - */ - private boolean connected; - - /** - * The one and only PushBufferStream this - * PushBufferDataSource provides to its clients and containing the - * result of the audio mixing performed by audioMixer. - */ - private AudioMixingPushBufferStream outputStream; - - /** - * The indicator which determines whether this DataSource is - * started. - */ - private boolean started; - - /** - * The indicator which determines whether this DataSource is set - * to transmit "silence" instead of the actual media. - */ - private boolean mute = false; - - /** - * The tones to send via inband DTMF, if not empty. - */ - private LinkedList tones = new LinkedList(); - - /** - * Initializes a new AudioMixingPushBufferDataSource instance which - * gives access to the result of the audio mixing performed by a specific - * AudioMixer. - * - * @param audioMixer the AudioMixer performing audio mixing, - * managing the input DataSources and pushing the data of the new - * output PushBufferDataSource - */ - public AudioMixingPushBufferDataSource(AudioMixer audioMixer) - { - this.audioMixer = audioMixer; - } - - /** - * Adds a new input DataSource to be mixed by the associated - * AudioMixer of this instance and to not have its audio - * contributions included in the mixing output represented by this - * DataSource. - * - * @param inputDataSource a DataSource to be added for mixing to - * the AudioMixer associate with this instance and to not have its - * audio contributions included in the mixing output represented by this - * DataSource - */ - public void addInputDataSource(DataSource inputDataSource) - { - audioMixer.addInputDataSource(inputDataSource, this); - } - - /** - * Implements {@link DataSource#connect()}. Lets the AudioMixer - * know that one of its output PushBufferDataSources has been - * connected and marks this DataSource as connected. - * - * @throws IOException if the AudioMixer fails to connect - */ - public synchronized void connect() - throws IOException - { - if (!connected) - { - audioMixer.connect(); - connected = true; - } - } - - /** - * Implements {@link DataSource#disconnect()}. Marks this - * DataSource as disconnected and notifies the AudioMixer - * that one of its output PushBufferDataSources has been - * disconnected. - */ - public synchronized void disconnect() - { - try - { - stop(); - } - catch (IOException ioex) - { - throw new UndeclaredThrowableException(ioex); - } - - if (connected) - { - outputStream = null; - connected = false; - - audioMixer.disconnect(); - } - } - - /** - * Gets the BufferControl available for this DataSource. - * Delegates to the AudioMixer because this instance is just a - * facet to it. - * - * @return the BufferControl available for this DataSource - */ - private BufferControl getBufferControl() - { - return audioMixer.getBufferControl(); - } - - /** - * Implements {@link CaptureDevice#getCaptureDeviceInfo()}. Delegates to the - * associated AudioMixer because it knows which - * CaptureDevice is being wrapped. - * - * @return the CaptureDeviceInfo of the CaptureDevice of - * the AudioMixer - */ - public CaptureDeviceInfo getCaptureDeviceInfo() - { - return audioMixer.getCaptureDeviceInfo(); - } - - /** - * Implements {@link DataSource#getContentType()}. Delegates to the - * associated AudioMixer because it manages the inputs and knows - * their characteristics. - * - * @return a String value which represents the type of the content - * being made available by this DataSource i.e. the associated - * AudioMixer - */ - public String getContentType() - { - return audioMixer.getContentType(); - } - - /** - * Implements {@link DataSource#getControl(String)}. - * - * @param controlType a String value which names the type of the - * control of this instance to be retrieved - * @return an Object which represents the control of this instance - * with the specified type if such a control is available; otherwise, - * null - */ - public Object getControl(String controlType) - { - return AbstractControls.getControl(this, controlType); - } - - /** - * Implements {@link DataSource#getControls()}. Gets an array of - * Objects which represent the controls available for this - * DataSource. - * - * @return an array of Objects which represent the controls - * available for this DataSource - */ - public Object[] getControls() - { - BufferControl bufferControl = getBufferControl(); - FormatControl[] formatControls = getFormatControls(); - - if (bufferControl == null) - return formatControls; - else if ((formatControls == null) || (formatControls.length < 1)) - return new Object[] { bufferControl }; - else - { - Object[] controls = new Object[1 + formatControls.length]; - - controls[0] = bufferControl; - System - .arraycopy( - formatControls, - 0, - controls, - 1, - formatControls.length); - return controls; - } - } - - /** - * Implements {@link DataSource#getDuration()}. Delegates to the associated - * AudioMixer because it manages the inputs and knows their - * characteristics. - * - * @return a Time value which represents the duration of the media - * being made available through this DataSource - */ - public Time getDuration() - { - return audioMixer.getDuration(); - } - - /** - * Implements {@link CaptureDevice#getFormatControls()}. Delegates to the - * associated AudioMixer because it knows which - * CaptureDevice is being wrapped. - * - * @return an array of FormatControls of the CaptureDevice - * of the associated AudioMixer - */ - public FormatControl[] getFormatControls() - { - return audioMixer.getFormatControls(); - } - - /** - * Implements {@link PushBufferDataSource#getStreams()}. Gets a - * PushBufferStream which reads data from the associated - * AudioMixer and mixes its inputs. - * - * @return an array with a single PushBufferStream which reads data - * from the associated AudioMixer and mixes its inputs if this - * DataSource is connected; otherwise, an empty array - */ - public synchronized PushBufferStream[] getStreams() - { - if (connected && (outputStream == null)) - { - AudioMixerPushBufferStream audioMixerOutputStream - = audioMixer.getOutputStream(); - - if (audioMixerOutputStream != null) - { - outputStream - = new AudioMixingPushBufferStream( - audioMixerOutputStream, - this); - if (started) - try - { - outputStream.start(); - } - catch (IOException ioex) - { - logger - .error( - "Failed to start " - + outputStream.getClass().getSimpleName() - + " with hashCode " - + outputStream.hashCode(), - ioex); - } - } - } - return - (outputStream == null) - ? new PushBufferStream[0] - : new PushBufferStream[] { outputStream }; - } - - /** - * Implements {@link DataSource#start()}. Starts the output - * PushBufferStream of this DataSource (if it exists) and - * notifies the AudioMixer that one of its output - * PushBufferDataSources has been started. - * - * @throws IOException if anything wrong happens while starting the output - * PushBufferStream of this DataSource - */ - public synchronized void start() - throws IOException - { - if (!started) - { - started = true; - if (outputStream != null) - outputStream.start(); - } - } - - /** - * Implements {@link DataSource#stop()}. Notifies the AudioMixer - * that one of its output PushBufferDataSources has been stopped - * and stops the output PushBufferStream of this - * DataSource (if it exists). - * - * @throws IOException if anything wrong happens while stopping the output - * PushBufferStream of this DataSource - */ - public synchronized void stop() - throws IOException - { - if (started) - { - started = false; - if (outputStream != null) - outputStream.stop(); - } - } - - /** - * Determines whether this DataSource is mute. - * - * @return true if this DataSource is mute; otherwise, - * false - */ - public boolean isMute() - { - return this.mute; - } - - /** - * Sets the mute state of this DataSource. - * - * @param mute true to mute this DataSource; otherwise, - * false - */ - public void setMute(boolean mute) - { - if (this.mute != mute) - { - this.mute = mute; - } - } - - /** - * Adds a new inband DTMF tone to send. - * - * @param tone the DTMF tone to send. - */ - public void addDTMF(DTMFInbandTone tone) - { - this.tones.add(tone); - } - - /** - * Determines whether this DataSource sends a DTMF tone. - * - * @return true if this DataSource is sending a DTMF tone; - * otherwise, false. - */ - public boolean isSendingDTMF() - { - return !this.tones.isEmpty(); - } - - /** - * Gets the next inband DTMF tone signal. - * - * @param samplingFrequency The sampling frequency (codec clock rate) in Hz - * of the stream which will encapsulate this signal. - * @param sampleSizeInBits The size of each sample (8 for a byte, 16 for a - * short and 32 for an int) - * - * @return The data array containing the DTMF signal. - */ - public int[] getNextToneSignal( - double samplingFrequency, - int sampleSizeInBits) - { - DTMFInbandTone tone = tones.poll(); - return tone.getAudioSamples(samplingFrequency, sampleSizeInBits); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/conference/AudioMixingPushBufferStream.java b/src/net/java/sip/communicator/impl/neomedia/conference/AudioMixingPushBufferStream.java deleted file mode 100644 index 4b09161cd..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/conference/AudioMixingPushBufferStream.java +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.conference; - -import java.io.*; - -import javax.media.*; -import javax.media.format.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.control.*; -import net.java.sip.communicator.util.*; - -/** - * Represents a PushBufferStream containing the result of the audio - * mixing of DataSources. - * - * @author Lyubomir Marinov - */ -public class AudioMixingPushBufferStream - extends ControlsAdapter - implements PushBufferStream -{ - - /** - * The Logger used by the AudioMixingPushBufferStream - * class and its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(AudioMixingPushBufferStream.class); - - /** - * The AudioMixerPushBufferStream which reads data from the input - * DataSources and pushes it to this instance to be mixed. - */ - private final AudioMixerPushBufferStream audioMixerStream; - - /** - * The AudioMixingPushBufferDataSource which created and owns this - * instance and defines the input data which is to not be mixed in the - * output of this PushBufferStream. - */ - private final AudioMixingPushBufferDataSource dataSource; - - /** - * The collection of input audio samples still not mixed and read through - * this AudioMixingPushBufferStream. - */ - private int[][] inputSamples; - - /** - * The maximum number of per-stream audio samples available through - * inputSamples. - */ - private int maxInputSampleCount; - - /** - * The Object which synchronizes the access to the data to be read - * from this PushBufferStream i.e. to {@link #inputSamples}, - * {@link #maxInputSampleCount} and {@link #timeStamp}. - */ - private final Object readSyncRoot = new Object(); - - /** - * The time stamp of {@link #inputSamples} to be reported in the specified - * Buffer when data is read from this instance. - */ - private long timeStamp; - - /** - * The BufferTransferHandler through which this - * PushBufferStream notifies its clients that new data is available - * for reading. - */ - private BufferTransferHandler transferHandler; - - /** - * Initializes a new AudioMixingPushBufferStream mixing the - * input data of a specific AudioMixerPushBufferStream and - * excluding from the mix the audio contributions of a specific - * AudioMixingPushBufferDataSource. - * - * @param audioMixerStream the AudioMixerPushBufferStream reading - * data from input DataSources and to push it to the new - * AudioMixingPushBufferStream - * @param dataSource the AudioMixingPushBufferDataSource which has - * requested the initialization of the new instance and which defines the - * input data to not be mixed in the output of the new instance - */ - AudioMixingPushBufferStream( - AudioMixerPushBufferStream audioMixerStream, - AudioMixingPushBufferDataSource dataSource) - { - this.audioMixerStream = audioMixerStream; - this.dataSource = dataSource; - } - - /** - * Implements {@link SourceStream#endOfStream()}. Delegates to the wrapped - * AudioMixerPushBufferStream because this instance is just a facet - * to it. - * - * @return true if this SourceStream has reached the end - * of the media it makes available; otherwise, false - */ - public boolean endOfStream() - { - /* - * TODO If the inputSamples haven't been consumed yet, don't report the - * end of this stream even if the wrapped stream has reached its end. - */ - return audioMixerStream.endOfStream(); - } - - /** - * Implements {@link SourceStream#getContentDescriptor()}. Delegates to the - * wrapped AudioMixerPushBufferStream because this instance is just - * a facet to it. - * - * @return a ContentDescriptor which describes the content being - * made available by this SourceStream - */ - public ContentDescriptor getContentDescriptor() - { - return audioMixerStream.getContentDescriptor(); - } - - /** - * Implements {@link SourceStream#getContentLength()}. Delegates to the - * wrapped AudioMixerPushBufferStream because this instance is just - * a facet to it. - * - * @return the length of the media being made available by this - * SourceStream - */ - public long getContentLength() - { - return audioMixerStream.getContentLength(); - } - - /** - * Gets the AudioMixingPushBufferDataSource which created and owns - * this instance and defines the input data which is to not be mixed in the - * output of this PushBufferStream. - * - * @return the AudioMixingPushBufferDataSource which created and - * owns this instance and defines the input data which is to not be mixed in - * the output of this PushBufferStream - */ - public AudioMixingPushBufferDataSource getDataSource() - { - return dataSource; - } - - /** - * Implements {@link PushBufferStream#getFormat()}. Delegates to the wrapped - * AudioMixerPushBufferStream because this instance is just a facet - * to it. - * - * @return the Format of the audio being made available by this - * PushBufferStream - */ - public AudioFormat getFormat() - { - return audioMixerStream.getFormat(); - } - - /** - * Gets the maximum possible value for an audio sample of a specific - * AudioFormat. - * - * @param outputFormat the AudioFormat of which to get the maximum - * possible value for an audio sample - * @return the maximum possible value for an audio sample of the specified - * AudioFormat - * @throws UnsupportedFormatException if the specified outputFormat - * is not supported by the underlying implementation - */ - private static int getMaxOutputSample(AudioFormat outputFormat) - throws UnsupportedFormatException - { - switch(outputFormat.getSampleSizeInBits()) - { - case 8: - return Byte.MAX_VALUE; - case 16: - return Short.MAX_VALUE; - case 32: - return Integer.MAX_VALUE; - case 24: - default: - throw - new UnsupportedFormatException( - "Format.getSampleSizeInBits()", - outputFormat); - } - } - - /** - * Mixes as in audio mixing a specified collection of audio sample sets and - * returns the resulting mix audio sample set in a specific - * AudioFormat. - * - * @param inputSamples the collection of audio sample sets to be mixed into - * one audio sample set in the sense of audio mixing - * @param outputFormat the AudioFormat in which the resulting mix - * audio sample set is to be produced - * @param outputSampleCount the size of the resulting mix audio sample set - * to be produced - * @return the resulting audio sample set of the audio mixing of the - * specified input audio sample sets - */ - private static int[] mix( - int[][] inputSamples, - AudioFormat outputFormat, - int outputSampleCount) - { - int[] outputSamples = new int[outputSampleCount]; - - /* - * The trivial case of performing audio mixing the audio of a single - * stream. Then there is nothing to mix and the input becomes the - * output. - */ - if (inputSamples.length == 1) - { - int[] inputStreamSamples = inputSamples[0]; - - if (inputStreamSamples != null) - { - System.arraycopy( - inputStreamSamples, 0, - outputSamples, 0, - inputStreamSamples.length); - } - return outputSamples; - } - - int maxOutputSample; - - try - { - maxOutputSample = getMaxOutputSample(outputFormat); - } - catch (UnsupportedFormatException ufex) - { - throw new UnsupportedOperationException(ufex); - } - - for (int[] inputStreamSamples : inputSamples) - { - if (inputStreamSamples == null) - continue; - - int inputStreamSampleCount = inputStreamSamples.length; - - if (inputStreamSampleCount <= 0) - continue; - - for (int i = 0; i < inputStreamSampleCount; i++) - { - int inputStreamSample = inputStreamSamples[i]; - int outputSample = outputSamples[i]; - - outputSamples[i] - = inputStreamSample - + outputSample - - Math.round( - inputStreamSample - * (outputSample - / (float) maxOutputSample)); - } - } - return outputSamples; - } - - /** - * Implements {@link PushBufferStream#read(Buffer)}. If - * inputSamples are available, mixes them and writes the mix to the - * specified Buffer performing the necessary data type conversions. - * - * @param buffer the Buffer to receive the data read from this - * instance - * @throws IOException if anything wrong happens while reading from this - * instance - */ - public void read(Buffer buffer) - throws IOException - { - int[][] inputSamples; - int maxInputSampleCount; - long timeStamp; - - synchronized (readSyncRoot) - { - inputSamples = this.inputSamples; - maxInputSampleCount = this.maxInputSampleCount; - timeStamp = this.timeStamp; - - this.inputSamples = null; - this.maxInputSampleCount = 0; - this.timeStamp = Buffer.TIME_UNKNOWN; - } - - int inputSampleCount = (inputSamples == null) ? 0 : inputSamples.length; - - if ((inputSampleCount == 0) - || (maxInputSampleCount <= 0)) - { - buffer.setLength(0); - return; - } - - AudioFormat outputFormat = getFormat(); - int[] outputSamples - = mix(inputSamples, outputFormat, maxInputSampleCount); - - Class outputDataType = outputFormat.getDataType(); - - if (Format.byteArray.equals(outputDataType)) - { - byte[] outputData; - - switch (outputFormat.getSampleSizeInBits()) - { - case 16: - outputData = new byte[outputSamples.length * 2]; - for (int i = 0; i < outputSamples.length; i++) - ArrayIOUtils.writeInt16(outputSamples[i], outputData, i * 2); - break; - case 32: - outputData = new byte[outputSamples.length * 4]; - for (int i = 0; i < outputSamples.length; i++) - writeInt(outputSamples[i], outputData, i * 4); - break; - case 8: - case 24: - default: - throw - new UnsupportedOperationException( - "AudioMixingPushBufferStream.read(Buffer)"); - } - - buffer.setData(outputData); - buffer.setFormat(outputFormat); - buffer.setLength(outputData.length); - buffer.setOffset(0); - buffer.setTimeStamp(timeStamp); - } - else - throw - new UnsupportedOperationException( - "AudioMixingPushBufferStream.read(Buffer)"); - } - - /** - * Sets the collection of audio sample sets to be mixed in the sense of - * audio mixing by this stream when data is read from it. Triggers a push to - * the clients of this stream. - * - * @param inputSamples the collection of audio sample sets to be mixed by - * this stream when data is read from it - * @param maxInputSampleCount the maximum number of per-stream audio samples - * available through inputSamples - * @param timeStamp the time stamp of inputSamples to be reported - * in the specified Buffer when data is read from this instance - */ - void setInputSamples( - int[][] inputSamples, - int maxInputSampleCount, - long timeStamp) - { - synchronized (readSyncRoot) - { - this.inputSamples = inputSamples; - this.maxInputSampleCount = maxInputSampleCount; - } - - BufferTransferHandler transferHandler = this.transferHandler; - - if (transferHandler != null) - transferHandler.transferData(this); - } - - /** - * Implements - * {@link PushBufferStream#setTransferHandler(BufferTransferHandler)}. Sets - * the BufferTransferHandler which is to be notified by this - * instance when it has media available for reading. - * - * @param transferHandler the BufferTransferHandler to be notified - * by this instance when it has media available for reading - */ - public void setTransferHandler(BufferTransferHandler transferHandler) - { - this.transferHandler = transferHandler; - } - - /** - * Starts the pushing of data out of this stream. - * - * @throws IOException if starting the pushing of data out of this stream - * fails - */ - synchronized void start() - throws IOException - { - audioMixerStream.addOutputStream(this); - if (logger.isTraceEnabled()) - logger - .trace( - "Started " - + getClass().getSimpleName() - + " with hashCode " - + hashCode()); - } - - /** - * Stops the pushing of data out of this stream. - * - * @throws IOException if stopping the pushing of data out of this stream - * fails - */ - synchronized void stop() - throws IOException - { - audioMixerStream.removeOutputStream(this); - if (logger.isTraceEnabled()) - logger - .trace( - "Stopped " - + getClass().getSimpleName() - + " with hashCode " - + hashCode()); - } - - /** - * Converts an integer to a series of bytes and writes the result into a - * specific output array of bytes starting the writing at a specific offset - * in it. - * - * @param input the integer to be written out as a series of bytes - * @param output the output to receive the conversion of the specified - * integer to a series of bytes - * @param outputOffset the offset in output at which the writing of - * the result of the conversion is to be started - */ - private static void writeInt(int input, byte[] output, int outputOffset) - { - output[outputOffset] = (byte) (input & 0xFF); - output[outputOffset + 1] = (byte) ((input >>> 8) & 0xFF); - output[outputOffset + 2] = (byte) ((input >>> 16) & 0xFF); - output[outputOffset + 3] = (byte) (input >> 24); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/conference/DataSourceFilter.java b/src/net/java/sip/communicator/impl/neomedia/conference/DataSourceFilter.java deleted file mode 100644 index 311897aae..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/conference/DataSourceFilter.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.conference; - -import javax.media.protocol.*; - -/** - * Represents a filter which determines whether a specific DataSource - * is to be selected or deselected by the caller of the filter. - * - * @author Lubomir Marinov - */ -public interface DataSourceFilter -{ - - /** - * Determines whether a specific DataSource is accepted by this - * filter i.e. whether the caller of this filter should include it in its - * selection. - * - * @param dataSource the DataSource to be checked whether it is - * accepted by this filter - * @return true if this filter accepts the specified - * DataSource i.e. if the caller of this filter should include it - * in its selection; otherwise, false - */ - public boolean accept(DataSource dataSource); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/conference/InputDataSourceDesc.java b/src/net/java/sip/communicator/impl/neomedia/conference/InputDataSourceDesc.java deleted file mode 100644 index ed7e99640..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/conference/InputDataSourceDesc.java +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.conference; - -import java.io.*; - -import javax.media.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.protocol.*; -import net.java.sip.communicator.util.*; - -/** - * Describes additional information about a specific input DataSource - * of an AudioMixer so that the AudioMixer can, for example, - * quickly discover the output AudioMixingPushBufferDataSource in the - * mix of which the contribution of the DataSource is to not be - * included. - *

- * Private to AudioMixer and AudioMixerPushBufferStream but - * extracted into its own file for the sake of clarity. - *

- * - * @author Lubomir Marinov - */ -class InputDataSourceDesc -{ - - /** - * The Logger used by the InputDataSourceDesc class and - * its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(InputDataSourceDesc.class); - - /** - * The constant which represents an empty array with SourceStream - * element type. Explicitly defined in order to avoid unnecessary allocations. - */ - private static final SourceStream[] EMPTY_STREAMS = new SourceStream[0]; - - /** - * The indicator which determines whether the effective input - * DataSource described by this instance is currently connected. - */ - private boolean connected; - - /** - * The Thread which currently executes {@link DataSource#connect()} - * on the effective input DataSource described by this instance. - */ - private Thread connectThread; - - /** - * The DataSource for which additional information is described by - * this instance. - */ - public final DataSource inputDataSource; - - /** - * The AudioMixingPushBufferDataSource in which the mix - * contributions of {@link #inputDataSource} are to not be included. - */ - public final AudioMixingPushBufferDataSource outputDataSource; - - /** - * The DataSource, if any, which transcodes the tracks of - * {@link #inputDataSource} in the output Format of the associated - * AudioMixer. - */ - private DataSource transcodingDataSource; - - /** - * Initializes a new InputDataSourceDesc instance which is to - * describe additional information about a specific input - * DataSource of an AudioMixer. Associates the specified - * DataSource with the AudioMixingPushBufferDataSource in - * which the mix contributions of the specified input DataSource - * are to not be included. - * - * @param inputDataSource a DataSourc for which additional - * information is to be described by the new instance - * @param outputDataSource the AudioMixingPushBufferDataSource in - * which the mix contributions of inputDataSource are to not be - * included - */ - public InputDataSourceDesc( - DataSource inputDataSource, - AudioMixingPushBufferDataSource outputDataSource) - { - this.inputDataSource = inputDataSource; - this.outputDataSource = outputDataSource; - } - - /** - * Connects the effective input DataSource described by this - * instance upon request from a specific AudioMixer. If the - * effective input DataSource is to be asynchronously connected, - * the completion of the connect procedure will be reported to the specified - * AudioMixer by calling its - * {@link AudioMixer#connected(InputDataSourceDesc)}. - * - * @param audioMixer the AudioMixer requesting the effective input - * DataSource described by this instance to be connected - * @throws IOException if anything wrong happens while connecting the - * effective input DataSource described by this instance - */ - synchronized void connect(final AudioMixer audioMixer) - throws IOException - { - final DataSource effectiveInputDataSource - = (transcodingDataSource == null) - ? inputDataSource - : transcodingDataSource; - - if (effectiveInputDataSource instanceof TranscodingDataSource) - { - if (connectThread == null) - { - connectThread = new Thread() - { - @Override - public void run() - { - try - { - audioMixer - .connect( - effectiveInputDataSource, - inputDataSource); - synchronized (InputDataSourceDesc.this) - { - connected = true; - } - audioMixer.connected(InputDataSourceDesc.this); - } - catch (IOException ioex) - { - logger - .error( - "Failed to connect to inputDataSource " - + MediaStreamImpl - .toString(inputDataSource), - ioex); - } - finally - { - synchronized (InputDataSourceDesc.this) - { - if (connectThread == Thread.currentThread()) - connectThread = null; - } - } - } - }; - connectThread.setDaemon(true); - connectThread.start(); - } - } - else - { - audioMixer.connect(effectiveInputDataSource, inputDataSource); - connected = true; - } - } - - /** - * Creates a DataSource which attempts to transcode the tracks of - * the input DataSource described by this instance into a specific - * output Format. - * - * @param outputFormat the Format in which the tracks of the input - * DataSource described by this instance are to be transcoded - * @return true if a new transcoding DataSource has been - * created for the input DataSource described by this instance; - * otherwise, false - */ - synchronized boolean createTranscodingDataSource(Format outputFormat) - { - if (transcodingDataSource == null) - { - setTranscodingDataSource( - new TranscodingDataSource(inputDataSource, outputFormat)); - return true; - } - else - return false; - } - - /** - * Disconnects the effective input DataSource described by this - * instance if it is already connected. - */ - synchronized void disconnect() - { - if (connected) - { - getEffectiveInputDataSource().disconnect(); - connected = false; - } - } - - /** - * Gets the control available for the effective input DataSource - * described by this instance with a specific type. - * - * @param controlType a String value which specifies the type of - * the control to be retrieved - * @return an Object which represents the control available for the - * effective input DataSource described by this instance with the - * specified controlType if such a control exists; otherwise, - * null - */ - public synchronized Object getControl(String controlType) - { - DataSource effectiveInputDataSource = getEffectiveInputDataSource(); - - return - (effectiveInputDataSource == null) - ? null - : effectiveInputDataSource.getControl(controlType); - } - - /** - * Gets the actual DataSource from which the associated - * AudioMixer directly reads in order to retrieve the mix - * contribution of the DataSource described by this instance. - * - * @return the actual DataSource from which the associated - * AudioMixer directly reads in order to retrieve the mix - * contribution of the DataSource described by this instance - */ - public synchronized DataSource getEffectiveInputDataSource() - { - return - (transcodingDataSource == null) - ? inputDataSource - : (connected ? transcodingDataSource : null); - } - - /** - * Gets the SourceStreams of the effective input - * DataSource described by this instance. - * - * @return an array of the SourceStreams of the effective input - * DataSource described by this instance - */ - public synchronized SourceStream[] getStreams() - { - if (!connected) - return EMPTY_STREAMS; - - DataSource inputDataSource = getEffectiveInputDataSource(); - - if (inputDataSource instanceof PushBufferDataSource) - return ((PushBufferDataSource) inputDataSource).getStreams(); - else if (inputDataSource instanceof PullBufferDataSource) - return ((PullBufferDataSource) inputDataSource).getStreams(); - else if (inputDataSource instanceof TranscodingDataSource) - return ((TranscodingDataSource) inputDataSource).getStreams(); - else - return null; - } - - /** - * Sets the DataSource, if any, which transcodes the tracks of the - * input DataSource described by this instance in the output - * Format of the associated AudioMixer. - * - * @param transcodingDataSource the DataSource which transcodes - * the tracks of the input DataSource described by this instance in - * the output Format of the associated AudioMixer - */ - private synchronized void setTranscodingDataSource( - DataSource transcodingDataSource) - { - this.transcodingDataSource = transcodingDataSource; - connected = false; - } - - /** - * Starts the effective input DataSource described by this instance - * if it is connected. - * - * @throws IOException if starting the effective input DataSource - * described by this instance fails - */ - synchronized void start() - throws IOException - { - if (connected) - getEffectiveInputDataSource().start(); - } - - /** - * Stops the effective input DataSource described by this instance - * if it is connected. - * - * @throws IOException if stopping the effective input DataSource - * described by this instance fails - */ - synchronized void stop() - throws IOException - { - if (connected) - getEffectiveInputDataSource().stop(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/conference/InputStreamDesc.java b/src/net/java/sip/communicator/impl/neomedia/conference/InputStreamDesc.java deleted file mode 100644 index 4926270e0..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/conference/InputStreamDesc.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.conference; - -import java.lang.ref.*; - -import javax.media.*; -import javax.media.protocol.*; - -/** - * Describes additional information about a specific input audio - * SourceStream of an AudioMixer so that the - * AudioMixer can, for example, quickly discover the output - * AudioMixingPushBufferDataSource in the mix of which the contribution - * of the SourceStream is to not be included. - *

- * Private to AudioMixer and AudioMixerPushBufferStream but - * extracted into its own file for the sake of clarity. - *

- * - * @author Lyubomir Marinov - */ -class InputStreamDesc -{ - /** - * The Buffer into which media data is to be read from - * {@link #inputStream}. - */ - private SoftReference buffer; - - /** - * The DataSource which created the SourceStream described - * by this instance and additional information about it. - */ - public final InputDataSourceDesc inputDataSourceDesc; - - /** - * The SourceStream for which additional information is described - * by this instance. - */ - private SourceStream inputStream; - - /** - * The number of reads of this input stream which did not return any - * samples. - */ - long nonContributingReadCount; - - /** - * Initializes a new InputStreamDesc instance which is to describe - * additional information about a specific input audio SourceStream - * of an AudioMixer. Associates the specified SourceStream - * with the DataSource which created it and additional information - * about it. - * - * @param inputStream a SourceStream for which additional - * information is to be described by the new instance - * @param inputDataSourceDesc the DataSource which created the - * SourceStream to be described by the new instance and additional - * information about it - */ - public InputStreamDesc( - SourceStream inputStream, - InputDataSourceDesc inputDataSourceDesc) - { - this.inputStream = inputStream; - this.inputDataSourceDesc = inputDataSourceDesc; - } - - /** - * Gets the Buffer into which media data is to be read from the - * SourceStream described by this instance. - * - * @param create the indicator which determines whether the Buffer - * is to be created in case it does not exist - * @return the Buffer into which media data is to be read from the - * SourceStream described by this instance - */ - public Buffer getBuffer(boolean create) - { - Buffer buffer = (this.buffer == null) ? null : this.buffer.get(); - - if ((buffer == null) && create) - { - buffer = new Buffer(); - setBuffer(buffer); - } - return buffer; - } - - /** - * Gets the SourceStream described by this instance. - * - * @return the SourceStream described by this instance - */ - public SourceStream getInputStream() - { - return inputStream; - } - - /** - * Gets the AudioMixingPushBufferDataSource in which the mix - * contribution of the SourceStream described by this instance is - * to not be included. - * - * @return the AudioMixingPushBufferDataSource in which the mix - * contribution of the SourceStream described by this instance is - * to not be included - */ - public AudioMixingPushBufferDataSource getOutputDataSource() - { - return inputDataSourceDesc.outputDataSource; - } - - /** - * Sets the Buffer into which media data is to be read from the - * SourceStream described by this instance. - * - * @param buffer the Buffer into which media data is to be read - * from the SourceStream described by this instance - */ - public void setBuffer(Buffer buffer) - { - this.buffer - = (buffer == null) ? null : new SoftReference(buffer); - } - - /** - * Sets the SourceStream to be described by this instance. - * - * @param inputStream the SourceStream to be described by this - * instance - */ - public void setInputStream(SourceStream inputStream) - { - if (this.inputStream != inputStream) - { - this.inputStream = inputStream; - - /* - * Since the inputStream has changed, one may argue that the Buffer - * of the old value is not optimal for the new value. - */ - setBuffer(null); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/control/AbstractControls.java b/src/net/java/sip/communicator/impl/neomedia/control/AbstractControls.java deleted file mode 100644 index 4c3c9e7f5..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/control/AbstractControls.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.control; - -import javax.media.*; - -import net.java.sip.communicator.util.*; - -/** - * Provides an abstract implementation of Controls which facilitates - * implementers by requiring them to only implement - * {@link Controls#getControls()}. - * - * @author Lubomir Marinov - */ -public abstract class AbstractControls - implements Controls -{ - - /** - * The Logger used by the AbstractControls class and its - * instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(AbstractControls.class); - - /** - * Implements {@link Controls#getControl(String)}. Invokes - * {@link #getControls()} and then looks for a control of the specified type - * in the returned array of controls. - * - * @param controlType a String value naming the type of the control - * of this instance to be retrieved - * @return an Object which represents the control of this instance - * with the specified type - */ - public Object getControl(String controlType) - { - return getControl(this, controlType); - } - - /** - * Gets the control of a specific Controls implementation of a - * specific type if such a control is made available through - * {@link Controls#getControls()}; otherwise, returns null. - * - * @param controlsImpl the implementation of Controls which is to - * be queried for its list of controls so that the control of the specified - * type can be looked for - * @param controlType a String value which names the type of the - * control to be retrieved - * @return an Object which represents the control of - * controlsImpl of the specified controlType if such a - * control is made available through Controls#getControls(); - * otherwise, null - */ - public static Object getControl(Controls controlsImpl, String controlType) - { - Object[] controls = controlsImpl.getControls(); - - if ((controls != null) && (controls.length > 0)) - { - Class controlClass; - - try - { - controlClass = Class.forName(controlType); - } - catch (ClassNotFoundException cnfe) - { - controlClass = null; - logger - .warn( - "Failed to find control class " + controlType, - cnfe); - } - if (controlClass != null) - for (Object control : controls) - if (controlClass.isInstance(control)) - return control; - } - return null; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/control/AbstractFormatControl.java b/src/net/java/sip/communicator/impl/neomedia/control/AbstractFormatControl.java deleted file mode 100644 index 7e105b3da..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/control/AbstractFormatControl.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.control; - -import java.util.*; - -import javax.media.*; -import javax.media.control.*; - -/** - * Provides an abstract implementation of FormatControl which - * facilitates implementers by requiring them to implement just - * {@link FormatControl#getSupportedFormats()} and - * {@link FormatControl#getFormat()}. - * - * @author Lyubomir Marinov - */ -public abstract class AbstractFormatControl - implements FormatControl -{ - - /** - * The indicator which determines whether this track is enabled. - */ - private boolean enabled; - - /** - * Implements {@link Control#getControlComponent()}. Returns null. - * - * @return a Component which represents UI associated with this - * instance if any; otherwise, null - */ - public java.awt.Component getControlComponent() - { - // No Component is exported by this instance. - return null; - } - - /** - * Gets an array of FormatControl instances from the list of - * controls available for a specific Controls implementation. - * - * @param controlsImpl the Controls implementation from which the - * FormatControl instances are to be retrieved - * @return an array of FormatControl instances from the list of - * controls available for the specified Controls implementation - */ - public static FormatControl[] getFormatControls(Controls controlsImpl) - { - List formatControls = new ArrayList(); - - for (Object control : controlsImpl.getControls()) - if (control instanceof FormatControl) - formatControls.add((FormatControl) control); - return formatControls.toArray(new FormatControl[formatControls.size()]); - } - - /** - * Implements {@link FormatControl#isEnabled()}. - * - * @return true if this track is enabled; otherwise, false - */ - public boolean isEnabled() - { - return enabled; - } - - /** - * Implements {@link FormatControl#setEnabled(boolean)}. - * - * @param enabled true if this track is to be enabled; otherwise, - * false - */ - public void setEnabled(boolean enabled) - { - this.enabled = enabled; - } - - /** - * Implements {@link FormatControl#setFormat(Format)}. Not supported and - * just returns the currently set format if the specified Format is - * supported and null if it is not supported. - * - * @param format the Format to be set on this instance - * @return the currently set Format after the attempt to set it on - * this instance if format is supported by this instance and - * regardless of whether it was actually set; null if - * format is not supported by this instance - */ - public Format setFormat(Format format) - { - return setFormat(this, format); - } - - /** - * Implements setting the Format of a specific - * FormatControl as documented for - * {@link FormatControl#setFormat(Format)} in the case of not supporting - * Format setting. - * - * @param formatControl the FormatControl for which the - * functionality is implemented - * @param format the Format specified to be set to - * formatControl and which will be ignored in accord with the - * documentation of FormatControl#setFormat(Format) - * @return the currently set Format of formatControl if - * format is supported by formatControl; null if - * format is not supported by formatControl - */ - public static Format setFormat(FormatControl formatControl, Format format) - { - /* - * Determine whether the specified format is supported by this instance - * because we have to return null if it is not supported. Or at least - * that is what I gather from the respective javadoc. - */ - boolean formatIsSupported = false; - - if (format != null) - for (Format supportedFormat : formatControl.getSupportedFormats()) - if (supportedFormat.matches(format)) - { - formatIsSupported = true; - break; - } - - /* - * We do not actually support setFormat so we have to return the - * currently set format if the specified format is supported. - */ - return formatIsSupported ? formatControl.getFormat() : null; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/control/ControlsAdapter.java b/src/net/java/sip/communicator/impl/neomedia/control/ControlsAdapter.java deleted file mode 100644 index 461c75779..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/control/ControlsAdapter.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.control; - -/** - * Provides a default implementation of Controls which does not expose - * any controls. - * - * @author Lubomir Marinov - */ -public class ControlsAdapter - extends AbstractControls -{ - - /** - * The constant which represents an empty array of controls. Explicitly - * defined in order to avoid unnecessary allocations. - */ - public static final Object[] EMPTY_CONTROLS = new Object[0]; - - /** - * Implements {@link javax.media.Controls#getControls()}. Gets the controls - * available for the owner of this instance. The current implementation - * returns an empty array because it has no available controls. - * - * @return an array of Objects which represent the controls - * available for the owner of this instance - */ - public Object[] getControls() - { - return EMPTY_CONTROLS; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/control/FrameProcessingControlImpl.java b/src/net/java/sip/communicator/impl/neomedia/control/FrameProcessingControlImpl.java deleted file mode 100644 index 6610b2c26..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/control/FrameProcessingControlImpl.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.control; - -import java.awt.*; - -import javax.media.control.*; - -/** - * Provides a base implementation of FrameProcessingControl which keeps - * track of the minimalProcessing property, switches its value to - * true when it's notified that its owner is at least one frame behind - * and doesn't implement the controlComponent and - * framesDropped properties. - * - * @author Lyubomir Marinov - */ -public class FrameProcessingControlImpl - implements FrameProcessingControl -{ - - /** - * The indicator which determines whether the owner of this - * FrameProcessingControl is to perform only the minimum operations - * necessary to keep it working normally but without producing output. - */ - private boolean minimalProcessing = false; - - /** - * Gets the UI Component associated with this Control - * object. - * - * @return the UI Component associated with this Control - * object - */ - public Component getControlComponent() - { - /* - * We totally don't care about providing a UI component which controls - * frame drop from inside the media implementation. - */ - return null; - } - - /** - * Gets the number of output frames that were dropped during processing - * since the last call to this method. - * - * @return the number of output frame that were dropped during processing - * since the last call to this method - */ - public int getFramesDropped() - { - return 0; // Not implemented. - } - - /** - * Determines whether the owner of this FrameProcessingControl is - * to perform only the minimum operations necessary to keep it working - * normally but without producing output. - * - * @return true if the owner of this - * FrameProcessingControl is to perform only the minimum operations - * necessary to keep it working normally but without producing output; - * otherwise, false - */ - public boolean isMinimalProcessing() - { - return minimalProcessing; - } - - /** - * Sets the number of frames the owner of this - * FrameProcessingControl is lagging behind. It is a hint to do - * minimal processing for the next framesBehind frames in order to - * catch up. - * - * @param framesBehind the number of frames the owner of this - * FrameProcessingControl is lagging behind - */ - public void setFramesBehind(float framesBehind) - { - setMinimalProcessing(framesBehind > 0); - } - - /** - * Sets the indicator which determines whether the owner of this - * FrameProcessingControl is to perform only the minimal operations - * necessary to keep it working normally but without producing output. - * - * @param minimalProcessing true if minimal processing mode is to - * be turned on or false if minimal processing mode is to be turned - * off - * @return the actual minimal processing mode in effect after the set - * attempt - */ - public boolean setMinimalProcessing(boolean minimalProcessing) - { - this.minimalProcessing = minimalProcessing; - return this.minimalProcessing; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/control/FrameRateControlAdapter.java b/src/net/java/sip/communicator/impl/neomedia/control/FrameRateControlAdapter.java deleted file mode 100644 index ea2672d91..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/control/FrameRateControlAdapter.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.control; - -import java.awt.*; - -import javax.media.*; -import javax.media.control.*; - -/** - * Provides a default implementation of FrameRateControl. - * - * @author Lyubomir Marinov - */ -public class FrameRateControlAdapter - implements FrameRateControl -{ - /** - * Gets the UI Component associated with this Control - * object. FrameRateControlAdapter always returns null. - * - * @return the UI Component associated with this Control - * object - * @see Control#getControlComponent() - */ - public Component getControlComponent() - { - return null; - } - - /** - * Gets the current output frame rate. FrameRateControlAdapter - * always returns -1. - * - * @return the current output frame rate if it is known; otherwise, - * -1 - * @see FrameRateControl#getFrameRate() - */ - public float getFrameRate() - { - return -1; - } - - /** - * Gets the maximum supported output frame rate. - * FrameRateControlAdapter always returns -1. - * - * @return the maximum supported output frame rate if it is known; - * otherwise, -1 - * @see FrameRateControl#getMaxSupportedFrameRate() - */ - public float getMaxSupportedFrameRate() - { - return -1; - } - - /** - * Gets the default/preferred output frame rate. - * FrameRateControlAdapter always returns -1. - * - * @return the default/preferred output frame rate if it is known; - * otherwise, -1 - * @see FrameRateControl#getPreferredFrameRate() - */ - public float getPreferredFrameRate() - { - return -1; - } - - /** - * Sets the output frame rate. FrameRateControlAdapter always - * returns -1. - * - * @param frameRate the output frame rate to change the current one to - * @return the actual current output frame rate or -1 if it is - * unknown or not controllable - * @see FrameRateControl#setFrameRate(float) - */ - public float setFrameRate(float frameRate) - { - return -1; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/control/ReadOnlyBufferControlDelegate.java b/src/net/java/sip/communicator/impl/neomedia/control/ReadOnlyBufferControlDelegate.java deleted file mode 100644 index 6cd97561b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/control/ReadOnlyBufferControlDelegate.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.control; - -import javax.media.control.*; - -/** - * Represents a wrapper of a specific BufferControl which does not call - * the setters of the wrapped instance and calls only the getters. - * - * @author Lubomir Marinov - */ -public class ReadOnlyBufferControlDelegate - implements BufferControl -{ - - /** - * The BufferControl wrapped by this instance. - */ - private final BufferControl bufferControl; - - /** - * Initializes a new ReadOnlyBufferControlDelegate instance which - * is to wrap a specific BufferControl and call only its getters. - * - * @param bufferControl the BufferControl to be wrapped by the new - * instance - */ - public ReadOnlyBufferControlDelegate(BufferControl bufferControl) - { - this.bufferControl = bufferControl; - } - - /** - * Implements {@link BufferControl#getBufferLength()}. Gets the length in - * milliseconds of the buffering performed by the owner of the wrapped - * BufferControl. - * - * @return the length in milliseconds of the buffering performed by the - * owner of the wrapped BufferControl - */ - public long getBufferLength() - { - return bufferControl.getBufferLength(); - } - - /** - * Implements {@link javax.media.Control#getControlComponent()}. Gets the UI - * Component representing this instance and exported by the owner - * of the wrapped BufferControl. - * - * @return the UI Component representing the wrapped - * BufferControl and exported by its owner if such a - * Component is available; otherwise, null - */ - public java.awt.Component getControlComponent() - { - return bufferControl.getControlComponent(); - } - - /** - * Implements {@link BufferControl#getEnabledThreshold()}. Gets the - * indicator of the wrapped BufferControl which determines whether - * threshold calculations are enabled. - * - * @return true if threshold calculations are enabled in the - * wrapped BufferControl; otherwise, false - */ - public boolean getEnabledThreshold() - { - return bufferControl.getEnabledThreshold(); - } - - /** - * Implements {@link BufferControl#getMinimumThreshold()}. Gets the minimum - * threshold in milliseconds for the buffering performed by the owner of the - * wrapped BufferControl. - * - * @return the minimum threshold in milliseconds for the buffering performed - * by the owner of the wrapped BufferControl - */ - public long getMinimumThreshold() - { - return bufferControl.getMinimumThreshold(); - } - - /** - * Implements {@link BufferControl#setBufferLength(long)}. Ignores the - * request because this instance provides read-only support and returns the - * value actually in effect. - * - * @param bufferLength the length in milliseconds of the buffering to be - * performed by the owner of the wrapped BufferControl - * @return the length in milliseconds of the buffering performed by the - * owner of the wrapped BufferControl that is actually in effect - */ - public long setBufferLength(long bufferLength) - { - return getBufferLength(); - } - - /** - * Implements {@link BufferControl#setEnabledThreshold(boolean)}. Ignores - * the set request because this instance provides read-only support. - * - * @param enabledThreshold true if threshold calculations are - * to be enabled; otherwise, false - */ - public void setEnabledThreshold(boolean enabledThreshold) - { - } - - /** - * Implements {@link BufferControl#setMinimumThreshold(long)}. Ignores the - * set request because this instance provides read-only support and returns - * the value actually in effect. - * - * @param minimumThreshold the minimum threshold in milliseconds for the - * buffering to be performed by the owner of the wrapped - * BufferControl - * @return the minimum threshold in milliseconds for the buffering performed - * by the owner of the wrapped BufferControl that is actually in - * effect - */ - public long setMinimumThreshold(long minimumThreshold) - { - return getMinimumThreshold(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/control/ReadOnlyFormatControlDelegate.java b/src/net/java/sip/communicator/impl/neomedia/control/ReadOnlyFormatControlDelegate.java deleted file mode 100644 index 5c0a9f7f1..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/control/ReadOnlyFormatControlDelegate.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.control; - -import java.awt.*; - -import javax.media.*; -import javax.media.control.*; - -/** - * Represents a wrapper of a specific FormatControl instance which does - * not allow setting its format using {@link FormatControl#setFormat(Format)}. - * - * @author Lubomir Marinov - */ -public class ReadOnlyFormatControlDelegate - implements FormatControl -{ - - /** - * The FormatControl wrapped by this instance. - */ - private final FormatControl formatControl; - - /** - * Initializes a new ReadOnlyFormatControlDelegate instance which - * is to wrap a specific FormatControl in order to prevent calls to - * its {@link FormatControl#setFormat(Format)}. - * - * @param formatControl the FormatControl which is to have calls to - * its FormatControl#setFormat(Format) prevented - */ - public ReadOnlyFormatControlDelegate(FormatControl formatControl) - { - this.formatControl = formatControl; - } - - /** - * Implements {@link Control#getControlComponent()}. - * - * @return a Component which represents UI associated with this - * instance if any; otherwise, null - */ - public Component getControlComponent() - { - return formatControl.getControlComponent(); - } - - /** - * Gets the Format of the owner of this FormatControl. - * Delegates to the wrapped FormatControl. - * - * @return the Format of the owner of this FormatControl - */ - public Format getFormat() - { - return formatControl.getFormat(); - } - - /** - * Gets the Formats supported by the owner of this - * FormatControl. Delegates to the wrapped FormatControl. - * - * @return an array of Formats supported by the owner of this - * FormatControl - */ - public Format[] getSupportedFormats() - { - return formatControl.getSupportedFormats(); - } - - /** - * Implements {@link FormatControl#isEnabled()}. - * - * @return true if this track is enabled; otherwise, false - */ - public boolean isEnabled() - { - return formatControl.isEnabled(); - } - - /** - * Implements {@link FormatControl#setEnabled(boolean)}. - * - * @param enabled true if this track is to be enabled; otherwise, - * false - */ - public void setEnabled(boolean enabled) - { - // Ignore the request because this instance is read-only. - } - - /** - * Implements {@link FormatControl#setFormat(Format)}. Not supported and - * just returns the currently set format if the specified Format is - * supported and null if it is not supported. - * - * @param format the Format to be set on this instance - * @return the currently set Format after the attempt to set it on - * this instance if format is supported by this instance and - * regardless of whether it was actually set; null if - * format is not supported by this instance - */ - public Format setFormat(Format format) - { - return AbstractFormatControl.setFormat(this, format); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/AbstractMediaDevice.java b/src/net/java/sip/communicator/impl/neomedia/device/AbstractMediaDevice.java deleted file mode 100644 index 05f9aca65..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/AbstractMediaDevice.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import java.io.*; -import java.util.*; - -import javax.media.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.format.*; - -/** - * Defines the interface for MediaDevice required by the - * net.java.sip.communicator.impl.neomedia implementation of - * net.java.sip.communicator.service.neomedia. - * - * @author Lyubomir Marinov - */ -public abstract class AbstractMediaDevice - implements MediaDevice -{ - /** - * Connects to a specific CaptureDevice given in the form of a - * DataSource. Explicitly defined in order to allow extenders to - * customize the connect procedure. - * - * @param captureDevice the CaptureDevice to be connected to - * @throws IOException if anything wrong happens while connecting to the - * specified captureDevice - */ - public void connect(DataSource captureDevice) - throws IOException - { - if (captureDevice == null) - throw new NullPointerException("captureDevice"); - try - { - captureDevice.connect(); - } - catch (NullPointerException npe) - { - /* - * The old media says it happens when the operating system does not - * support the operation. - */ - IOException ioe = new IOException(); - - ioe.initCause(npe); - throw ioe; - } - } - - /** - * Creates a DataSource instance for this MediaDevice - * which gives access to the captured media. - * - * @return a DataSource instance which gives access to the media - * captured by this MediaDevice - */ - abstract DataSource createOutputDataSource(); - - /** - * Initializes a new Renderer instance which is to play back media - * on this MediaDevice. - * - * @return a new Renderer instance which is to play back media on - * this MediaDevice or null if a suitable - * Renderer is to be chosen irrespective of this - * MediaDevice - */ - abstract Renderer createRenderer(); - - /** - * Creates a new MediaDeviceSession instance which is to represent - * the use of this MediaDevice by a MediaStream. - * - * @return a new MediaDeviceSession instance which is to represent - * the use of this MediaDevice by a MediaStream - */ - public MediaDeviceSession createSession() - { - switch (getMediaType()) - { - case VIDEO: - return new VideoMediaDeviceSession(this); - default: - return new AudioMediaDeviceSession(this); - } - } - - /** - * Returns a List containing (at the time of writing) a single - * extension descriptor indicating RECVONLY support for - * mixer-to-client audio levels. - * - * @return a List containing the CSRC_AUDIO_LEVEL_URN - * extension descriptor. - */ - public List getSupportedExtensions() - { - return null; - } - - /** - * Gets a list of MediaFormats supported by this - * MediaDevice. - * - * @return the list of MediaFormats supported by this device - * @see MediaDevice#getSupportedFormats() - */ - public List getSupportedFormats() - { - return getSupportedFormats(null, null); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/AudioMediaDeviceImpl.java b/src/net/java/sip/communicator/impl/neomedia/device/AudioMediaDeviceImpl.java deleted file mode 100644 index dceccefd1..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/AudioMediaDeviceImpl.java +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import java.io.*; -import java.net.*; -import java.util.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.conference.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.util.*; - -/** - * Extends MediaDeviceImpl with audio-specific functionality. - * - * @author Lyubomir Marinov - */ -public class AudioMediaDeviceImpl - extends MediaDeviceImpl -{ - - /** - * The Logger used by the AudioMediaDeviceImpl class and - * its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(AudioMediaDeviceImpl.class); - - /** - * The AudioMixer which enables sharing an exclusive - * CaptureDevice such as JavaSound between multiple - * CaptureDevice users. - */ - private AudioMixer captureDeviceSharing; - - /** - * The List of RTP extensions supported by this device (at the time - * of writing this list is only filled for audio devices and is - * null otherwise). - */ - private List rtpExtensions = null; - - /** - * Initializes a new AudioMediaDeviceImpl instance which represents - * a MediaDevice with MediaType AUDIO and a - * MediaDirection which does not allow sending. - */ - public AudioMediaDeviceImpl() - { - super(MediaType.AUDIO); - } - - /** - * Initializes a new AudioMediaDeviceImpl which is to provide an - * implementation of MediaDevice with MediaType - * AUDIO to a CaptureDevice with a specific - * CaptureDeviceInfo. - * - * @param captureDeviceInfo the CaptureDeviceInfo of the - * CaptureDevice to which the new instance is to provide an - * implementation of MediaDevice - */ - public AudioMediaDeviceImpl(CaptureDeviceInfo captureDeviceInfo) - { - super(captureDeviceInfo, MediaType.AUDIO); - } - - /** - * Connects to a specific CaptureDevice given in the form of a - * DataSource. - * - * @param captureDevice the CaptureDevice to be connected to - * @throws IOException if anything wrong happens while connecting to the - * specified captureDevice - * @see AbstractMediaDevice#connect(DataSource) - */ - @Override - public void connect(DataSource captureDevice) - throws IOException - { - super.connect(captureDevice); - - /* - * 1. Changing buffer size. The default buffer size (for JavaSound) is - * 125 milliseconds - 1/8 sec. On Mac OS X this leads to an exception - * and no audio capture. A value of 30 for the buffer fixes the problem - * and is OK when using some PSTN gateways. - * - * 2. Changing to 60. When it is 30 there are some issues with Asterisk - * and NAT (we don't start to send stream and so Asterisk RTP part - * doesn't notice that we are behind NAT). - * - * 3. Do not set buffer length on Linux as it completely breaks audio - * capture. - */ - if(!OSUtils.IS_LINUX) - { - BufferControl bufferControl - = (BufferControl) - captureDevice.getControl(BufferControl.class.getName()); - - if (bufferControl != null) - bufferControl.setBufferLength(60 /* millis */); - } - } - - /** - * Creates the JMF CaptureDevice this instance represents and - * provides an implementation of MediaDevice for. - * - * @return the JMF CaptureDevice this instance represents and - * provides an implementation of MediaDevice for; null - * if the creation fails - */ - @Override - synchronized CaptureDevice createCaptureDevice() - { - CaptureDevice captureDevice = null; - - if (getDirection().allowsSending()) - { - if (captureDeviceSharing == null) - { - String protocol = getCaptureDeviceInfoLocatorProtocol(); - boolean createCaptureDeviceIfNull = true; - - if (AudioSystem.LOCATOR_PROTOCOL_JAVASOUND.equalsIgnoreCase( - protocol) - || AudioSystem.LOCATOR_PROTOCOL_PORTAUDIO - .equalsIgnoreCase(protocol)) - { - captureDevice = superCreateCaptureDevice(); - createCaptureDeviceIfNull = false; - if (captureDevice != null) - { - captureDeviceSharing - = createCaptureDeviceSharing(captureDevice); - captureDevice - = captureDeviceSharing.createOutputDataSource(); - } - } - if ((captureDevice == null) && createCaptureDeviceIfNull) - captureDevice = superCreateCaptureDevice(); - } - else - captureDevice = captureDeviceSharing.createOutputDataSource(); - } - return captureDevice; - } - - /** - * Creates a new AudioMixer which is to enable the sharing of a - * specific explicit CaptureDevice - * - * @param captureDevice an exclusive CaptureDevice for which - * sharing is to be enabled - * @return a new AudioMixer which enables the sharing of the - * specified exclusive captureDevice - */ - private AudioMixer createCaptureDeviceSharing(CaptureDevice captureDevice) - { - return - new AudioMixer(captureDevice) - { - @Override - protected void connect( - DataSource dataSource, - DataSource inputDataSource) - throws IOException - { - /* - * CaptureDevice needs special connecting as defined by - * AbstractMediaDevice and, especially, MediaDeviceImpl. - */ - if (inputDataSource == captureDevice) - AudioMediaDeviceImpl.this.connect(dataSource); - else - super.connect(dataSource, inputDataSource); - } - }; - } - - /** - * Initializes a new Renderer instance which is to play back media - * on this MediaDevice. - * - * @return a new Renderer instance which is to play back media on - * this MediaDevice or null if a suitable - * Renderer is to be chosen irrespective of this - * MediaDevice - */ - @Override - Renderer createRenderer() - { - Renderer renderer = null; - - try - { - String locatorProtocol = getCaptureDeviceInfoLocatorProtocol(); - - if (locatorProtocol != null) - { - AudioSystem audioSystem - = AudioSystem.getAudioSystem(locatorProtocol); - - if (audioSystem != null) - renderer = audioSystem.createRenderer(true); - } - } - finally - { - if (renderer == null) - renderer = super.createRenderer(); - } - return renderer; - } - - /** - * Gets the protocol of the MediaLocator of the - * CaptureDeviceInfo represented by this instance. - * - * @return the protocol of the MediaLocator of the - * CaptureDeviceInfo represented by this instance - */ - private String getCaptureDeviceInfoLocatorProtocol() - { - CaptureDeviceInfo cdi = getCaptureDeviceInfo(); - - if (cdi != null) - { - MediaLocator locator = cdi.getLocator(); - - if (locator != null) - return locator.getProtocol(); - } - - return null; - } - - /** - * Returns a List containing (at the time of writing) a single - * extension descriptor indicating RECVONLY support for - * mixer-to-client audio levels. - * - * @return a List containing the CSRC_AUDIO_LEVEL_URN - * extension descriptor. - */ - @Override - public List getSupportedExtensions() - { - if (rtpExtensions == null) - { - rtpExtensions = new ArrayList(1); - - URI csrcAudioLevelURN; - - try - { - csrcAudioLevelURN = new URI(RTPExtension.CSRC_AUDIO_LEVEL_URN); - } - catch (URISyntaxException e) - { - // can't happen since CSRC_AUDIO_LEVEL_URN is a valid URI and - // never changes. - if (logger.isInfoEnabled()) - logger.info("Aha! Someone messed with the source!", e); - csrcAudioLevelURN = null; - } - if (csrcAudioLevelURN != null) - rtpExtensions.add( - new RTPExtension( - csrcAudioLevelURN, - MediaDirection.RECVONLY)); - } - - return rtpExtensions; - } - - private boolean isLessThanOrEqualToMaxAudioFormat(Format format) - { - if (format instanceof AudioFormat) - { - AudioFormat audioFormat = (AudioFormat) format; - int channels = audioFormat.getChannels(); - - if ((channels == Format.NOT_SPECIFIED) - || (MediaUtils.MAX_AUDIO_CHANNELS == Format.NOT_SPECIFIED) - || (channels <= MediaUtils.MAX_AUDIO_CHANNELS)) - { - double sampleRate = audioFormat.getSampleRate(); - - if ((sampleRate == Format.NOT_SPECIFIED) - || (MediaUtils.MAX_AUDIO_SAMPLE_RATE - == Format.NOT_SPECIFIED) - || (sampleRate <= MediaUtils.MAX_AUDIO_SAMPLE_RATE)) - { - int sampleSizeInBits - = audioFormat.getSampleSizeInBits(); - - if ((sampleSizeInBits == Format.NOT_SPECIFIED) - || (MediaUtils.MAX_AUDIO_SAMPLE_SIZE_IN_BITS - == Format.NOT_SPECIFIED) - || (sampleSizeInBits - <= MediaUtils - .MAX_AUDIO_SAMPLE_SIZE_IN_BITS)) - { - return true; - } - } - } - } - return false; - } - - /** - * Invokes the super (with respect to the AudioMediaDeviceImpl - * class) implementation of {@link MediaDeviceImpl#createCaptureDevice()}. - * Allows this instance to customize the very CaptureDevice which - * is to be possibly further wrapped by this instance. - * - * @return the CaptureDevice returned by the call to the super - * implementation of MediaDeviceImpl#createCaptureDevice. - */ - protected CaptureDevice superCreateCaptureDevice() - { - CaptureDevice captureDevice = super.createCaptureDevice(); - - if (captureDevice != null) - { - /* - * Try to default the captureDevice to a Format which does not - * exceed the maximum quality known to MediaUtils. - */ - try - { - FormatControl[] formatControls - = captureDevice.getFormatControls(); - - if ((formatControls != null) && (formatControls.length != 0)) - { - for (FormatControl formatControl : formatControls) - { - Format format = formatControl.getFormat(); - - if ((format != null) - && isLessThanOrEqualToMaxAudioFormat(format)) - continue; - - Format[] supportedFormats - = formatControl.getSupportedFormats(); - AudioFormat supportedFormatToSet = null; - - if ((supportedFormats != null) - && (supportedFormats.length != 0)) - { - for (Format supportedFormat : supportedFormats) - { - if (isLessThanOrEqualToMaxAudioFormat( - supportedFormat)) - { - supportedFormatToSet - = (AudioFormat) supportedFormat; - break; - } - } - } - - if (!supportedFormatToSet.matches(format)) - { - int channels = supportedFormatToSet.getChannels(); - double sampleRate - = supportedFormatToSet.getSampleRate(); - int sampleSizeInBits - = supportedFormatToSet.getSampleSizeInBits(); - - if (channels == Format.NOT_SPECIFIED) - channels = MediaUtils.MAX_AUDIO_CHANNELS; - if (sampleRate == Format.NOT_SPECIFIED) - sampleRate = MediaUtils.MAX_AUDIO_SAMPLE_RATE; - if (sampleSizeInBits == Format.NOT_SPECIFIED) - { - sampleSizeInBits - = MediaUtils.MAX_AUDIO_SAMPLE_SIZE_IN_BITS; - /* - * TODO A great deal of the neomedia-contributed - * audio Codecs, CaptureDevices, DataSources and - * Renderers deal with 16-bit samples. - */ - if (sampleSizeInBits == Format.NOT_SPECIFIED) - sampleSizeInBits = 16; - } - - if ((channels != Format.NOT_SPECIFIED) - && (sampleRate != Format.NOT_SPECIFIED) - && (sampleSizeInBits - != Format.NOT_SPECIFIED)) - { - AudioFormat formatToSet - = new AudioFormat( - supportedFormatToSet.getEncoding(), - sampleRate, - sampleSizeInBits, - channels); - - if (supportedFormatToSet.matches(formatToSet)) - formatControl.setFormat( - supportedFormatToSet.intersects( - formatToSet)); - } - } - } - } - } - catch (Throwable t) - { - if (t instanceof ThreadDeath) - throw (ThreadDeath) t; - /* - * We tried to default the captureDevice to a Format which does - * not exceed the maximum quality known to MediaUtils and we - * failed but it does not mean that the captureDevice will not - * be successfully used. - */ - } - } - - return captureDevice; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/AudioMediaDeviceSession.java b/src/net/java/sip/communicator/impl/neomedia/device/AudioMediaDeviceSession.java deleted file mode 100644 index fc1cb0372..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/AudioMediaDeviceSession.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.audiolevel.*; -import net.java.sip.communicator.service.neomedia.event.*; -import net.java.sip.communicator.util.*; - -/** - * Extends MediaDeviceSession to add audio-specific functionality. - * - * @author Emil Ivov - * @author Damian Minkov - */ -public class AudioMediaDeviceSession - extends MediaDeviceSession -{ - /** - * The Logger used by the AudioMediaDeviceSession class - * and its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(AudioMediaDeviceSession.class); - - /** - * The Effect that we will register with our DataSource in - * order to measure the audio levels of the local user. - */ - private final AudioLevelEffect localUserAudioLevelEffect - = new AudioLevelEffect(); - - /** - * The effect that we will register with our stream in order to measure - * audio levels of the remote user audio. - */ - private final AudioLevelEffect streamAudioLevelEffect - = new AudioLevelEffect(); - - /** - * Initializes a new MediaDeviceSession instance which is to - * represent the use of a specific MediaDevice by a - * MediaStream. - * - * @param device the MediaDevice the use of which by a - * MediaStream is to be represented by the new instance - */ - protected AudioMediaDeviceSession(AbstractMediaDevice device) - { - super(device); - } - - /** - * Called by {@link MediaDeviceSession#playerControllerUpdate( - * ControllerEvent event)} when the player associated with this session's - * ReceiveStream moves enters the Configured state, so - * we use the occasion to add our audio level effect. - * - * @param player the Player which is the source of a - * ConfigureCompleteEvent - * @see MediaDeviceSession#playerConfigureComplete(Processor) - */ - @Override - protected void playerConfigureComplete(Processor player) - { - super.playerConfigureComplete(player); - - TrackControl tcs[] = player.getTrackControls(); - - if (tcs != null) - { - for (TrackControl tc : tcs) - { - if (tc.getFormat() instanceof AudioFormat) - { - // Assume there is only one audio track. - try - { - registerStreamAudioLevelJMFEffect(tc); - } - catch (UnsupportedPlugInException upie) - { - logger.error( - "Failed to register stream audio level Effect", - upie); - } - break; - } - } - } - } - - /** - * Gets notified about ControllerEvents generated by the - * processor reading our capture data source, calls the corresponding - * method from the parent class so that it would initialize the processor - * and then adds the level effect for the local user audio levels. - * - * @param event the ControllerEvent specifying the - * Controller which is the source of the event and the very type of - * the event - */ - @Override - protected void processorControllerUpdate(ControllerEvent event) - { - super.processorControllerUpdate(event); - - if (event instanceof ConfigureCompleteEvent) - { - Processor processor = (Processor) event.getSourceController(); - - if (processor != null) - registerLocalUserAudioLevelEffect(processor); - } - } - - /** - * Creates an audio level effect and add its to the codec chain of the - * TrackControl assuming that it only contains a single track. - * - * @param processor the processor on which track control we need - * to register a level effect with. - */ - protected void registerLocalUserAudioLevelEffect(Processor processor) - { - //we register the effect regardless of whether or not we have any - //listeners at this point because we won't get a second chance. - //however the effect would do next to nothing unless we register a - //first listener with it. - // - //XXX: i am assuming that a single effect could be reused multiple times - // if that turns out not to be the case we need to create a new instance - // here. - - // here we add sound level indicator for captured media - // from the microphone if there are interested listeners - try - { - TrackControl tcs[] = processor.getTrackControls(); - - if (tcs != null) - for (TrackControl tc : tcs) - if (tc.getFormat() instanceof AudioFormat) - { - //we assume a single track - tc.setCodecChain( - new Codec[] { localUserAudioLevelEffect }); - break; - } - } - catch (UnsupportedPlugInException ex) - { - logger.error( - "Effects are not supported by the datasource.", ex); - } - } - - /** - * Adds an audio level effect to the tracks of the specified - * trackControl and so that we would notify interested listeners - * of audio level changes. - * - * @param trackControl the TrackControl where we need to register - * a level effect that would measure the audio levels of the - * ReceiveStream associated with this class. - * - * @throws UnsupportedPlugInException if we fail to add our sound level - * effect to the track control of mediaStream's processor. - */ - private void registerStreamAudioLevelJMFEffect(TrackControl trackControl) - throws UnsupportedPlugInException - { - //we register the effect regardless of whether or not we have any - //listeners at this point because we won't get a second chance. - //however the effect would do next to nothing unless we register a - //first listener with it. - // Assume there is only one audio track - trackControl.setCodecChain(new Codec[] { streamAudioLevelEffect }); - } - - /** - * Sets the SimpleAudioLevelListener that this session should be - * notifying about changes in local audio level related information. This - * class only supports a single listener for audio changes per source - * (i.e. stream or data source). Audio changes are generally quite time - * intensive (~ 50 per second) so we are doing this in order to reduce the - * number of objects associated with the process (such as event instances - * listener list iterators and sync copies). - * - * @param listener the SimpleAudioLevelListener to add - */ - public void setLocalUserAudioLevelListener( - SimpleAudioLevelListener listener) - { - this.localUserAudioLevelEffect.setAudioLevelListener(listener); - } - - /** - * Sets listener as the SimpleAudioLevelListener that we - * are going to notify every time a change occurs in the audio level of - * the media that this device session is receiving from the remote party. - * This class only supports a single listener for audio changes per source - * (i.e. stream or data source). Audio changes are generally quite time - * intensive (~ 50 per second) so we are doing this in order to reduce the - * number of objects associated with the process (such as event instances - * listener list iterators and sync copies). - * - * @param listener the SimpleAudioLevelListener that we want - * notified for audio level changes in the remote participant's media. - */ - public void setStreamAudioLevelListener(SimpleAudioLevelListener listener) - { - this.streamAudioLevelEffect.setAudioLevelListener(listener); - } - - /** - * Returns the last audio level that was measured by this device session - * for the specified ssrc. - * - * @param ssrc the SSRC ID whose last measured audio level we'd like to - * retrieve. - * - * @return the audio level that was last measured for the specified - * ssrc or -1 if no level has been cached for that ID. - */ - public int getLastMeasuredAudioLevel(long ssrc) - { - return -1; - } - - /** - * Returns the last audio level that was measured by the underlying - * mixer for local user. - * - * @return the audio level that was last measured for the local user. - */ - public int getLastMeasuredLocalUserAudioLevel() - { - return -1; - } - - /** - * Copies the playback part of a specific MediaDeviceSession into - * this instance. - * - * @param deviceSession the MediaDeviceSession to copy the playback - * part of into this instance - */ - @Override - public void copyPlayback(MediaDeviceSession deviceSession) - { - AudioMediaDeviceSession amds = (AudioMediaDeviceSession) deviceSession; - - this.setStreamAudioLevelListener( - amds.streamAudioLevelEffect.getAudioLevelListener()); - this.setLocalUserAudioLevelListener( - amds.localUserAudioLevelEffect.getAudioLevelListener()); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/AudioMixerMediaDevice.java b/src/net/java/sip/communicator/impl/neomedia/device/AudioMixerMediaDevice.java deleted file mode 100644 index 295e59fe9..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/AudioMixerMediaDevice.java +++ /dev/null @@ -1,1239 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import java.io.*; -import java.net.*; -import java.util.*; -import java.beans.*; - -import javax.media.*; -import javax.media.protocol.*; -import javax.media.rtp.*; - -import net.java.sip.communicator.impl.neomedia.audiolevel.*; -import net.java.sip.communicator.impl.neomedia.conference.*; -import net.java.sip.communicator.impl.neomedia.protocol.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.event.*; -import net.java.sip.communicator.service.neomedia.format.*; -import net.java.sip.communicator.util.*; - -/** - * Implements a MediaDevice which performs audio mixing using - * {@link AudioMixer}. - * - * @author Lyubomir Marinov - * @author Emil Ivov - */ -public class AudioMixerMediaDevice - extends AbstractMediaDevice - implements MediaDeviceWrapper -{ - /** - * The Logger used by AudioMixerMediaDevice and its - * instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(AudioMixerMediaDevice.class); - - /** - * The AudioMixer which performs audio mixing in this - * MediaDevice (and rather the session that it represents). - */ - private AudioMixer audioMixer; - - /** - * The actual AudioMediaDeviceImpl wrapped by this instance for the - * purposes of audio mixing and used by {@link #audioMixer} as its - * CaptureDevice. - */ - private final AudioMediaDeviceImpl device; - - /** - * The MediaDeviceSession of this AudioMixer with - * {@link #device}. - */ - private AudioMixerMediaDeviceSession deviceSession; - - /** - * The SimpleAudioLevelListener which is registered (or is to be - * registered) with {@link #localUserAudioLevelDispatcher} and which - * delivers each of the audio level changes to - * {@link #localUserAudioLevelListeners}. - */ - private final SimpleAudioLevelListener localUserAudioLevelDelegate - = new SimpleAudioLevelListener() - { - public void audioLevelChanged(int level) - { - lastMeasuredLocalUserAudioLevel = level; - fireLocalUserAudioLevelChanged(level); - } - }; - - /** - * The dispatcher that delivers to listeners calculations of the local - * audio level. - */ - private final AudioLevelEventDispatcher localUserAudioLevelDispatcher - = new AudioLevelEventDispatcher( - "Local User Audio Level Dispatcher (Mixer Edition)"); - - /** - * The List where we store all listeners interested in changes of - * the local audio level and the number of times each one of them has been - * added. We wrap listeners because we may have multiple subscriptions with - * the same listener and we would only store it once. If one of the multiple - * subscriptions of a particular listener is removed, however, we wouldn't - * want to reset the listener to null as there are others still - * interested, and hence the referenceCount in the wrapper. - *

- * Note: localUserAudioLevelListeners is a copy-on-write - * storage and access to it is synchronized by - * {@link #localUserAudioLevelListenersSyncRoot}. - *

- */ - private List - localUserAudioLevelListeners - = new ArrayList(); - - /** - * The Object which synchronizes the access to - * {@link #localUserAudioLevelListeners}. - */ - private final Object localUserAudioLevelListenersSyncRoot = new Object(); - - /** - * The levels map that we use to cache last measured audio levels for all - * streams associated with this mixer. - */ - private final AudioLevelMap audioLevelCache = new AudioLevelMap(); - - /** - * The most recently measured level of the locally captured audio stream. - */ - private int lastMeasuredLocalUserAudioLevel = 0; - - /** - * The List of RTP extensions supported by this device (at the time - * of writing this list is only filled for audio devices and is - * null otherwise). - */ - private List rtpExtensions = null; - - /** - * The Map where we store audio level dispatchers and the - * streams they are interested in. - */ - private final Map - streamAudioLevelListeners - = new HashMap(); - - /** - * Initializes a new AudioMixerMediaDevice instance which is to - * enable audio mixing on a specific AudioMediaDeviceImpl. - * - * @param device the AudioMediaDeviceImpl which the new instance is - * to enable audio mixing on - */ - public AudioMixerMediaDevice(AudioMediaDeviceImpl device) - { - /* - * AudioMixer is initialized with a CaptureDevice so we have to be sure - * that the wrapped device can provide one. - */ - if (!device.getDirection().allowsSending()) - throw - new IllegalArgumentException("device must be able to capture"); - - this.device = device; - } - - /** - * Connects to a specific CaptureDevice given in the form of a - * DataSource. - * - * @param captureDevice the CaptureDevice to be connected to - * @throws IOException if anything wrong happens while connecting to the - * specified captureDevice - * @see AbstractMediaDevice#connect(DataSource) - */ - @Override - public void connect(DataSource captureDevice) - throws IOException - { - DataSource effectiveCaptureDevice = captureDevice; - - /* - * Unwrap wrappers of the captureDevice until - * AudioMixingPushBufferDataSource is found. - */ - if (captureDevice instanceof PushBufferDataSourceDelegate) - captureDevice - = ((PushBufferDataSourceDelegate) captureDevice) - .getDataSource(); - - /* - * AudioMixingPushBufferDataSource is definitely not a CaptureDevice - * and does not need the special connecting defined by - * AbstractMediaDevice and MediaDeviceImpl. - */ - if (captureDevice instanceof AudioMixingPushBufferDataSource) - effectiveCaptureDevice.connect(); - else - device.connect(effectiveCaptureDevice); - } - - /** - * Creates a DataSource instance for this MediaDevice - * which gives access to the captured media. - * - * @return a DataSource instance which gives access to the media - * captured by this MediaDevice - * @see AbstractMediaDevice#createOutputDataSource() - */ - public AudioMixingPushBufferDataSource createOutputDataSource() - { - return getAudioMixer().createOutputDataSource(); - } - - /** - * Initializes a new Renderer instance which is to play back media - * on this MediaDevice. - * - * @return a new Renderer instance which is to play back media on - * this MediaDevice or null if a suitable - * Renderer is to be chosen irrespective of this - * MediaDevice - */ - Renderer createRenderer() - { - return device.createRenderer(); - } - - /** - * Creates a new MediaDeviceSession instance which is to represent - * the use of this MediaDevice by a MediaStream. - * - * @return a new MediaDeviceSession instance which is to represent - * the use of this MediaDevice by a MediaStream - * @see AbstractMediaDevice#createSession() - */ - @Override - public synchronized MediaDeviceSession createSession() - { - if (deviceSession == null) - deviceSession = new AudioMixerMediaDeviceSession(); - return new MediaStreamMediaDeviceSession(deviceSession); - } - - /** - * Notifies the SimpleAudioLevelListeners registered with this - * instance about the new/current audio level of the local media stream. - * - * @param level the new/current audio level of the local media stream. - */ - private void fireLocalUserAudioLevelChanged(int level) - { - List localUserAudioLevelListeners; - - synchronized(localUserAudioLevelListenersSyncRoot) - { - /* - * It is safe to not copy the localUserAudioLevelListeners of this - * instance here because it is a copy-on-write storage. - */ - localUserAudioLevelListeners = this.localUserAudioLevelListeners; - } - - /* - * XXX These events are going to happen veeery often (~50 times per sec) - * and we'd like to avoid creating an iterator every time. - */ - int localUserAudioLevelListenerCount - = localUserAudioLevelListeners.size(); - - for(int i = 0; i < localUserAudioLevelListenerCount; i++) - localUserAudioLevelListeners.get(i).listener.audioLevelChanged( - level); - } - - /** - * Gets the AudioMixer which performs audio mixing in this - * MediaDevice (and rather the session it represents). If it still - * does not exist, it is created. - * - * @return the AudioMixer which performs audio mixing in this - * MediaDevice (and rather the session it represents) - */ - private synchronized AudioMixer getAudioMixer() - { - if (audioMixer == null) - audioMixer = new AudioMixer(device.createCaptureDevice()) - { - @Override - protected void connect( - DataSource dataSource, - DataSource inputDataSource) - throws IOException - { - /* - * CaptureDevice needs special connecting as defined by - * AbstractMediaDevice and, especially, MediaDeviceImpl. - */ - if (inputDataSource == captureDevice) - AudioMixerMediaDevice.this.connect(dataSource); - else - super.connect(dataSource, inputDataSource); - } - - @Override - protected void read( PushBufferStream stream, - Buffer buffer, - DataSource dataSource) - throws IOException - { - super.read(stream, buffer, dataSource); - - /* - * XXX The audio read from the specified stream has not been - * made available to the mixing yet. Slow code here is - * likely to degrade the performance of the whole mixer. - */ - if (dataSource == captureDevice) - { - /* - * The audio of the very CaptureDevice to be contributed - * to the mix. - */ - synchronized(localUserAudioLevelListenersSyncRoot) - { - if (localUserAudioLevelListeners.isEmpty()) - return; - } - - localUserAudioLevelDispatcher.addData(buffer); - - } - else if (dataSource - instanceof ReceiveStreamPushBufferDataSource) - { - /* - * The audio of a ReceiveStream to be contributed to the - * mix. - */ - ReceiveStream receiveStream - = ((ReceiveStreamPushBufferDataSource) dataSource) - .getReceiveStream(); - AudioLevelEventDispatcher streamEventDispatcher; - - synchronized (streamAudioLevelListeners) - { - streamEventDispatcher - = streamAudioLevelListeners.get(receiveStream); - } - - if ((streamEventDispatcher != null) - && !buffer.isDiscard() - && (buffer.getLength() > 0) - && (buffer.getData() != null)) - { - streamEventDispatcher.addData(buffer); - } - } - } - }; - return audioMixer; - } - - /** - * Returns the MediaDirection supported by this device. - * - * @return {@link MediaDirection#SENDONLY} if this is a read-only device, - * {@link MediaDirection#RECVONLY} if this is a write-only device or - * {@link MediaDirection#SENDRECV} if this MediaDevice can both - * capture and render media - * @see MediaDevice#getDirection() - */ - public MediaDirection getDirection() - { - return device.getDirection(); - } - - /** - * Gets the MediaFormat in which this MediaDevice
captures - * media. - * - * @return the MediaFormat in which this MediaDevice - * captures media - * @see MediaDevice#getFormat() - */ - public MediaFormat getFormat() - { - return device.getFormat(); - } - - /** - * Gets the MediaType that this device supports. - * - * @return {@link MediaType#AUDIO} if this is an audio device or - * {@link MediaType#VIDEO} if this is a video device - * @see MediaDevice#getMediaType() - */ - public MediaType getMediaType() - { - return device.getMediaType(); - } - - /** - * Returns a List containing (at the time of writing) a single - * extension descriptor indicating SENDRECV for mixer-to-client - * audio levels. - * - * @return a List containing the CSRC_AUDIO_LEVEL_URN - * extension descriptor. - */ - @Override - public List getSupportedExtensions() - { - if (rtpExtensions == null) - { - rtpExtensions = new ArrayList(1); - - URI csrcAudioLevelURN; - try - { - csrcAudioLevelURN = new URI(RTPExtension.CSRC_AUDIO_LEVEL_URN); - } - catch (URISyntaxException e) - { - // can't happen since CSRC_AUDIO_LEVEL_URN is a valid URI and - // never changes. - if (logger.isInfoEnabled()) - logger.info("Aha! Someone messed with the source!", e); - return null; - } - - rtpExtensions.add(new RTPExtension( - csrcAudioLevelURN, MediaDirection.SENDRECV)); - } - - return rtpExtensions; - } - - /** - * Gets the list of MediaFormats supported by this - * MediaDevice. - * - * @param sendPreset not used - * @param receivePreset not used - * @return the list of MediaFormats supported by this - * MediaDevice - * @see MediaDevice#getSupportedFormats() - */ - public List getSupportedFormats( - QualityPreset sendPreset, - QualityPreset receivePreset) - { - return device.getSupportedFormats(); - } - - /** - * Gets the actual MediaDevice which this MediaDevice is - * effectively built on top of and forwarding to. - * - * @return the actual MediaDevice which this MediaDevice - * is effectively built on top of and forwarding to - * @see MediaDeviceWrapper#getWrappedDevice() - */ - public MediaDevice getWrappedDevice() - { - return device; - } - - /** - * Removes the DataSource accepted by a specific - * DataSourceFilter from the list of input DataSource of - * the AudioMixer of this AudioMixerMediaDevice from - * which it reads audio to be mixed. - * - * @param dataSourceFilter the DataSourceFilter which selects the - * DataSources to be removed - */ - void removeInputDataSources(DataSourceFilter dataSourceFilter) - { - AudioMixer audioMixer = this.audioMixer; - - if (audioMixer != null) - audioMixer.removeInputDataSources(dataSourceFilter); - } - - /** - * Represents the one and only MediaDeviceSession with the - * MediaDevice of this AudioMixer - */ - private class AudioMixerMediaDeviceSession - extends MediaDeviceSession - { - /** - * The list of MediaDeviceSessions of MediaStreams - * which use this AudioMixer. - */ - private final List - mediaStreamMediaDeviceSessions - = new LinkedList(); - - /** - * Initializes a new AudioMixingMediaDeviceSession which is to - * represent the MediaDeviceSession of this AudioMixer - * with its MediaDevice - */ - public AudioMixerMediaDeviceSession() - { - super(AudioMixerMediaDevice.this); - } - - /** - * Adds l to the list of listeners that are being notified of - * new local audio levels as they change. If l is added - * multiple times it would only be registered once. - * - * @param l the listener we'd like to add. - */ - public void addLocalUserAudioLevelListener(SimpleAudioLevelListener l) - { - // If the listener is null, we have nothing more to do here. - if (l == null) - return; - - synchronized(localUserAudioLevelListenersSyncRoot) - { - //if this is the first listener that we are seeing then we also - //need to create the dispatcher. - if (localUserAudioLevelListeners.isEmpty()) - { - localUserAudioLevelDispatcher.setAudioLevelListener( - localUserAudioLevelDelegate); - } - - //check if this listener has already been added. - SimpleAudioLevelListenerWrapper wrapper - = new SimpleAudioLevelListenerWrapper(l); - int index = localUserAudioLevelListeners.indexOf(wrapper); - - if( index != -1) - { - wrapper = localUserAudioLevelListeners.get(index); - wrapper.referenceCount++; - } - else - { - /* - * XXX localUserAudioLevelListeners must be a copy-on-write - * storage so that firing events to its - * SimpleAudioLevelListeners can happen outside a block - * synchronized by localUserAudioLevelListenersSyncRoot and - * thus reduce the chances for a deadlock (which was, - * otherwise, observed in practice). - */ - localUserAudioLevelListeners - = new ArrayList( - localUserAudioLevelListeners); - localUserAudioLevelListeners.add(wrapper); - } - } - } - - /** - * Adds a specific MediaStreamMediaDeviceSession to the mix - * represented by this instance so that it knows when it is in use. - * - * @param mediaStreamMediaDeviceSession the - * MediaStreamMediaDeviceSession to be added to the mix - * represented by this instance - */ - void addMediaStreamMediaDeviceSession( - MediaStreamMediaDeviceSession mediaStreamMediaDeviceSession) - { - if (mediaStreamMediaDeviceSession == null) - throw new NullPointerException("mediaStreamMediaDeviceSession"); - - synchronized (mediaStreamMediaDeviceSessions) - { - if (!mediaStreamMediaDeviceSessions - .contains(mediaStreamMediaDeviceSession)) - mediaStreamMediaDeviceSessions - .add(mediaStreamMediaDeviceSession); - } - } - - /** - * Adds a specific DataSource providing remote audio to the mix - * produced by the associated MediaDevice. - * - * @param playbackDataSource the DataSource providing remote - * audio to be added to the mix produced by the associated - * MediaDevice - */ - @Override - public void addPlaybackDataSource(DataSource playbackDataSource) - { - /* - * We don't play back the contributions of the conference members - * separately, we have a single playback of the mix of all - * contributions but ours. - */ - super.addPlaybackDataSource( - (AudioMixingPushBufferDataSource) getCaptureDevice()); - } - - /** - * Adds a specific ReceiveStream to the list of - * ReceiveStreams known to this instance to be contributing - * audio to the mix produced by its associated AudioMixer. - * - * @param receiveStream the ReceiveStream to be added to the - * list of ReceiveStreams known to this instance to be - * contributing audio to the mix produced by its associated - * AudioMixer - */ - @Override - public void addReceiveStream(ReceiveStream receiveStream) - { - addSSRC(receiveStream.getSSRC()); - } - - /** - * Creates the DataSource that this instance is to read - * captured media from. Since this is the MediaDeviceSession of - * this AudioMixer with its MediaDevice, returns the - * localOutputDataSource of the AudioMixer i.e. the - * DataSource which represents the mix of all - * ReceiveStreams and excludes the captured data from the - * MediaDevice of the AudioMixer. - * - * @return the DataSource that this instance is to read - * captured media from - * @see MediaDeviceSession#createCaptureDevice() - */ - @Override - protected DataSource createCaptureDevice() - { - return getAudioMixer().getLocalOutputDataSource(); - } - - /** - * Sets listener as the list of listeners that will receive - * notifications of audio level event changes in the data arriving from - * stream. - * - * @param stream the stream that l would like to register as - * an audio level listener for. - * @param listener the listener we'd like to register for notifications - * from stream. - */ - public void setStreamAudioLevelListener( - ReceiveStream stream, - SimpleAudioLevelListener listener) - { - synchronized(streamAudioLevelListeners) - { - AudioLevelEventDispatcher dispatcher - = streamAudioLevelListeners.get(stream); - - if (listener == null) - { - if (dispatcher != null) - { - try - { - dispatcher.setAudioLevelListener(null); - dispatcher.setAudioLevelCache(null, -1); - } - finally - { - streamAudioLevelListeners.remove(dispatcher); - } - } - } - else - { - if (dispatcher == null) - { - dispatcher - = new AudioLevelEventDispatcher( - "Stream Audio Level Dispatcher" - + " (Mixer Edition)"); - dispatcher.setAudioLevelCache( - audioLevelCache, - stream.getSSRC()); - streamAudioLevelListeners.put(stream, dispatcher); - } - dispatcher.setAudioLevelListener(listener); - } - } - } - - /** - * Removes l from the list of listeners that are being - * notified of local audio levels.If l is not in the list, - * the method has no effect. - * - * @param l the listener we'd like to remove. - */ - public void removeLocalUserAudioLevelListener( - SimpleAudioLevelListener l) - { - synchronized(localUserAudioLevelListenersSyncRoot) - { - //check if this listener has already been added. - int index - = localUserAudioLevelListeners.indexOf( - new SimpleAudioLevelListenerWrapper(l)); - - if( index != -1) - { - SimpleAudioLevelListenerWrapper wrapper - = localUserAudioLevelListeners.get(index); - - if(wrapper.referenceCount > 1) - wrapper.referenceCount--; - else - { - /* - * XXX localUserAudioLevelListeners must be a - * copy-on-write storage so that firing events to its - * SimpleAudioLevelListeners can happen outside a block - * synchronized by localUserAudioLevelListenersSyncRoot - * and thus reduce the chances for a deadlock (whic - * was, otherwise, observed in practice). - */ - localUserAudioLevelListeners - = new ArrayList( - localUserAudioLevelListeners); - localUserAudioLevelListeners.remove(wrapper); - } - } - - //if this was the last listener then we also need to remove the - //dispatcher - if (localUserAudioLevelListeners.isEmpty()) - localUserAudioLevelDispatcher.setAudioLevelListener(null); - } - } - - /** - * Removes a specific MediaStreamMediaDeviceSession from the - * mix represented by this instance. When the last - * MediaStreamMediaDeviceSession is removed from this instance, - * it is no longer in use and closes itself thus signaling to its - * MediaDevice that it is no longer in use. - * - * @param mediaStreamMediaDeviceSession the - * MediaStreamMediaDeviceSession to be removed from the mix - * represented by this instance - */ - void removeMediaStreamMediaDeviceSession( - MediaStreamMediaDeviceSession mediaStreamMediaDeviceSession) - { - if (mediaStreamMediaDeviceSession != null) - { - synchronized (mediaStreamMediaDeviceSessions) - { - if (mediaStreamMediaDeviceSessions - .remove(mediaStreamMediaDeviceSession) - && mediaStreamMediaDeviceSessions.isEmpty()) - close(); - } - } - } - - /** - * Removes a specific DataSource providing remote audio from - * the mix produced by the associated AudioMixer. - * - * @param playbackDataSource the DataSource providing remote - * audio to be removed from the mix produced by the associated - * AudioMixer - */ - @Override - public void removePlaybackDataSource( - final DataSource playbackDataSource) - { - removeInputDataSources( - new DataSourceFilter() - { - public boolean accept(DataSource dataSource) - { - return dataSource.equals(playbackDataSource); - } - }); - } - - /** - * Removes a specific ReceiveStream from the list of - * ReceiveStreams known to this instance to be contributing - * audio to the mix produced by its associated AudioMixer. - * - * @param receiveStream the ReceiveStream to be removed from - * the list of ReceiveStreams known to this instance to be - * contributing audio to the mix produced by its associated - * AudioMixer - */ - @Override - public void removeReceiveStream(ReceiveStream receiveStream) - { - removeSSRC(receiveStream.getSSRC()); - - //make sure we no longer cache levels for that stream. - audioLevelCache.removeLevel(receiveStream.getSSRC()); - } - } - - /** - * Represents the work of a MediaStream with the - * MediaDevice of an AudioMixer and the contribution of - * that MediaStream to the mix. - */ - private static class MediaStreamMediaDeviceSession - extends AudioMediaDeviceSession - implements PropertyChangeListener - { - /** - * The MediaDeviceSession of the AudioMixer that this - * instance exposes to a MediaStream. While there are multiple - * MediaStreamMediaDeviceSessions each servicing a specific - * MediaStream, they all share and delegate to one and the same - * AudioMixerMediaDeviceSession so that they all contribute to - * the mix. - */ - private final AudioMixerMediaDeviceSession audioMixerMediaDeviceSession; - - /** - * We use this field to keep a reference to the listener that we've - * registered with the audio mixer for local audio level notifications. - * We use this reference so that we could unregister it if someone - * resets it or sets it to null. - */ - private SimpleAudioLevelListener localUserAudioLevelListener = null; - - /** - * We use this field to keep a reference to the listener that we've - * registered with the audio mixer for stream audio level notifications. - * We use this reference so because at the time we get it from the - * MediaStream it might be too early to register it with the - * mixer as it is like that we don't have a receive stream yet. If - * that's the case, we hold on to the listener and register it only - * when we get the ReceiveStream. - */ - private SimpleAudioLevelListener streamAudioLevelListener = null; - - /** - * The Object that we use to lock operations on - * streamAudioLevelListener. - */ - private final Object streamAudioLevelListenerLock = new Object(); - - /** - * Initializes a new MediaStreamMediaDeviceSession which is to - * represent the work of a MediaStream with the - * MediaDevice of this AudioMixer and its contribution - * to the mix. - * - * @param audioMixerMediaDeviceSession the MediaDeviceSession - * of the AudioMixer with its MediaDevice which the - * new instance is to delegate to in order to contribute to the mix - */ - public MediaStreamMediaDeviceSession( - AudioMixerMediaDeviceSession audioMixerMediaDeviceSession) - { - super(audioMixerMediaDeviceSession.getDevice()); - - this.audioMixerMediaDeviceSession = audioMixerMediaDeviceSession; - this.audioMixerMediaDeviceSession - .addMediaStreamMediaDeviceSession(this); - - this.audioMixerMediaDeviceSession.addPropertyChangeListener(this); - } - - /** - * Releases the resources allocated by this instance in the course of - * its execution and prepares it to be garbage collected. - * - * @see MediaDeviceSession#close() - */ - @Override - public void close() - { - try - { - super.close(); - } - finally - { - audioMixerMediaDeviceSession - .removeMediaStreamMediaDeviceSession(this); - } - } - - /** - * Creates a new Player for a specific DataSource so - * that it is played back on the MediaDevice represented by - * this instance. - * - * @param dataSource the DataSource to create a new - * Player for - * @return a new Player for the specified dataSource - * @see MediaDeviceSession#createPlayer(DataSource) - */ - @Override - protected Player createPlayer(DataSource dataSource) - { - /* - * We don't want the contribution of each conference member played - * back separately, we want the one and only mix of all - * contributions but ours to be played back once for all of them. - */ - return null; - } - - /** - * Returns the list of SSRC identifiers that are directly contributing - * to the media flows that we are sending out. Note that since this is - * a pseudo device we would simply be delegating the call to the - * corresponding method of the master mixer device session. - * - * @return a long[] array of SSRC identifiers that are - * currently contributing to the mixer encapsulated by this device - * session. - */ - @Override - public long[] getRemoteSSRCList() - { - return audioMixerMediaDeviceSession.getRemoteSSRCList(); - } - - /** - * Notifies this MediaDeviceSession that a DataSource - * has been added for playback on the represented MediaDevice. - * - * @param playbackDataSource the DataSource which has been - * added for playback on the represented MediaDevice - * @see MediaDeviceSession#playbackDataSourceAdded(DataSource) - */ - @Override - protected void playbackDataSourceAdded(DataSource playbackDataSource) - { - super.playbackDataSourceAdded(playbackDataSource); - - DataSource captureDevice = getCaptureDevice(); - - /* - * Unwrap wrappers of the captureDevice until - * AudioMixingPushBufferDataSource is found. - */ - if (captureDevice instanceof PushBufferDataSourceDelegate) - captureDevice - = ((PushBufferDataSourceDelegate) captureDevice) - .getDataSource(); - if (captureDevice instanceof AudioMixingPushBufferDataSource) - ((AudioMixingPushBufferDataSource) captureDevice) - .addInputDataSource(playbackDataSource); - - audioMixerMediaDeviceSession.addPlaybackDataSource( - playbackDataSource); - } - - /** - * Notifies this MediaDeviceSession that a DataSource - * has been removed from playback on the represented - * MediaDevice. - * - * @param playbackDataSource the DataSource which has been - * removed from playback on the represented MediaDevice - * @see MediaDeviceSession#playbackDataSourceRemoved(DataSource) - */ - @Override - protected void playbackDataSourceRemoved(DataSource playbackDataSource) - { - super.playbackDataSourceRemoved(playbackDataSource); - - audioMixerMediaDeviceSession.removePlaybackDataSource( - playbackDataSource); - } - - /** - * The method relays PropertyChangeEvents indicating a change - * in the SSRC_LIST in the encapsulated mixer device so that the - * MediaStream that uses this device session can update its - * CSRC list. - * - * @param evt that PropertyChangeEvent whose old and new value - * we will be relaying to the stream. - */ - public void propertyChange(PropertyChangeEvent evt) - { - if (MediaDeviceSession.SSRC_LIST.equals(evt.getPropertyName())) - firePropertyChange( - MediaDeviceSession.SSRC_LIST, - evt.getOldValue(), - evt.getNewValue()); - } - - /** - * Notifies this instance that a specific ReceiveStream has - * been added to the list of playbacks of ReceiveStreams and/or - * DataSources performed by respective Players on the - * MediaDevice represented by this instance. - * - * @param receiveStream the ReceiveStream which has been added - * to the list of playbacks of ReceiveStreams and/or - * DataSources performed by respective Players on the - * MediaDevice represented by this instance - */ - @Override - protected void receiveStreamAdded(ReceiveStream receiveStream) - { - super.receiveStreamAdded(receiveStream); - - /* - * If someone registered a stream level listener, we can now add it - * since we have the stream that it's supposed to listen to. - */ - synchronized(streamAudioLevelListenerLock) - { - if(this.streamAudioLevelListener != null) - audioMixerMediaDeviceSession.setStreamAudioLevelListener( - receiveStream, - streamAudioLevelListener); - } - - audioMixerMediaDeviceSession.addReceiveStream(receiveStream); - } - - /** - * Notifies this instance that a specific ReceiveStream has - * been removed from the list of playbacks of ReceiveStreams - * and/or DataSources performed by respective Players - * on the MediaDevice represented by this instance. - * - * @param receiveStream the ReceiveStream which has been - * removed from the list of playbacks of ReceiveStreams and/or - * DataSources performed by respective Players on the - * MediaDevice represented by this instance - */ - @Override - protected void receiveStreamRemoved(ReceiveStream receiveStream) - { - super.receiveStreamRemoved(receiveStream); - - audioMixerMediaDeviceSession.removeReceiveStream(receiveStream); - } - - /** - * Override it here cause we won't register effects to that stream - * cause we already have one. - * - * @param processor the processor. - */ - @Override - protected void registerLocalUserAudioLevelEffect(Processor processor) - { - } - - /** - * Adds a specific SoundLevelListener to the list of listeners - * interested in and notified about changes in local sound level related - * information. - * @param l the SoundLevelListener to add - */ - @Override - public void setLocalUserAudioLevelListener(SimpleAudioLevelListener l) - { - if (localUserAudioLevelListener != null) - { - audioMixerMediaDeviceSession.removeLocalUserAudioLevelListener( - localUserAudioLevelListener); - localUserAudioLevelListener = null; - } - - if (l != null) - { - this.localUserAudioLevelListener = l; - - // add the listener only if we are not muted - // this happens when holding a conversation, stream is muted - // and when recreated listener is again set - if(!isMute()) - audioMixerMediaDeviceSession.addLocalUserAudioLevelListener( - l); - } - } - - /** - * Adds listener to the list of - * SimpleAudioLevelListeners registered with the mixer session - * that this "slave session" encapsulates. This class does not keep a - * reference to listener. - * - * @param listener the SimpleAudioLevelListener that we are to - * pass to the mixer device session or null if we are trying - * to unregister it. - */ - @Override - public void setStreamAudioLevelListener( - SimpleAudioLevelListener listener) - { - synchronized(streamAudioLevelListenerLock) - { - this.streamAudioLevelListener = listener; - - for (ReceiveStream receiveStream : getReceiveStreams()) - { - /* - * If we already have a ReceiveStream, register the listener - * with the mixer; otherwise, wait till we get one. - */ - audioMixerMediaDeviceSession.setStreamAudioLevelListener( - receiveStream, - listener); - } - } - } - - /** - * Returns the last audio level that was measured by the underlying - * mixer for the specified csrc. - * - * @param csrc the CSRC ID whose last measured audio level we'd like to - * retrieve. - * - * @return the audio level that was last measured by the underlying - * mixer for the specified csrc or -1 if the - * csrc does not belong to neither of the conference - * participants. - */ - @Override - public int getLastMeasuredAudioLevel(long csrc) - { - return - ((AudioMixerMediaDevice) getDevice()).audioLevelCache.getLevel( - csrc); - } - - /** - * Returns the last audio level that was measured by the underlying - * mixer for local user. - * - * @return the audio level that was last measured for the local user. - */ - @Override - public int getLastMeasuredLocalUserAudioLevel() - { - return - ((AudioMixerMediaDevice) getDevice()) - .lastMeasuredLocalUserAudioLevel; - } - - /** - * Sets the indicator which determines whether this - * MediaDeviceSession is set to output "silence" instead of the - * actual media fed from its CaptureDevice. - * If we are muted we just remove the local level listener from the - * session. - * - * @param mute true to set this MediaDeviceSession to - * output "silence" instead of the actual media fed from its - * CaptureDevice; otherwise, false - */ - @Override - public void setMute(boolean mute) - { - boolean oldValue = isMute(); - - super.setMute(mute); - - boolean newValue = isMute(); - - if (oldValue != newValue) - { - if (newValue) - { - audioMixerMediaDeviceSession - .removeLocalUserAudioLevelListener( - localUserAudioLevelListener); - } - else - { - audioMixerMediaDeviceSession - .addLocalUserAudioLevelListener( - localUserAudioLevelListener); - } - } - } - } - - /** - * A very lightweight wrapper that allows us to track the number of times - * that a particular listener was added. - */ - private static class SimpleAudioLevelListenerWrapper - { - /** The listener being wrapped by this wrapper. */ - public final SimpleAudioLevelListener listener; - - /** The number of times this listener has been added. */ - int referenceCount; - - /** - * Creates a wrapper of the l listener. - * - * @param l the listener we'd like to wrap; - */ - public SimpleAudioLevelListenerWrapper(SimpleAudioLevelListener l) - { - this.listener = l; - this.referenceCount = 1; - } - - /** - * Returns true if obj is a wrapping the same listener - * as ours. - * - * @param obj the wrapper we'd like to compare to this instance - * - * @return true if obj is a wrapping the same listener - * as ours. - */ - @Override - public boolean equals(Object obj) - { - return (obj instanceof SimpleAudioLevelListenerWrapper) - && ((SimpleAudioLevelListenerWrapper)obj).listener == listener; - } - - /** - * Returns a hash code value for this instance for the benefit of - * hashtables. - * - * @return a hash code value for this instance for the benefit of - * hashtables - */ - @Override - public int hashCode() - { - /* - * Equality is based on the listener field only so its hashCode is - * enough. Besides, it's the only immutable of this instance i.e. - * the only field appropriate for the calculation of the hashCode. - */ - return listener.hashCode(); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/AudioSystem.java b/src/net/java/sip/communicator/impl/neomedia/device/AudioSystem.java deleted file mode 100644 index fcf70e977..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/AudioSystem.java +++ /dev/null @@ -1,505 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import java.io.*; -import java.util.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.neomedia.*; - -public abstract class AudioSystem - extends DeviceSystem -{ - public static final int FEATURE_DENOISE = 2; - - public static final int FEATURE_ECHO_CANCELLATION = 4; - - public static final int FEATURE_NOTIFY_AND_PLAYBACK_DEVICES = 8; - - private static final int FLAG_CAPTURE_DEVICE_IS_NULL = 1; - - private static final int FLAG_NOTIFY_DEVICE_IS_NULL = 2; - - private static final int FLAG_PLAYBACK_DEVICE_IS_NULL = 4; - - public static final String LOCATOR_PROTOCOL_AUDIORECORD = "audiorecord"; - - public static final String LOCATOR_PROTOCOL_JAVASOUND = "javasound"; - - public static final String LOCATOR_PROTOCOL_OPENSLES = "opensles"; - - public static final String LOCATOR_PROTOCOL_PORTAUDIO = "portaudio"; - - public static final String LOCATOR_PROTOCOL_PULSEAUDIO = "pulseaudio"; - - public static final String PROP_CAPTURE_DEVICE = "captureDevice"; - - public static final String PROP_NOTIFY_DEVICE = "notifyDevice"; - - public static final String PROP_PLAYBACK_DEVICE = "playbackDevice"; - - public static AudioSystem getAudioSystem(String locatorProtocol) - { - AudioSystem[] audioSystems = getAudioSystems(); - AudioSystem audioSystemWithLocatorProtocol = null; - - if (audioSystems != null) - { - for (AudioSystem audioSystem : audioSystems) - { - if (audioSystem.getLocatorProtocol().equalsIgnoreCase( - locatorProtocol)) - { - audioSystemWithLocatorProtocol = audioSystem; - break; - } - } - } - return audioSystemWithLocatorProtocol; - } - - public static AudioSystem[] getAudioSystems() - { - DeviceSystem[] deviceSystems - = DeviceSystem.getDeviceSystems(MediaType.AUDIO); - List audioSystems; - - if (deviceSystems == null) - audioSystems = null; - else - { - audioSystems = new ArrayList(deviceSystems.length); - for (DeviceSystem deviceSystem : deviceSystems) - if (deviceSystem instanceof AudioSystem) - audioSystems.add((AudioSystem) deviceSystem); - } - return - (audioSystems == null) - ? null - : audioSystems.toArray(new AudioSystem[audioSystems.size()]); - } - - private CaptureDeviceInfo captureDevice; - - private int flags; - - private CaptureDeviceInfo notifyDevice; - - private CaptureDeviceInfo playbackDevice; - - private List playbackDevices; - - protected AudioSystem(String locatorProtocol) - throws Exception - { - this(locatorProtocol, 0); - } - - protected AudioSystem(String locatorProtocol, int features) - throws Exception - { - super(MediaType.AUDIO, locatorProtocol, features); - } - - public CaptureDeviceInfo getCaptureDevice() - { - List captureDevices = null; - - if (this.captureDevice != null) - { - if (captureDevices == null) - captureDevices = getCaptureDevices(); - if ((captureDevices == null) - || !captureDevices.contains(this.captureDevice)) - setCaptureDevice(null, false); - } - - CaptureDeviceInfo captureDevice = this.captureDevice; - - if ((captureDevice == null) - && ((flags & FLAG_CAPTURE_DEVICE_IS_NULL) == 0)) - { - if (captureDevices == null) - captureDevices = getCaptureDevices(); - if ((captureDevices != null) && (captureDevices.size() > 0)) - { - captureDevice = loadDevice(PROP_CAPTURE_DEVICE, captureDevices); - if (captureDevice == null) - captureDevice = captureDevices.get(0); - } - } - return captureDevice; - } - - public List getCaptureDevices() - { - MediaServiceImpl mediaServiceImpl - = NeomediaActivator.getMediaServiceImpl(); - DeviceConfiguration deviceConfiguration - = (mediaServiceImpl == null) - ? null - : mediaServiceImpl.getDeviceConfiguration(); - List deviceList; - - if (deviceConfiguration == null) - { - /* - * XXX The initialization of MediaServiceImpl is very complex so it - * is wise to not reference it at the early stage of its - * initialization. The same goes for DeviceConfiguration. If for - * some reason one of the two is not available at this time, just - * fall back go something that makes sense. - */ - @SuppressWarnings("unchecked") - Vector audioCaptureDeviceInfos - = CaptureDeviceManager.getDeviceList( - new AudioFormat(AudioFormat.LINEAR, -1, 16, -1)); - - deviceList = audioCaptureDeviceInfos; - } - else - { - deviceList = deviceConfiguration.getAvailableAudioCaptureDevices(); - } - - return - filterDeviceListByLocatorProtocol(deviceList, getLocatorProtocol()); - } - - public CaptureDeviceInfo getNotifyDevice() - { - List notifyDevices = null; - - if (this.notifyDevice != null) - { - if (notifyDevices == null) - notifyDevices = getNotifyDevices(); - if ((notifyDevices == null) - || !notifyDevices.contains(this.notifyDevice)) - setNotifyDevice(null, false); - } - - CaptureDeviceInfo notifyDevice = this.notifyDevice; - - if ((notifyDevice == null) - && ((flags & FLAG_NOTIFY_DEVICE_IS_NULL) == 0)) - { - if (notifyDevices == null) - notifyDevices = getNotifyDevices(); - if ((notifyDevices != null) && (notifyDevices.size() > 0)) - { - notifyDevice = loadDevice(PROP_NOTIFY_DEVICE, notifyDevices); - if (notifyDevice == null) - notifyDevice = notifyDevices.get(0); - } - } - return notifyDevice; - } - - public List getNotifyDevices() - { - return getPlaybackDevices(); - } - - public CaptureDeviceInfo getPlaybackDevice() - { - List playbackDevices = null; - - if (this.playbackDevice != null) - { - if (playbackDevices == null) - playbackDevices = getPlaybackDevices(); - if ((playbackDevices == null) - || !playbackDevices.contains(this.playbackDevice)) - setPlaybackDevice(null, false); - } - - CaptureDeviceInfo playbackDevice = this.playbackDevice; - - if ((playbackDevice == null) - && ((flags & FLAG_PLAYBACK_DEVICE_IS_NULL) == 0)) - { - if (playbackDevices == null) - playbackDevices = getPlaybackDevices(); - if ((playbackDevices != null) && (playbackDevices.size() > 0)) - { - playbackDevice - = loadDevice(PROP_PLAYBACK_DEVICE, playbackDevices); - if (playbackDevice == null) - playbackDevice = playbackDevices.get(0); - } - } - return playbackDevice; - } - - public List getPlaybackDevices() - { - List playbackDevices = this.playbackDevices; - - return - (playbackDevices == null) - ? null - : new ArrayList(playbackDevices); - } - - /** - * Loads the user's preference with respect to a CaptureDeviceInfo - * among a specific list of CaptureDeviceInfos from the - * ConfigurationService. - * - * @param property the name of the ConfigurationService property - * which specifies the user's preference with respect to a - * CaptureDeviceInfo among the specified list of - * CaptureDeviceInfos - * @param devices the list of CaptureDeviceInfos which are valid - * selections for the user's preference - * @return a CaptureDeviceInfo among the specified devices - * which represents the user's preference stored in the - * ConfigurationService - */ - private CaptureDeviceInfo loadDevice( - String property, - List devices) - { - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - - if (cfg != null) - { - property - = DeviceConfiguration.PROP_AUDIO_SYSTEM - + "." - + getLocatorProtocol() - + "." - + property; - - String name = cfg.getString(property); - - if ((name != null) - && !NoneAudioSystem.LOCATOR_PROTOCOL.equalsIgnoreCase(name)) - { - for (CaptureDeviceInfo device : devices) - if (name.equals(device.getName())) - return device; - } - } - return null; - } - - @Override - protected void postInitialize() - { - try - { - super.postInitialize(); - } - finally - { - try - { - if (captureDevice != null) - { - List captureDevices = getCaptureDevices(); - - if ((captureDevices == null) - || !captureDevices.contains(captureDevice)) - setCaptureDevice(null, false); - } - } - finally - { - if ((FEATURE_NOTIFY_AND_PLAYBACK_DEVICES & getFeatures()) != 0) - { - try - { - if (notifyDevice != null) - { - List notifyDevices - = getNotifyDevices(); - - if ((notifyDevices == null) - || !notifyDevices.contains(notifyDevice)) - setNotifyDevice(null, false); - } - } - finally - { - if (playbackDevice != null) - { - List playbackDevices - = getPlaybackDevices(); - - if ((playbackDevices == null) - || !playbackDevices.contains( - playbackDevice)) - setPlaybackDevice(null, false); - } - } - } - } - } - } - - /** - * Saves the user's preference with respect to a specific - * CaptureDeviceInfo in the ConfigurationService. - * - * @param property the name of the ConfigurationService property - * into which the user's preference with respect to the specified - * CaptureDeviceInfo is to be saved - * @param device the CaptureDeviceInfo which is the user's - * preference - * @param isNull true if the user's preference with respect to the - * specified device is null; otherwise, false - */ - private void saveDevice( - String property, - CaptureDeviceInfo device, - boolean isNull) - { - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - - if (cfg != null) - { - property - = DeviceConfiguration.PROP_AUDIO_SYSTEM - + "." - + getLocatorProtocol() - + "." - + property; - if (device == null) - { - if (isNull) - cfg.setProperty(property, NoneAudioSystem.LOCATOR_PROTOCOL); - else - cfg.removeProperty(property); - } - else - cfg.setProperty(property, device.getName()); - } - } - - public void setCaptureDevice(CaptureDeviceInfo captureDevice, boolean save) - { - if ((this.captureDevice != captureDevice) || (captureDevice == null)) - { - CaptureDeviceInfo oldValue = this.captureDevice; - - this.captureDevice = captureDevice; - - if (save) - { - boolean isNull = (this.captureDevice == null); - - if (isNull) - flags |= FLAG_CAPTURE_DEVICE_IS_NULL; - else - flags &= ~FLAG_CAPTURE_DEVICE_IS_NULL; - - saveDevice(PROP_CAPTURE_DEVICE, this.captureDevice, isNull); - } - - CaptureDeviceInfo newValue = getCaptureDevice(); - - if (oldValue != newValue) - firePropertyChange(PROP_CAPTURE_DEVICE, oldValue, newValue); - } - } - - protected void setCaptureDevices(List captureDevices) - { - if (captureDevices != null) - { - boolean commit = false; - - for (CaptureDeviceInfo captureDevice : captureDevices) - { - CaptureDeviceManager.addDevice(captureDevice); - commit = true; - } - if (commit && !MediaServiceImpl.isJmfRegistryDisableLoad()) - { - try - { - CaptureDeviceManager.commit(); - } - catch (IOException ioe) - { - // Whatever. - } - } - } - } - - public void setNotifyDevice(CaptureDeviceInfo notifyDevice, boolean save) - { - if ((this.notifyDevice != notifyDevice) || (notifyDevice == null)) - { - CaptureDeviceInfo oldValue = this.notifyDevice; - - this.notifyDevice = notifyDevice; - - if (save) - { - boolean isNull = (this.notifyDevice == null); - - if (isNull) - flags |= FLAG_NOTIFY_DEVICE_IS_NULL; - else - flags &= ~FLAG_NOTIFY_DEVICE_IS_NULL; - - saveDevice(PROP_NOTIFY_DEVICE, this.notifyDevice, isNull); - } - - CaptureDeviceInfo newValue = getNotifyDevice(); - - if (oldValue != newValue) - firePropertyChange(PROP_NOTIFY_DEVICE, oldValue, newValue); - } - } - - public void setPlaybackDevice( - CaptureDeviceInfo playbackDevice, - boolean save) - { - if ((this.playbackDevice != playbackDevice) || (playbackDevice == null)) - { - CaptureDeviceInfo oldValue = this.playbackDevice; - - this.playbackDevice = playbackDevice; - - if (save) - { - boolean isNull = (this.playbackDevice == null); - - if (isNull) - flags |= FLAG_PLAYBACK_DEVICE_IS_NULL; - else - flags &= ~FLAG_PLAYBACK_DEVICE_IS_NULL; - - saveDevice(PROP_PLAYBACK_DEVICE, this.playbackDevice, isNull); - } - - CaptureDeviceInfo newValue = getPlaybackDevice(); - - if (oldValue != newValue) - firePropertyChange(PROP_PLAYBACK_DEVICE, oldValue, newValue); - } - } - - protected void setPlaybackDevices(List playbackDevices) - { - this.playbackDevices - = (playbackDevices == null) - ? null - : new ArrayList(playbackDevices); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/DeviceConfiguration.java b/src/net/java/sip/communicator/impl/neomedia/device/DeviceConfiguration.java deleted file mode 100644 index 409f34c4f..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/DeviceConfiguration.java +++ /dev/null @@ -1,1131 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import java.awt.*; -import java.beans.*; -import java.io.*; -import java.util.*; -import java.util.List; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.codec.video.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.util.*; -import net.java.sip.communicator.util.event.*; - -/** - * This class aims to provide a simple configuration interface for JMF. It - * retrieves stored configuration when started or listens to ConfigurationEvent - * for property changes and configures the JMF accordingly. - * - * @author Martin Andre - * @author Emil Ivov - * @author Lyubomir Marinov - */ -public class DeviceConfiguration - extends PropertyChangeNotifier - implements PropertyChangeListener -{ - - /** - * The name of the DeviceConfiguration property which represents - * the device used by DeviceConfiguration for audio capture. - */ - public static final String AUDIO_CAPTURE_DEVICE - = AudioSystem.PROP_CAPTURE_DEVICE; - - /** - * The name of the DeviceConfiguration property which represents - * the device used by DeviceConfiguration for audio notify. - */ - public static final String AUDIO_NOTIFY_DEVICE - = AudioSystem.PROP_NOTIFY_DEVICE; - - /** - * The name of the DeviceConfiguration property which represents - * the device used by DeviceConfiguration for audio playback. - */ - public static final String AUDIO_PLAYBACK_DEVICE - = AudioSystem.PROP_PLAYBACK_DEVICE; - - /** - * The list of class names of custom Renderer implementations to be - * registered with JMF. - */ - private static final String[] CUSTOM_RENDERERS - = new String[] - { - OSUtils.IS_ANDROID ? ".audio.AudioTrackRenderer" : null, - OSUtils.IS_ANDROID ? ".audio.OpenSLESRenderer" : null, - OSUtils.IS_LINUX ? ".audio.PulseAudioRenderer" : null, - OSUtils.IS_ANDROID ? null : ".audio.PortAudioRenderer", - ".video.JAWTRenderer" - }; - - /** - * The default value to be used for the {@link #PROP_AUDIO_DENOISE} property - * when it does not have a value. - */ - public static final boolean DEFAULT_AUDIO_DENOISE = true; - - /** - * The default value to be used for the {@link #PROP_AUDIO_ECHOCANCEL} - * property when it does not have a value. - */ - public static final boolean DEFAULT_AUDIO_ECHOCANCEL = true; - - /** - * The default value to be used for the - * {@link #PROP_AUDIO_ECHOCANCEL_FILTER_LENGTH_IN_MILLIS} property when it - * does not have a value. The recommended filter length is approximately the - * third of the room reverberation time. For example, in a small room, - * reverberation time is in the order of 300 ms, so a filter length of 100 - * ms is a good choice (800 samples at 8000 Hz sampling rate). - */ - public static final long DEFAULT_AUDIO_ECHOCANCEL_FILTER_LENGTH_IN_MILLIS - = 100; - - /** - * The default frame rate, -1 unlimited. - */ - public static final int DEFAULT_VIDEO_FRAMERATE = -1; - - /** - * The default video height. - */ - public static final int DEFAULT_VIDEO_HEIGHT = 480; - - /** - * The default value for video maximum bandwidth. - */ - public static final int DEFAULT_VIDEO_MAX_BANDWIDTH = 256; - - /** - * The default video width. - */ - public static final int DEFAULT_VIDEO_WIDTH = 640; - - /** - * The name of the boolean property which determines whether noise - * suppression is to be performed for captured audio. - */ - static final String PROP_AUDIO_DENOISE - = "net.java.sip.communicator.impl.neomedia.denoise"; - - /** - * The name of the boolean property which determines whether echo - * cancellation is to be performed for captured audio. - */ - static final String PROP_AUDIO_ECHOCANCEL - = "net.java.sip.communicator.impl.neomedia.echocancel"; - - /** - * The name of the long property which determines the filter length - * in milliseconds to be used by the echo cancellation implementation. The - * recommended filter length is approximately the third of the room - * reverberation time. For example, in a small room, reverberation time is - * in the order of 300 ms, so a filter length of 100 ms is a good choice - * (800 samples at 8000 Hz sampling rate). - */ - static final String PROP_AUDIO_ECHOCANCEL_FILTER_LENGTH_IN_MILLIS - = "net.java.sip.communicator.impl.neomedia.echocancel.filterLengthInMillis"; - - public static final String PROP_AUDIO_SYSTEM - = "net.java.sip.communicator.impl.neomedia.audioSystem"; - - public static final String PROP_AUDIO_SYSTEM_DEVICES - = PROP_AUDIO_SYSTEM + "." + DeviceSystem.PROP_DEVICES; - - /** - * The ConfigurationService property which stores the device used - * by DeviceConfiguration for video capture. - */ - private static final String PROP_VIDEO_DEVICE - = "net.java.sip.communicator.impl.neomedia.videoDevice"; - - /** - * The property we use to store the video framerate settings. - */ - private static final String PROP_VIDEO_FRAMERATE - = "net.java.sip.communicator.impl.neomedia.video.framerate"; - - /** - * The name of the property which specifies the height of the video. - */ - private static final String PROP_VIDEO_HEIGHT - = "net.java.sip.communicator.impl.neomedia.video.height"; - - /** - * The property we use to store the settings for maximum allowed video - * bandwidth. - */ - private static final String PROP_VIDEO_MAX_BANDWIDTH - = "net.java.sip.communicator.impl.neomedia.video.maxbandwidth"; - - /** - * The name of the property which specifies the width of the video. - */ - private static final String PROP_VIDEO_WIDTH - = "net.java.sip.communicator.impl.neomedia.video.width"; - - /** - * The currently supported resolutions we will show as option - * and user can select. - */ - public static final Dimension[] SUPPORTED_RESOLUTIONS - = new Dimension[] - { - // QVGA - new Dimension(160, 100), - //QCIF - new Dimension(176, 144), - // QVGA - new Dimension(320, 200), - // QVGA - new Dimension(320, 240), - //CIF - new Dimension(352, 288), - // VGA - new Dimension(640, 480), - // HD 720 - new Dimension(1280, 720) - }; - - /** - * The name of the DeviceConfiguration property which - * represents the device used by DeviceConfiguration for video - * capture. - */ - public static final String VIDEO_CAPTURE_DEVICE = "VIDEO_CAPTURE_DEVICE"; - - private AudioSystem audioSystem; - - /** - * The frame rate. - */ - private int frameRate = DEFAULT_VIDEO_FRAMERATE; - - /** - * The Logger used by this instance for logging output. - */ - private Logger logger = Logger.getLogger(DeviceConfiguration.class); - - /** - * The device that we'll be using for video capture. - */ - private CaptureDeviceInfo videoCaptureDevice; - - /** - * Current setting for video maximum bandwidth. - */ - private int videoMaxBandwidth = -1; - - /** - * The current resolution settings. - */ - private Dimension videoSize; - - /** - * Initializes a new DeviceConfiguration instance. - */ - public DeviceConfiguration() - { - // these seem to be throwing exceptions every now and then so we'll - // blindly catch them for now - try - { - DeviceSystem.initializeDeviceSystems(); - extractConfiguredCaptureDevices(); - - ConfigurationService cfg - = NeomediaActivator.getConfigurationService(); - - if (cfg != null) - { - cfg.addPropertyChangeListener(PROP_VIDEO_HEIGHT, this); - cfg.addPropertyChangeListener(PROP_VIDEO_WIDTH, this); - cfg.addPropertyChangeListener(PROP_VIDEO_FRAMERATE, this); - cfg.addPropertyChangeListener(PROP_VIDEO_MAX_BANDWIDTH, this); - } - } - catch (Exception ex) - { - logger.error("Failed to initialize media.", ex); - } - - registerCustomRenderers(); - fixRenderers(); - } - - /** - * Fixes the list of Renderers registered with FMJ in order to - * resolve operating system-specific issues. - */ - private static void fixRenderers() - { - @SuppressWarnings("unchecked") - Vector renderers - = PlugInManager.getPlugInList(null, null, PlugInManager.RENDERER); - - /* - * JMF is no longer in use, FMJ is used in its place. FMJ has its own - * JavaSoundRenderer which is also extended into a JMF-compatible one. - */ - PlugInManager.removePlugIn( - "com.sun.media.renderer.audio.JavaSoundRenderer", - PlugInManager.RENDERER); - - if (OSUtils.IS_WINDOWS) - { - if (OSUtils.IS_WINDOWS32 && - (OSUtils.IS_WINDOWS_VISTA || OSUtils.IS_WINDOWS_7)) - { - /* - * DDRenderer will cause 32-bit Windows Vista/7 to switch its - * theme from Aero to Vista Basic so try to pick up a different - * Renderer. - */ - if (renderers.contains( - "com.sun.media.renderer.video.GDIRenderer")) - { - PlugInManager.removePlugIn( - "com.sun.media.renderer.video.DDRenderer", - PlugInManager.RENDERER); - } - } - else if (OSUtils.IS_WINDOWS64) - { - /* - * Remove the native Renderers for 64-bit Windows because native - * JMF libs are not available for 64-bit machines. - */ - PlugInManager.removePlugIn( - "com.sun.media.renderer.video.GDIRenderer", - PlugInManager.RENDERER); - PlugInManager.removePlugIn( - "com.sun.media.renderer.video.DDRenderer", - PlugInManager.RENDERER); - } - } - else if (!OSUtils.IS_LINUX32) - { - if (renderers.contains( - "com.sun.media.renderer.video.LightWeightRenderer") - || renderers.contains( - "com.sun.media.renderer.video.AWTRenderer")) - { - // Remove XLibRenderer because it is native and JMF is supported - // on 32-bit machines only. - PlugInManager.removePlugIn( - "com.sun.media.renderer.video.XLibRenderer", - PlugInManager.RENDERER); - } - } - } - - /** - * Detects capture devices configured through JMF and disable audio and/or - * video transmission if none were found. - */ - private void extractConfiguredCaptureDevices() - { - extractConfiguredAudioCaptureDevices(); - extractConfiguredVideoCaptureDevices(); - } - - /** - * Returns the configured video capture device with the specified - * output format. - * @param format the output format of the video format. - * @return CaptureDeviceInfo for the video device. - */ - private CaptureDeviceInfo extractConfiguredVideoCaptureDevice(Format format) - { - @SuppressWarnings("unchecked") - List videoCaptureDevices - = CaptureDeviceManager.getDeviceList(format); - CaptureDeviceInfo videoCaptureDevice = null; - - if (videoCaptureDevices.size() > 0) - { - ConfigurationService cfg - = NeomediaActivator.getConfigurationService(); - String videoDevName - = (cfg == null) ? null : cfg.getString(PROP_VIDEO_DEVICE); - - if (videoDevName == null) - videoCaptureDevice = videoCaptureDevices.get(0); - else - { - for (CaptureDeviceInfo captureDeviceInfo : videoCaptureDevices) - { - if (videoDevName.equals(captureDeviceInfo.getName())) - { - videoCaptureDevice = captureDeviceInfo; - break; - } - } - } - - if ((videoCaptureDevice != null) && logger.isInfoEnabled()) - { - logger.info( - "Found " - + videoCaptureDevice.getName() - + " as a " - + format - + " video capture device."); - } - } - return videoCaptureDevice; - } - - /** - * Returns a device that we could use for audio capture. - * - * @return the CaptureDeviceInfo of a device that we could use for audio - * capture. - */ - public CaptureDeviceInfo getAudioCaptureDevice() - { - AudioSystem audioSystem = getAudioSystem(); - - return (audioSystem == null) ? null : audioSystem.getCaptureDevice(); - } - - /** - * Gets the list of audio capture devices which are available through this - * DeviceConfiguration, amongst which is - * {@link #getAudioCaptureDevice()} and represent acceptable values - * for {@link #setAudioCaptureDevice(CaptureDeviceInfo, boolean)} - * - * @return an array of CaptureDeviceInfo describing the audio - * capture devices available through this - * DeviceConfiguration - */ - public List getAvailableAudioCaptureDevices() - { - @SuppressWarnings("unchecked") - Vector audioCaptureDevices - = CaptureDeviceManager.getDeviceList( - new AudioFormat(AudioFormat.LINEAR, -1, 16, -1)); - - return audioCaptureDevices; - } - - public AudioSystem getAudioSystem() - { - return audioSystem; - } - - public AudioSystem[] getAvailableAudioSystems() - { - AudioSystem[] audioSystems = AudioSystem.getAudioSystems(); - - if ((audioSystems == null) || (audioSystems.length == 0)) - return audioSystems; - else - { - List audioSystemsWithDevices - = new ArrayList(); - - for (AudioSystem audioSystem : audioSystems) - { - if (!NoneAudioSystem.LOCATOR_PROTOCOL.equalsIgnoreCase( - audioSystem.getLocatorProtocol())) - { - List captureDevices - = audioSystem.getCaptureDevices(); - - if ((captureDevices == null) - || (captureDevices.size() <= 0)) - { - if ((AudioSystem.FEATURE_NOTIFY_AND_PLAYBACK_DEVICES - & audioSystem.getFeatures()) - == 0) - { - continue; - } - else - { - List notifyDevices - = audioSystem.getNotifyDevices(); - - if ((notifyDevices == null) - || (notifyDevices.size() <= 0)) - { - List playbackDevices - = audioSystem.getPlaybackDevices(); - - if ((playbackDevices == null) - || (playbackDevices.size() <= 0)) - { - continue; - } - } - } - } - } - audioSystemsWithDevices.add(audioSystem); - } - - int audioSystemsWithDevicesCount = audioSystemsWithDevices.size(); - - return - (audioSystemsWithDevicesCount == audioSystems.length) - ? audioSystems - : audioSystemsWithDevices.toArray( - new AudioSystem[audioSystemsWithDevicesCount]); - } - } - - public void setAudioSystem(AudioSystem audioSystem, boolean save) - { - if (this.audioSystem != audioSystem) - { - if (this.audioSystem != null) - this.audioSystem.removePropertyChangeListener(this); - - AudioSystem oldValue = this.audioSystem; - - this.audioSystem = audioSystem; - - if (this.audioSystem != null) - this.audioSystem.addPropertyChangeListener(this); - - if (save) - { - ConfigurationService cfg - = NeomediaActivator.getConfigurationService(); - - if (cfg != null) - { - if (this.audioSystem == null) - cfg.removeProperty(PROP_AUDIO_SYSTEM); - else - cfg.setProperty( - PROP_AUDIO_SYSTEM, - this.audioSystem.getLocatorProtocol()); - } - } - - firePropertyChange(PROP_AUDIO_SYSTEM, oldValue, this.audioSystem); - } - } - - /** - * Gets the list of video capture devices which are available through this - * DeviceConfiguration, amongst which is - * {@link #getVideoCaptureDevice(MediaUseCase)} and represent acceptable - * values for {@link #setVideoCaptureDevice(CaptureDeviceInfo, boolean)} - * - * @param useCase extract video capture devices that correspond to this - * MediaUseCase - * @return an array of CaptureDeviceInfo describing the video - * capture devices available through this - * DeviceConfiguration - */ - public List getAvailableVideoCaptureDevices( - MediaUseCase useCase) - { - Format[] formats - = new Format[] - { - new AVFrameFormat(), - new VideoFormat(VideoFormat.RGB), - new VideoFormat(VideoFormat.YUV), - new VideoFormat(Constants.H264) - }; - Set videoCaptureDevices - = new HashSet(); - - for (Format format : formats) - { - @SuppressWarnings("unchecked") - Vector cdis - = CaptureDeviceManager.getDeviceList(format); - - if (useCase != MediaUseCase.ANY) - { - for (CaptureDeviceInfo cdi : cdis) - { - MediaUseCase cdiUseCase - = DeviceSystem.LOCATOR_PROTOCOL_IMGSTREAMING - .equalsIgnoreCase( - cdi.getLocator().getProtocol()) - ? MediaUseCase.DESKTOP - : MediaUseCase.CALL; - - if (cdiUseCase.equals(useCase)) - videoCaptureDevices.add(cdi); - } - } - else - { - videoCaptureDevices.addAll(cdis); - } - } - - return new ArrayList(videoCaptureDevices); - } - - /** - * Returns a device that we could use for video capture. - * - * @param useCase MediaUseCase that will determined device - * we will use - * @return the CaptureDeviceInfo of a device that we could use for video - * capture. - */ - public CaptureDeviceInfo getVideoCaptureDevice(MediaUseCase useCase) - { - CaptureDeviceInfo dev = null; - - switch (useCase) - { - case ANY: - case CALL: - dev = videoCaptureDevice; - break; - case DESKTOP: - List devs - = getAvailableVideoCaptureDevices(MediaUseCase.DESKTOP); - - if (devs.size() > 0) - dev = devs.get(0); - break; - default: - break; - } - - return dev; - } - - /** - * Sets the device which is to be used by this - * DeviceConfiguration for video capture. - * - * @param device a CaptureDeviceInfo describing device to be - * used by this DeviceConfiguration for video - * capture. - * @param save whether we will save this option or not. - */ - public void setVideoCaptureDevice(CaptureDeviceInfo device, boolean save) - { - if (videoCaptureDevice != device) - { - CaptureDeviceInfo oldDevice = videoCaptureDevice; - - videoCaptureDevice = device; - - if (save) - { - ConfigurationService cfg - = NeomediaActivator.getConfigurationService(); - - if (cfg != null) - { - cfg.setProperty( - PROP_VIDEO_DEVICE, - (videoCaptureDevice == null) - ? NoneAudioSystem.LOCATOR_PROTOCOL - : videoCaptureDevice.getName()); - } - } - - firePropertyChange(VIDEO_CAPTURE_DEVICE, oldDevice, device); - } - } - - /** - * @return the audioNotifyDevice - */ - public CaptureDeviceInfo getAudioNotifyDevice() - { - AudioSystem audioSystem = getAudioSystem(); - - return (audioSystem == null) ? null : audioSystem.getNotifyDevice(); - } - - /** - * Sets the indicator which determines whether echo cancellation is to be - * performed for captured audio. - * - * @param echoCancel true if echo cancellation is to be performed - * for captured audio; otherwise, false - */ - public void setEchoCancel(boolean echoCancel) - { - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - - if (cfg != null) - cfg.setProperty(PROP_AUDIO_ECHOCANCEL, echoCancel); - } - - /** - * Sets the indicator which determines whether noise suppression is to be - * performed for captured audio. - * - * @param denoise true if noise suppression is to be performed for - * captured audio; otherwise, false - */ - public void setDenoise(boolean denoise) - { - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - - if (cfg != null) - cfg.setProperty(PROP_AUDIO_DENOISE, denoise); - } - - /** - * Gets the indicator which determines whether echo cancellation is to be - * performed for captured audio. - * - * @return true if echo cancellation is to be performed for - * captured audio; otherwise, false - */ - public boolean isEchoCancel() - { - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - boolean value = DEFAULT_AUDIO_ECHOCANCEL; - - if (cfg != null) - value = cfg.getBoolean(PROP_AUDIO_ECHOCANCEL, value); - return value; - } - - /** - * Get the echo cancellation filter length (in milliseconds). - * - * @return echo cancel filter length in milliseconds - */ - public long getEchoCancelFilterLengthInMillis() - { - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - long value = DEFAULT_AUDIO_ECHOCANCEL_FILTER_LENGTH_IN_MILLIS; - - if (cfg != null) - { - value - = cfg.getLong( - PROP_AUDIO_ECHOCANCEL_FILTER_LENGTH_IN_MILLIS, - value); - } - return value; - } - - /** - * Gets the indicator which determines whether noise suppression is to be - * performed for captured audio - * - * @return true if noise suppression is to be performed for - * captured audio; otherwise, false - */ - public boolean isDenoise() - { - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - boolean value = DEFAULT_AUDIO_DENOISE; - - if (cfg != null) - value = cfg.getBoolean(PROP_AUDIO_DENOISE, value); - - return value; - } - - /** - * Registers the custom Renderer implementations defined by class - * name in {@link #CUSTOM_RENDERERS} with JMF. - */ - private void registerCustomRenderers() - { - @SuppressWarnings("unchecked") - Vector renderers - = PlugInManager.getPlugInList(null, null, PlugInManager.RENDERER); - boolean commit = false; - - for (String customRenderer : CUSTOM_RENDERERS) - { - if (customRenderer == null) - continue; - if (customRenderer.startsWith(".")) - { - customRenderer - = "net.java.sip.communicator.impl.neomedia" - + ".jmfext.media.renderer" - + customRenderer; - } - if ((renderers == null) || !renderers.contains(customRenderer)) - { - try - { - Renderer customRendererInstance - = (Renderer) - Class.forName(customRenderer).newInstance(); - - PlugInManager.addPlugIn( - customRenderer, - customRendererInstance.getSupportedInputFormats(), - null, - PlugInManager.RENDERER); - commit = true; - } - catch (Throwable t) - { - logger.error( - "Failed to register custom Renderer " - + customRenderer - + " with JMF.", - t); - } - } - } - - /* - * Just in case, bubble our JMF contributions at the top so that they - * are considered preferred. - */ - int pluginType = PlugInManager.RENDERER; - @SuppressWarnings("unchecked") - Vector plugins - = PlugInManager.getPlugInList(null, null, pluginType); - - if (plugins != null) - { - int pluginCount = plugins.size(); - int pluginBeginIndex = 0; - String preferred = "net.java.sip.communicator.impl.neomedia."; - - for (int pluginIndex = pluginCount - 1; - pluginIndex >= pluginBeginIndex;) - { - String plugin = plugins.get(pluginIndex); - - if (plugin.startsWith(preferred)) - { - plugins.remove(pluginIndex); - plugins.add(0, plugin); - pluginBeginIndex++; - commit = true; - } - else - pluginIndex--; - } - PlugInManager.setPlugInList(plugins, pluginType); - if (logger.isTraceEnabled()) - logger.trace("Reordered plug-in list:" + plugins); - } - - if (commit && !MediaServiceImpl.isJmfRegistryDisableLoad()) - { - try - { - PlugInManager.commit(); - } - catch (IOException ioex) - { - logger.warn( - "Failed to commit changes to the JMF plug-in list."); - } - } - } - - /** - * Gets the maximum allowed video bandwidth. - * - * @return the maximum allowed video bandwidth. The default value is - * {@link #DEFAULT_VIDEO_MAX_BANDWIDTH}. - */ - public int getVideoMaxBandwidth() - { - if (videoMaxBandwidth == -1) - { - ConfigurationService cfg - = NeomediaActivator.getConfigurationService(); - int value = DEFAULT_VIDEO_MAX_BANDWIDTH; - - if (cfg != null) - value = cfg.getInt(PROP_VIDEO_MAX_BANDWIDTH, value); - - videoMaxBandwidth = value; - } - return videoMaxBandwidth; - } - - /** - * Sets and stores the maximum allowed video bandwidth. - * - * @param videoMaxBandwidth the maximum allowed video bandwidth - */ - public void setVideoMaxBandwidth(int videoMaxBandwidth) - { - this.videoMaxBandwidth = videoMaxBandwidth; - - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - - if (cfg != null) - { - if (videoMaxBandwidth != DEFAULT_VIDEO_MAX_BANDWIDTH) - cfg.setProperty(PROP_VIDEO_MAX_BANDWIDTH, videoMaxBandwidth); - else - cfg.removeProperty(PROP_VIDEO_MAX_BANDWIDTH); - } - } - - /** - * Gets the frame rate set on this DeviceConfiguration. - * - * @return the frame rate set on this DeviceConfiguration. The - * default value is {@link #DEFAULT_VIDEO_FRAMERATE} - */ - public int getFrameRate() - { - if (frameRate == -1) - { - ConfigurationService cfg - = NeomediaActivator.getConfigurationService(); - int value = DEFAULT_VIDEO_FRAMERATE; - - if (cfg != null) - value = cfg.getInt(PROP_VIDEO_FRAMERATE, value); - - frameRate = value; - } - return frameRate; - } - - /** - * Sets and stores the frame rate. - * - * @param frameRate the frame rate to be set on this - * DeviceConfiguration - */ - public void setFrameRate(int frameRate) - { - this.frameRate = frameRate; - - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - - if (cfg != null) - { - if (frameRate != DEFAULT_VIDEO_FRAMERATE) - cfg.setProperty(PROP_VIDEO_FRAMERATE, frameRate); - else - cfg.removeProperty(PROP_VIDEO_FRAMERATE); - } - } - - /** - * Gets the video size set on this DeviceConfiguration. - * - * @return the video size set on this DeviceConfiguration - */ - public Dimension getVideoSize() - { - if(videoSize == null) - { - ConfigurationService cfg - = NeomediaActivator.getConfigurationService(); - int height = DEFAULT_VIDEO_HEIGHT; - int width = DEFAULT_VIDEO_WIDTH; - - if (cfg != null) - { - height = cfg.getInt(PROP_VIDEO_HEIGHT, height); - width = cfg.getInt(PROP_VIDEO_WIDTH, width); - } - - videoSize = new Dimension(width, height); - } - return videoSize; - } - - /** - * Sets and stores the video size. - * - * @param videoSize the video size to be set on this - * DeviceConfiguration - */ - public void setVideoSize(Dimension videoSize) - { - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - - if (cfg != null) - { - if ((videoSize.getHeight() != DEFAULT_VIDEO_HEIGHT) - || (videoSize.getWidth() != DEFAULT_VIDEO_WIDTH)) - { - cfg.setProperty(PROP_VIDEO_HEIGHT, videoSize.height); - cfg.setProperty(PROP_VIDEO_WIDTH, videoSize.width); - } - else - { - cfg.removeProperty(PROP_VIDEO_HEIGHT); - cfg.removeProperty(PROP_VIDEO_WIDTH); - } - } - - this.videoSize = videoSize; - - firePropertyChange( - VIDEO_CAPTURE_DEVICE, - videoCaptureDevice, videoCaptureDevice); - } - - /** - * Listens for changes in the configuration and if such happen - * we reset local values so next time we will update from - * the configuration. - * - * @param event the property change event - */ - public void propertyChange(PropertyChangeEvent event) - { - String propertyName = event.getPropertyName(); - - if (AudioSystem.PROP_CAPTURE_DEVICE.equals(propertyName) - || AudioSystem.PROP_NOTIFY_DEVICE.equals(propertyName) - || AudioSystem.PROP_PLAYBACK_DEVICE.equals(propertyName)) - { - firePropertyChange( - propertyName, - event.getOldValue(), - event.getNewValue()); - } - else if (DeviceSystem.PROP_DEVICES.equals(propertyName)) - { - if (event.getSource() instanceof AudioSystem) - firePropertyChange( - PROP_AUDIO_SYSTEM_DEVICES, - event.getOldValue(), - event.getNewValue()); - } - else if (PROP_VIDEO_FRAMERATE.equals(propertyName)) - { - frameRate = -1; - } - else if (PROP_VIDEO_HEIGHT.equals(propertyName) - || PROP_VIDEO_WIDTH.equals(propertyName)) - { - videoSize = null; - } - else if (PROP_VIDEO_MAX_BANDWIDTH.equals(propertyName)) - { - videoMaxBandwidth = -1; - } - } - - /** - * Detects audio capture devices configured through JMF and disable audio if - * none was found. - */ - private void extractConfiguredAudioCaptureDevices() - { - if (logger.isInfoEnabled()) - logger.info("Looking for configured audio devices."); - - AudioSystem[] availableAudioSystems = getAvailableAudioSystems(); - - if ((availableAudioSystems != null) - && (availableAudioSystems.length != 0)) - { - AudioSystem audioSystem = getAudioSystem(); - - if (audioSystem != null) - { - boolean audioSystemIsAvailable = false; - - for (AudioSystem availableAudioSystem : availableAudioSystems) - { - if (availableAudioSystem.equals(audioSystem)) - { - audioSystemIsAvailable = true; - break; - } - } - if (!audioSystemIsAvailable) - audioSystem = null; - } - - if (audioSystem == null) - { - ConfigurationService cfg - = NeomediaActivator.getConfigurationService(); - - if (cfg != null) - { - String locatorProtocol = cfg.getString(PROP_AUDIO_SYSTEM); - - if (locatorProtocol != null) - { - for (AudioSystem availableAudioSystem - : availableAudioSystems) - { - if (locatorProtocol.equalsIgnoreCase( - availableAudioSystem.getLocatorProtocol())) - { - audioSystem = availableAudioSystem; - break; - } - } - } - } - - if (audioSystem == null) - audioSystem = availableAudioSystems[0]; - - setAudioSystem(audioSystem, false); - } - } - } - - /** - * Detects video capture devices configured through JMF and disable video if - * none was found. - */ - private void extractConfiguredVideoCaptureDevices() - { - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - String videoCaptureDeviceString - = (cfg == null) ? null : cfg.getString(PROP_VIDEO_DEVICE); - - if (NoneAudioSystem.LOCATOR_PROTOCOL.equalsIgnoreCase( - videoCaptureDeviceString)) - { - videoCaptureDevice = null; - } - else - { - if (logger.isInfoEnabled()) - logger.info("Scanning for configured Video Devices."); - - Format[] formats - = new Format[] - { - new AVFrameFormat(), - new VideoFormat(VideoFormat.RGB), - new VideoFormat(VideoFormat.YUV), - new VideoFormat(Constants.H264) - }; - - for (Format format : formats) - { - videoCaptureDevice - = extractConfiguredVideoCaptureDevice(format); - if (videoCaptureDevice != null) - break; - } - if ((videoCaptureDevice == null) && logger.isInfoEnabled()) - logger.info("No Video Device was found."); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/DeviceSystem.java b/src/net/java/sip/communicator/impl/neomedia/device/DeviceSystem.java deleted file mode 100644 index 350768047..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/DeviceSystem.java +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import java.io.*; -import java.util.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.util.*; -import net.java.sip.communicator.util.event.*; - -public abstract class DeviceSystem - extends PropertyChangeNotifier -{ - private static final Logger logger = Logger.getLogger(DeviceSystem.class); - - public static final int FEATURE_REINITIALIZE = 1; - - public static final String LOCATOR_PROTOCOL_CIVIL = "civil"; - - public static final String LOCATOR_PROTOCOL_DIRECTSHOW = "directshow"; - - public static final String LOCATOR_PROTOCOL_IMGSTREAMING = "imgstreaming"; - - public static final String LOCATOR_PROTOCOL_MEDIARECORDER = "mediarecorder"; - - public static final String LOCATOR_PROTOCOL_QUICKTIME = "quicktime"; - - public static final String LOCATOR_PROTOCOL_VIDEO4LINUX2 = "video4linux2"; - - public static final String PROP_DEVICES = "devices"; - - private static List deviceSystems - = new LinkedList(); - - protected static List filterDeviceListByLocatorProtocol( - List deviceList, - String locatorProtocol) - { - if ((deviceList != null) && (deviceList.size() > 0)) - { - Iterator deviceListIter = deviceList.iterator(); - - while (deviceListIter.hasNext()) - { - MediaLocator locator = deviceListIter.next().getLocator(); - - if ((locator == null) - || !locatorProtocol.equalsIgnoreCase( - locator.getProtocol())) - { - deviceListIter.remove(); - } - } - } - return deviceList; - } - - public static DeviceSystem[] getDeviceSystems(MediaType mediaType) - { - List ret; - - synchronized (deviceSystems) - { - ret = new ArrayList(deviceSystems.size()); - for (DeviceSystem deviceSystem : deviceSystems) - if (deviceSystem.getMediaType().equals(mediaType)) - ret.add(deviceSystem); - } - return ret.toArray(new DeviceSystem[ret.size()]); - } - - public static void initializeDeviceSystems() - { - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - - /* - * Detect the audio capture devices unless the configuration explicitly - * states that they are to not be detected. - */ - if (((cfg == null) - || !cfg.getBoolean( - MediaServiceImpl.DISABLE_AUDIO_SUPPORT_PNAME, - false)) - && !Boolean.getBoolean( - MediaServiceImpl.DISABLE_AUDIO_SUPPORT_PNAME)) - { - if (logger.isInfoEnabled()) - logger.info("Initializing audio devices"); - - initializeDeviceSystems(MediaType.AUDIO); - } - - /* - * Detect the video capture devices unless the configuration explicitly - * states that they are to not be detected. - */ - if ((cfg == null) - || !cfg.getBoolean( - MediaServiceImpl.DISABLE_VIDEO_SUPPORT_PNAME, - false)) - { - if (logger.isInfoEnabled()) - logger.info("Initializing video devices"); - - initializeDeviceSystems(MediaType.VIDEO); - } - } - - public static void initializeDeviceSystems(MediaType mediaType) - { - String[] classNames; - - switch (mediaType) - { - case AUDIO: - classNames - = new String[] - { - OSUtils.IS_ANDROID ? ".AudioRecordSystem" : null, - OSUtils.IS_ANDROID ? ".OpenSLESSystem" : null, - OSUtils.IS_LINUX ? ".PulseAudioSystem" : null, - OSUtils.IS_ANDROID ? null : ".PortAudioSystem", - ".NoneAudioSystem" - }; - break; - case VIDEO: - classNames - = new String[] - { - OSUtils.IS_ANDROID ? ".MediaRecorderSystem" : null, - OSUtils.IS_LINUX ? ".Video4Linux2System" : null, - OSUtils.IS_MAC ? ".QuickTimeSystem" : null, - OSUtils.IS_WINDOWS ? ".DirectShowSystem" : null, - ".ImgStreamingSystem" - }; - break; - default: - throw new IllegalArgumentException("mediaType"); - } - - initializeDeviceSystems(classNames); - } - - private static void initializeDeviceSystems(String[] classNames) - { - synchronized (deviceSystems) - { - String packageName = null; - - for (String className : classNames) - { - if (className == null) - continue; - - if (className.startsWith(".")) - { - if (packageName == null) - packageName = DeviceSystem.class.getPackage().getName(); - className = packageName + className; - } - - // Initialize a single instance per className. - DeviceSystem deviceSystem = null; - - for (DeviceSystem aDeviceSystem : deviceSystems) - if (aDeviceSystem.getClass().getName().equals(className)) - { - deviceSystem = aDeviceSystem; - break; - } - - boolean reinitialize; - - if (deviceSystem == null) - { - reinitialize = false; - - Object o = null; - - try - { - o = Class.forName(className).newInstance(); - } - catch (Throwable t) - { - if (t instanceof ThreadDeath) - throw (ThreadDeath) t; - else if (logger.isDebugEnabled()) - logger.debug( - "Failed to initialize " + className, - t); - } - if (o instanceof DeviceSystem) - { - deviceSystem = (DeviceSystem) o; - if (!deviceSystems.contains(deviceSystem)) - deviceSystems.add(deviceSystem); - } - } - else - reinitialize = true; - - // Reinitializing is an optional feature. - if (reinitialize - && ((deviceSystem.getFeatures() & FEATURE_REINITIALIZE) - != 0)) - { - try - { - deviceSystem.initialize(); - } - catch (Throwable t) - { - if (t instanceof ThreadDeath) - throw (ThreadDeath) t; - else if (logger.isDebugEnabled()) - logger.debug( - "Failed to reinitialize " + className, - t); - } - } - } - } - } - - private final int features; - - private final String locatorProtocol; - - private final MediaType mediaType; - - protected DeviceSystem(MediaType mediaType, String locatorProtocol) - throws Exception - { - this(mediaType, locatorProtocol, 0); - } - - protected DeviceSystem( - MediaType mediaType, - String locatorProtocol, - int features) - throws Exception - { - if (mediaType == null) - throw new NullPointerException("mediaType"); - if (locatorProtocol == null) - throw new NullPointerException("locatorProtocol"); - - this.mediaType = mediaType; - this.locatorProtocol = locatorProtocol; - this.features = features; - - initialize(); - } - - public Renderer createRenderer(boolean playback) - { - String className = getRendererClassName(); - - if (className != null) - { - try - { - return (Renderer) Class.forName(className).newInstance(); - } - catch (Throwable t) - { - if (t instanceof ThreadDeath) - throw (ThreadDeath) t; - else - logger.warn( - "Failed to initialize a new " - + className - + " instance", - t); - } - } - return null; - } - - protected abstract void doInitialize() - throws Exception; - - public final int getFeatures() - { - return features; - } - - public final String getLocatorProtocol() - { - return locatorProtocol; - } - - public final MediaType getMediaType() - { - return mediaType; - } - - protected String getRendererClassName() - { - return null; - } - - protected final void initialize() - throws Exception - { - preInitialize(); - try - { - doInitialize(); - } - finally - { - postInitialize(); - } - } - - protected void postInitialize() - { - firePropertyChange(PROP_DEVICES, null, null); - } - - protected void preInitialize() - { - Format format; - - switch (getMediaType()) - { - case AUDIO: - format = new AudioFormat(null); - break; - case VIDEO: - format = new VideoFormat(null); - break; - default: - format = null; - break; - } - - if (format != null) - { - @SuppressWarnings("unchecked") - Vector cdis - = CaptureDeviceManager.getDeviceList(format); - - if ((cdis != null) && (cdis.size() > 0)) - { - boolean commit = false; - - for (CaptureDeviceInfo cdi - : filterDeviceListByLocatorProtocol( - cdis, - getLocatorProtocol())) - { - CaptureDeviceManager.removeDevice(cdi); - commit = true; - } - if (commit && !MediaServiceImpl.isJmfRegistryDisableLoad()) - { - try - { - CaptureDeviceManager.commit(); - } - catch (IOException ioe) - { - /* - * We do not really need commit but we have it for - * historical reasons. - */ - if (logger.isDebugEnabled()) - logger.debug( - "Failed to commit CaptureDeviceManager", - ioe); - } - } - } - } - } - - @Override - public String toString() - { - return getLocatorProtocol(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/DirectShowSystem.java b/src/net/java/sip/communicator/impl/neomedia/device/DirectShowSystem.java deleted file mode 100644 index 2f8958428..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/DirectShowSystem.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import javax.media.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.codec.video.*; -import net.java.sip.communicator.impl.neomedia.directshow.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.directshow.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.util.*; - -/** - * Discovers and registers DirectShow video capture devices with JMF. - * - * @author Sebastien Vincent - */ -public class DirectShowSystem - extends DeviceSystem -{ - /** - * The Logger used by the DirectShowSystem class and its - * instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(DirectShowSystem.class); - - /** - * The protocol of the MediaLocators identifying QuickTime/QTKit - * capture devices. - */ - private static final String LOCATOR_PROTOCOL = LOCATOR_PROTOCOL_DIRECTSHOW; - - /** - * Constructor. Discover and register DirectShow capture devices - * with JMF. - * - * @throws Exception if anything goes wrong while discovering and - * registering DirectShow capture defines with JMF - */ - public DirectShowSystem() - throws Exception - { - super(MediaType.VIDEO, LOCATOR_PROTOCOL); - } - - protected void doInitialize() - throws Exception - { - DSCaptureDevice devices[] = DSManager.getInstance().getCaptureDevices(); - boolean captureDeviceInfoIsAdded = false; - - for(int i = 0, count = (devices == null) ? 0 : devices.length; - i < count; - i++) - { - long pixelFormat = devices[i].getFormat().getPixelFormat(); - int ffmpegPixFmt = (int)DataSource.getFFmpegPixFmt(pixelFormat); - Format format = null; - - if(ffmpegPixFmt != FFmpeg.PIX_FMT_NONE) - { - format = new AVFrameFormat(ffmpegPixFmt, (int) pixelFormat); - } - else - { - logger.warn("No support for this webcam: " + - devices[i].getName() + "(format " + pixelFormat + - " not supported)"); - continue; - } - - if(logger.isInfoEnabled()) - { - for(DSFormat f : devices[i].getSupportedFormats()) - { - if(f.getWidth() != 0 && f.getHeight() != 0) - logger.info( - "Webcam available resolution for " - + devices[i].getName() - + ":" - + f.getWidth() - + "x" - + f.getHeight()); - } - } - - CaptureDeviceInfo device - = new CaptureDeviceInfo( - devices[i].getName(), - new MediaLocator( - LOCATOR_PROTOCOL + ':' + devices[i].getName()), - new Format[] { format }); - - if(logger.isInfoEnabled()) - logger.info("Found[" + i + "]: " + device.getName()); - - CaptureDeviceManager.addDevice(device); - captureDeviceInfoIsAdded = true; - } - - if (captureDeviceInfoIsAdded - && !MediaServiceImpl.isJmfRegistryDisableLoad()) - CaptureDeviceManager.commit(); - - DSManager.dispose(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/ImgStreamingSystem.java b/src/net/java/sip/communicator/impl/neomedia/device/ImgStreamingSystem.java deleted file mode 100644 index e2a04d8bb..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/ImgStreamingSystem.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import java.awt.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.codec.video.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.util.*; - -/** - * Add ImageStreaming capture device. - * - * @author Sebastien Vincent - */ -public class ImgStreamingSystem - extends DeviceSystem -{ - /** - * The locator protocol used when creating or parsing - * MediaLocators. - */ - private static final String LOCATOR_PROTOCOL - = LOCATOR_PROTOCOL_IMGSTREAMING; - - /** - * Add capture devices. - * - * @throws Exception if problem when adding capture devices - */ - public ImgStreamingSystem() - throws Exception - { - super(MediaType.VIDEO, LOCATOR_PROTOCOL, FEATURE_REINITIALIZE); - } - - protected void doInitialize() - throws Exception - { - /* - * XXX The initialization of MediaServiceImpl is very complex so it is - * wise to not reference it at the early stage of its initialization. - */ - ScreenDevice[] screens = ScreenDeviceImpl.getAvailableScreenDevices(); - - String name = "Desktop Streaming"; - int i = 0; - boolean multipleMonitorOneScreen = false; - Dimension screenSize = null; - - /* - * On Linux, multiple monitors may result in a single X display (:0.0) - * which combines them. - */ - if(OSUtils.IS_LINUX) - { - Dimension size = new Dimension(0, 0); - - for(ScreenDevice screen : screens) - { - Dimension s = screen.getSize(); - - size.width += s.width; - size.height += s.height; - } - - try - { - screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - - if(screenSize.width == size.width || - screenSize.height == size.height) - { - multipleMonitorOneScreen = true; - } - } - catch(Exception e) - { - } - } - - for(ScreenDevice screen : screens) - { - Dimension size = screenSize != null ? screenSize : screen.getSize(); - Format formats[] - = new Format[] - { - new AVFrameFormat( - size, - Format.NOT_SPECIFIED, - FFmpeg.PIX_FMT_ARGB, - Format.NOT_SPECIFIED), - new RGBFormat( - size, // size - Format.NOT_SPECIFIED, // maxDataLength - Format.byteArray, // dataType - Format.NOT_SPECIFIED, // frameRate - 32, // bitsPerPixel - 2 /* red */, 3 /* green */, 4 /* blue */) - }; - CaptureDeviceInfo devInfo - = new CaptureDeviceInfo( - name + " " + i, - new MediaLocator(LOCATOR_PROTOCOL + ":" + i), - formats); - - CaptureDeviceManager.addDevice(devInfo); - i++; - - if(multipleMonitorOneScreen) - break; - } - - if (!MediaServiceImpl.isJmfRegistryDisableLoad()) - CaptureDeviceManager.commit(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/JavaSoundSystem.java b/src/net/java/sip/communicator/impl/neomedia/device/JavaSoundSystem.java deleted file mode 100644 index 20a759f50..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/JavaSoundSystem.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import java.lang.reflect.Method; - -/** - * Auto-detection of FMJ audio capture devices. - * - * @author Ken Larson - */ -public class JavaSoundSystem - extends AudioSystem -{ - private static final String LOCATOR_PROTOCOL = LOCATOR_PROTOCOL_JAVASOUND; - - public JavaSoundSystem() - throws Exception - { - super(LOCATOR_PROTOCOL); - } - - protected void doInitialize() - throws Exception - { - // Done using reflection to avoid compile-time dependency on FMJ. - Class clazz - = Class.forName( - "net.sf.fmj.media.cdp.javasound.CaptureDevicePlugger"); - Method addCaptureDevices = clazz.getMethod("addCaptureDevices"); - Object captureDevicePlugger = clazz.newInstance(); - - addCaptureDevices.invoke(captureDevicePlugger); - } - - @Override - protected String getRendererClassName() - { - return "net.sf.fmj.media.renderer.audio.JavaSoundRenderer"; - } - - @Override - public String toString() - { - return "JavaSound"; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/LtiCivilSystem.java b/src/net/java/sip/communicator/impl/neomedia/device/LtiCivilSystem.java deleted file mode 100644 index 36daf97cb..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/LtiCivilSystem.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import java.lang.reflect.*; - -import net.java.sip.communicator.service.neomedia.*; - -/** - * FMJ auto-detect of CIVIL video capture devices. - * - * @author Ken Larson - */ -public class LtiCivilSystem - extends DeviceSystem -{ - private static final String LOCATOR_PROTOCOL = LOCATOR_PROTOCOL_CIVIL; - - /** - * Creates an instance of LtiCivilSystem and auto-detects CIVIL video - * capture devices. - * - * @throws java.lang.Exception if FMJ is not present in the classpath or if - * detection fails for some other reason. - */ - public LtiCivilSystem() - throws Exception - { - super(MediaType.VIDEO, LOCATOR_PROTOCOL); - } - - protected void doInitialize() - throws Exception - { - // Done using reflection to avoid compile-time dependency on FMJ. - Class clazz - = Class.forName("net.sf.fmj.media.cdp.civil.CaptureDevicePlugger"); - Method addCaptureDevices = clazz.getMethod("addCaptureDevices"); - Object captureDevicePlugger = clazz.newInstance(); - - addCaptureDevices.invoke(captureDevicePlugger); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceImpl.java b/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceImpl.java deleted file mode 100644 index 9a6d6b65b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceImpl.java +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import java.awt.*; -import java.io.*; -import java.util.*; -import java.util.List; - -import javax.media.*; -import javax.media.control.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.format.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.*; -import net.java.sip.communicator.impl.neomedia.protocol.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.format.*; -import net.java.sip.communicator.util.*; - -/** - * Implements MediaDevice for the JMF CaptureDevice. - * - * @author Lyubomir Marinov - * @author Emil Ivov - */ -public class MediaDeviceImpl - extends AbstractMediaDevice -{ - - /** - * The Logger used by MediaDeviceImpl and its instances - * for logging output. - */ - private static final Logger logger - = Logger.getLogger(MediaDeviceImpl.class); - - /** - * The CaptureDeviceInfo of the device that this instance is - * representing. - */ - private final CaptureDeviceInfo captureDeviceInfo; - - /** - * The MediaType of this instance and the CaptureDevice - * that it wraps. - */ - private final MediaType mediaType; - - /** - * Initializes a new MediaDeviceImpl instance with a specific - * MediaType and with MediaDirection which does not allow - * sending. - * - * @param mediaType the MediaType of the new instance - */ - public MediaDeviceImpl(MediaType mediaType) - { - this.captureDeviceInfo = null; - this.mediaType = mediaType; - } - - /** - * Initializes a new MediaDeviceImpl instance which is to provide - * an implementation of MediaDevice for a CaptureDevice - * with a specific CaptureDeviceInfo and which is of a specific - * MediaType. - * - * @param captureDeviceInfo the CaptureDeviceInfo of the JMF - * CaptureDevice the new instance is to provide an implementation - * of MediaDevice for - * @param mediaType the MediaType of the new instance - */ - public MediaDeviceImpl( - CaptureDeviceInfo captureDeviceInfo, - MediaType mediaType) - { - if (captureDeviceInfo == null) - throw new NullPointerException("captureDeviceInfo"); - if (mediaType == null) - throw new NullPointerException("mediaType"); - - this.captureDeviceInfo = captureDeviceInfo; - this.mediaType = mediaType; - } - - /** - * Creates the JMF CaptureDevice this instance represents and - * provides an implementation of MediaDevice for. - * - * @return the JMF CaptureDevice this instance represents and - * provides an implementation of MediaDevice for; null - * if the creation fails - */ - CaptureDevice createCaptureDevice() - { - CaptureDevice captureDevice = null; - - if (getDirection().allowsSending()) - { - Throwable exception = null; - - try - { - captureDevice - = (CaptureDevice) - Manager.createDataSource( - captureDeviceInfo.getLocator()); - } - catch (IOException ioe) - { - // TODO - exception = ioe; - } - catch (NoDataSourceException ndse) - { - // TODO - exception = ndse; - } - - if (exception != null) - { - logger - .error( - "Failed to create CaptureDevice" - + " from CaptureDeviceInfo " - + captureDeviceInfo, - exception); - } - else - { - if(captureDevice instanceof AbstractPullBufferCaptureDevice) - { - ((AbstractPullBufferCaptureDevice)captureDevice) - .setCaptureDeviceInfo(captureDeviceInfo); - } - - // Try to enable tracing on captureDevice. - if (logger.isTraceEnabled()) - captureDevice - = createTracingCaptureDevice(captureDevice, logger); - } - } - return captureDevice; - } - - /** - * Creates a DataSource instance for this MediaDevice - * which gives access to the captured media. - * - * @return a DataSource instance which gives access to the media - * captured by this MediaDevice - * @see AbstractMediaDevice#createOutputDataSource() - */ - DataSource createOutputDataSource() - { - return - getDirection().allowsSending() - ? (DataSource) createCaptureDevice() - : null; - } - - /** - * Initializes a new Renderer instance which is to play back media - * on this MediaDevice. - * - * @return a new Renderer instance which is to play back media on - * this MediaDevice or null if a suitable - * Renderer is to be chosen irrespective of this - * MediaDevice - */ - Renderer createRenderer() - { - return null; - } - - /** - * Creates a new CaptureDevice which traces calls to a specific - * CaptureDevice for debugging purposes. - * - * @param captureDevice the CaptureDevice which is to have its - * calls traced for debugging output - * @param logger the Logger to be used for logging the trace - * messages - * @return a new CaptureDevice which traces the calls to the - * specified captureDevice - */ - public static CaptureDevice createTracingCaptureDevice( - CaptureDevice captureDevice, - final Logger logger) - { - if (captureDevice instanceof PushBufferDataSource) - captureDevice - = new CaptureDeviceDelegatePushBufferDataSource( - captureDevice) - { - @Override - public void connect() - throws IOException - { - super.connect(); - - if (logger.isTraceEnabled()) - logger - .trace( - "Connected " - + MediaDeviceImpl - .toString(this.captureDevice)); - } - - @Override - public void disconnect() - { - super.disconnect(); - - if (logger.isTraceEnabled()) - logger - .trace( - "Disconnected " - + MediaDeviceImpl - .toString(this.captureDevice)); - } - - @Override - public void start() - throws IOException - { - super.start(); - - if (logger.isTraceEnabled()) - logger - .trace( - "Started " - + MediaDeviceImpl - .toString(this.captureDevice)); - } - - @Override - public void stop() - throws IOException - { - super.stop(); - - if (logger.isTraceEnabled()) - logger - .trace( - "Stopped " - + MediaDeviceImpl - .toString(this.captureDevice)); - } - }; - return captureDevice; - } - - /** - * Gets the CaptureDeviceInfo of the JMF CaptureDevice - * represented by this instance. - * - * @return the CaptureDeviceInfo of the CaptureDevice - * represented by this instance - */ - public CaptureDeviceInfo getCaptureDeviceInfo() - { - return captureDeviceInfo; - } - - /** - * Returns the MediaDirection supported by this device. - * - * @return {@link MediaDirection#SENDONLY} if this is a read-only device, - * {@link MediaDirection#RECVONLY} if this is a write-only device or - * {@link MediaDirection#SENDRECV} if this MediaDevice can both - * capture and render media - * @see MediaDevice#getDirection() - */ - public MediaDirection getDirection() - { - if (captureDeviceInfo != null) - return MediaDirection.SENDRECV; - else - return - MediaType.AUDIO.equals(getMediaType()) - ? MediaDirection.INACTIVE - : MediaDirection.RECVONLY; - } - - /** - * Gets the MediaFormat in which this MediaDevice captures - * media. - * - * @return the MediaFormat in which this MediaDevice - * captures media - * @see MediaDevice#getFormat() - */ - public MediaFormat getFormat() - { - CaptureDevice captureDevice = createCaptureDevice(); - - if (captureDevice != null) - { - MediaType mediaType = getMediaType(); - - for (FormatControl formatControl - : captureDevice.getFormatControls()) - { - MediaFormat format - = MediaFormatImpl.createInstance(formatControl.getFormat()); - - if ((format != null) && format.getMediaType().equals(mediaType)) - return format; - } - } - return null; - } - - /** - * Gets the MediaType that this device supports. - * - * @return {@link MediaType#AUDIO} if this is an audio device or - * {@link MediaType#VIDEO} if this is a video device - * @see MediaDevice#getMediaType() - */ - public MediaType getMediaType() - { - return mediaType; - } - - /** - * Gets the list of MediaFormats supported by this - * MediaDevice. - * - * @param sendPreset the preset used to set some of the format parameters, - * used for video and settings. - * @param receivePreset the preset used to set the receive format - * parameters, used for video and settings. - * @return the list of MediaFormats supported by this device - * @see MediaDevice#getSupportedFormats() - */ - public List getSupportedFormats( - QualityPreset sendPreset, - QualityPreset receivePreset) - { - MediaServiceImpl mediaServiceImpl - = NeomediaActivator.getMediaServiceImpl(); - EncodingConfiguration encodingConfiguration - = mediaServiceImpl.getEncodingConfiguration(); - MediaFormat[] supportedEncodings - = encodingConfiguration.getSupportedEncodings(getMediaType()); - List supportedFormats = new ArrayList(); - - // If there is preset, check and set the format attributes where needed. - if (supportedEncodings != null) - { - for (MediaFormat f : supportedEncodings) - { - if("h264".equalsIgnoreCase(f.getEncoding())) - { - Map h264AdvancedAttributes - = f.getAdvancedAttributes(); - - if (h264AdvancedAttributes == null) - h264AdvancedAttributes = new HashMap(); - - MediaLocator captureDeviceInfoLocator; - Dimension sendSize = null; - - // change send size only for video calls - if ((captureDeviceInfo != null) - && ((captureDeviceInfoLocator - = captureDeviceInfo.getLocator()) - != null) - && !DeviceSystem.LOCATOR_PROTOCOL_IMGSTREAMING - .equals(captureDeviceInfoLocator.getProtocol())) - { - if (sendPreset != null) - sendSize = sendPreset.getResolution(); - else - sendSize - = mediaServiceImpl - .getDeviceConfiguration() - .getVideoSize(); - } - - Dimension receiveSize; - - // if there is specified preset, send its settings - if (receivePreset != null) - receiveSize = receivePreset.getResolution(); - else - { - // or just send the max video resolution of the PC - // as we do by default - ScreenDevice screen - = mediaServiceImpl.getDefaultScreenDevice(); - - receiveSize - = (screen == null) ? null : screen.getSize(); - } - - h264AdvancedAttributes.put( - "imageattr", - MediaUtils.createImageAttr(sendSize, receiveSize)); - - f - = mediaServiceImpl.getFormatFactory().createMediaFormat( - f.getEncoding(), - f.getClockRate(), - f.getFormatParameters(), - h264AdvancedAttributes); - } - - if (f != null) - supportedFormats.add(f); - } - } - - return supportedFormats; - } - - /** - * Gets a human-readable String representation of this instance. - * - * @return a String providing a human-readable representation of - * this instance - */ - @Override - public String toString() - { - CaptureDeviceInfo captureDeviceInfo = getCaptureDeviceInfo(); - - return - (captureDeviceInfo == null) - ? super.toString() - : captureDeviceInfo.toString(); - } - - /** - * Returns a human-readable representation of a specific - * CaptureDevice in the form of a String value. - * - * @param captureDevice the CaptureDevice to get a human-readable - * representation of - * @return a String value which gives a human-readable - * representation of the specified captureDevice - */ - private static String toString(CaptureDevice captureDevice) - { - StringBuffer str = new StringBuffer(); - - str.append("CaptureDevice with hashCode "); - str.append(captureDevice.hashCode()); - str.append(" and captureDeviceInfo "); - - CaptureDeviceInfo captureDeviceInfo - = captureDevice.getCaptureDeviceInfo(); - MediaLocator mediaLocator = captureDeviceInfo.getLocator(); - - str.append((mediaLocator == null) ? captureDeviceInfo : mediaLocator); - return str.toString(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceSession.java b/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceSession.java deleted file mode 100644 index 64841be51..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceSession.java +++ /dev/null @@ -1,2194 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import java.awt.Dimension; // disambiguation -import java.io.*; -import java.util.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; -import javax.media.protocol.*; -import javax.media.rtp.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.format.*; -import net.java.sip.communicator.impl.neomedia.protocol.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.format.*; -import net.java.sip.communicator.util.*; -import net.java.sip.communicator.util.event.*; - -/** - * Represents the use of a specific MediaDevice by a - * MediaStream. - * - * @author Lyubomir Marinov - * @author Damian Minkov - * @author Emil Ivov - */ -public class MediaDeviceSession - extends PropertyChangeNotifier -{ - /** - * The Logger used by the MediaDeviceSession class and its - * instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(MediaDeviceSession.class); - - /** - * The name of the MediaDeviceSession instance property the value - * of which represents the output DataSource of the - * MediaDeviceSession instance which provides the captured (RTP) - * data to be sent by MediaStream to MediaStreamTarget. - */ - public static final String OUTPUT_DATA_SOURCE = "OUTPUT_DATA_SOURCE"; - - /** - * The name of the property that corresponds to the array of SSRC - * identifiers that we store in this MediaDeviceSession instance - * and that we update upon adding and removing ReceiveStream - */ - public static final String SSRC_LIST = "SSRC_LIST"; - - /** - * The JMF DataSource of {@link #device} through which this - * instance accesses the media captured by it. - */ - private DataSource captureDevice; - - /** - * The indicator which determines whether {@link DataSource#connect()} has - * been successfully executed on {@link #captureDevice}. - */ - private boolean captureDeviceIsConnected; - - /** - * The ContentDescriptor which specifies the content type in which - * this MediaDeviceSession is to output the media captured by its - * MediaDevice. - */ - private ContentDescriptor contentDescriptor; - - /** - * The MediaDevice used by this instance to capture and play back - * media. - */ - private final AbstractMediaDevice device; - - /** - * The last JMF Format set to this instance by a call to its - * {@link #setFormat(MediaFormat)} and to be set as the output format of - * {@link #processor}. - */ - private MediaFormatImpl format; - - /** - * The indicator which determines whether this MediaDeviceSession - * is set to output "silence" instead of the actual media captured from - * {@link #captureDevice}. - */ - private boolean mute = false; - - /** - * The list of playbacks of ReceiveStreams and/or - * DataSources performed by respective Players on the - * MediaDevice represented by this instance. - */ - private final List playbacks = new LinkedList(); - - /** - * The ControllerListener which listens to the Players of - * {@link #playbacks} for ControllerEvents. - */ - private ControllerListener playerControllerListener; - - /** - * The JMF Processor which transcodes {@link #captureDevice} into - * the format of this instance. - */ - private Processor processor; - - /** - * The ControllerListener which listens to {@link #processor} for - * ControllerEvents. - */ - private ControllerListener processorControllerListener; - - /** - * The indicator which determines whether {@link #processor} has received - * a ControllerClosedEvent at an unexpected time in its execution. - * A value of false does not mean that processor exists - * or that it is not closed, it just means that if processor failed - * to be initialized or it received a ControllerClosedEvent, it was - * at an expected time of its execution and that the fact in question was - * reflected, for example, by setting processor to null. - * If there is no processorIsPrematurelyClosed field and - * processor is set to null or left existing after the - * receipt of ControllerClosedEvent, it will either lead to not - * firing a PropertyChangeEvent for OUTPUT_DATA_SOURCE - * when it has actually changed and, consequently, cause the - * SendStreams of MediaStreamImpl to not be recreated or - * it will be impossible to detect that processor cannot have its - * format set and will thus be left broken even for subsequent calls to - * {@link #setFormat(MediaFormat)}. - */ - private boolean processorIsPrematurelyClosed; - - /** - * The list of SSRC identifiers representing the parties that we are - * currently handling receive streams from. - */ - private long[] ssrcList = null; - - /** - * The MediaDirection in which this MediaDeviceSession has - * been started. - */ - private MediaDirection startedDirection = MediaDirection.INACTIVE; - - /** - * If the player have to be disposed when we {@link #close()} this instance. - */ - private boolean disposePlayerOnClose = true; - - /** - * Whether output size has changed after latest processor config. - * Used for video streams. - */ - protected boolean outputsizeChanged = false; - - /** - * Initializes a new MediaDeviceSession instance which is to - * represent the use of a specific MediaDevice by a - * MediaStream. - * - * @param device the MediaDevice the use of which by a - * MediaStream is to be represented by the new instance - */ - protected MediaDeviceSession(AbstractMediaDevice device) - { - checkDevice(device); - - this.device = device; - } - - /** - * Sets the indicator which determines whether this instance is to dispose - * of its associated player upon closing. - * - * @param disposePlayerOnClose true to have this instance dispose - * of its associated player upon closing; otherwise, false - */ - public void setDisposePlayerOnClose(boolean disposePlayerOnClose) - { - this.disposePlayerOnClose = disposePlayerOnClose; - } - - /** - * Adds ssrc to the array of SSRC identifiers representing parties - * that this MediaDeviceSession is currently receiving streams - * from. We use this method mostly as a way of to caching SSRC identifiers - * during a conference call so that the streams that are sending CSRC lists - * could have them ready for use rather than have to construct them for - * every RTP packet. - * - * @param ssrc the new SSRC identifier that we'd like to add to the array of - * ssrc identifiers stored by this session. - */ - protected void addSSRC(long ssrc) - { - //init if necessary - if ( ssrcList == null) - { - setSsrcList(new long[]{ssrc}); - return; - } - - //check whether we already have this ssrc - for ( long i : ssrcList) - { - if ( i == ssrc) - return; - } - - //resize the array and add the new ssrc to the end. - long[] newSsrcList = new long[ssrcList.length + 1]; - - System.arraycopy(ssrcList, 0, newSsrcList, 0, ssrcList.length); - newSsrcList[newSsrcList.length - 1] = ssrc; - - setSsrcList(newSsrcList); - } - - /** - * For JPEG and H263, we know that they only work for particular sizes. So - * we'll perform extra checking here to make sure they are of the right - * sizes. - * - * @param sourceFormat the original format to check the size of - * @return the modified VideoFormat set to the size we support - */ - private static VideoFormat assertSize(VideoFormat sourceFormat) - { - int width, height; - - // JPEG - if (sourceFormat.matches(new Format(VideoFormat.JPEG_RTP))) - { - Dimension size = sourceFormat.getSize(); - - // For JPEG, make sure width and height are divisible by 8. - width = (size.width % 8 == 0) - ? size.width - : ((size.width / 8) * 8); - height = (size.height % 8 == 0) - ? size.height - : ((size.height / 8) * 8); - } - // H.263 - else if (sourceFormat.matches(new Format(VideoFormat.H263_RTP))) - { - // For H.263, we only support some specific sizes. -// if (size.width < 128) -// { -// width = 128; -// height = 96; -// } -// else if (size.width < 176) -// { -// width = 176; -// height = 144; -// } -// else -// { - width = 352; - height = 288; -// } - } - else - { - // We don't know this particular format. We'll just leave it alone - // then. - return sourceFormat; - } - - VideoFormat result - = new VideoFormat( - null, - new Dimension(width, height), - Format.NOT_SPECIFIED, - null, - Format.NOT_SPECIFIED); - return (VideoFormat) result.intersects(sourceFormat); - } - - /** - * Asserts that a specific MediaDevice is acceptable to be set as - * the MediaDevice of this instance. Allows extenders to override - * and customize the check. - * - * @param device the MediaDevice to be checked for suitability to - * become the MediaDevice of this instance - */ - protected void checkDevice(AbstractMediaDevice device) - { - } - - /** - * Releases the resources allocated by this instance in the course of its - * execution and prepares it to be garbage collected. - */ - public void close() - { - /** - * Here the order of stopping the playback and capture is important - * cause when we use echo cancellation the capturer access data from - * the render part and so there a synchronized so we don't get - * SEGFAULTS, but sometimes this synchronization can lead to slowly - * stopping of the renderer. Thats why we first stop the capturer. - */ - - // capture - disconnectCaptureDevice(); - closeProcessor(); - - // playback - if (disposePlayerOnClose) - disposePlayer(); - - processor = null; -// player = null; - captureDevice = null; - } - - /** - * Makes sure {@link #processor} is closed. - */ - private void closeProcessor() - { - if (processor != null) - { - if (processorControllerListener != null) - processor.removeControllerListener(processorControllerListener); - - processor.stop(); - if (logger.isTraceEnabled()) - logger - .trace( - "Stopped Processor with hashCode " - + processor.hashCode()); - - if (processor.getState() == Processor.Realized) - { - DataSource dataOutput; - - try - { - dataOutput = processor.getDataOutput(); - } - catch (NotRealizedError nre) - { - dataOutput = null; - } - if (dataOutput != null) - dataOutput.disconnect(); - } - - processor.deallocate(); - processor.close(); - processorIsPrematurelyClosed = false; - - /* - * Once the processor uses the captureDevice, the captureDevice has - * to be reconnected on its next use. - */ - disconnectCaptureDevice(); - } - } - - /** - * Creates the DataSource that this instance is to read captured - * media from. - * - * @return the DataSource that this instance is to read captured - * media from - */ - protected DataSource createCaptureDevice() - { - DataSource captureDevice = getDevice().createOutputDataSource(); - - if (!(captureDevice instanceof MuteDataSource)) - { - // Try to enable muting. - if (captureDevice instanceof PushBufferDataSource) - { - captureDevice - = new RewritablePushBufferDataSource( - (PushBufferDataSource) captureDevice); - } - else if (captureDevice instanceof PullBufferDataSource) - { - captureDevice - = new RewritablePullBufferDataSource( - (PullBufferDataSource) captureDevice); - } - } - if (captureDevice instanceof MuteDataSource) - ((MuteDataSource) captureDevice).setMute(mute); - - return captureDevice; - } - - /** - * Creates a new Player for a specific DataSource so that - * it is played back on the MediaDevice represented by this - * instance. - * - * @param dataSource the DataSource to create a new Player - * for - * @return a new Player for the specified dataSource - */ - protected Player createPlayer(DataSource dataSource) - { - Processor player = null; - Throwable exception = null; - - // A Player is documented to be created on a connected DataSource. - try - { - dataSource.connect(); - } - catch (IOException ioex) - { - // TODO - exception = ioex; - } - if (exception != null) - { - logger.error( - "Failed to connect to " - + MediaStreamImpl.toString(dataSource), - exception); - return player; - } - - try - { - player = Manager.createProcessor(dataSource); - } - catch (IOException ioe) - { - exception = ioe; - } - catch (NoPlayerException npe) - { - exception = npe; - } - if (exception != null) - { - logger.error( - "Failed to create Player for " - + MediaStreamImpl.toString(dataSource), - exception); - } - else - { - /* - * We cannot wait for the Player to get configured (e.g. with - * waitForState) because it will stay in the Configuring state until - * it reads some media. In the case of a ReceiveStream not sending - * media (e.g. abnormally stopped), it will leave us blocked. - */ - if (playerControllerListener == null) - playerControllerListener = new ControllerListener() - { - - /** - * Notifies this ControllerListener that the - * Controller which it is registered with has - * generated an event. - * - * @param event the ControllerEvent specifying the - * Controller which is the source of the event and - * the very type of the event - * @see ControllerListener#controllerUpdate(ControllerEvent) - */ - public void controllerUpdate(ControllerEvent event) - { - playerControllerUpdate(event); - } - }; - player.addControllerListener(playerControllerListener); - - player.configure(); - if (logger.isTraceEnabled()) - logger.trace( - "Created Player with hashCode " - + player.hashCode() - + " for " - + MediaStreamImpl.toString(dataSource)); - } - - if (player == null) - dataSource.disconnect(); - - return player; - } - - /** - * Initializes a new FMJ Processor which is to transcode - * {@link #captureDevice} into the format of this instance. - * - * @return a new FMJ Processor which is to transcode - * captureDevice into the format of this instance - */ - protected Processor createProcessor() - { - DataSource captureDevice = getConnectedCaptureDevice(); - - if (captureDevice != null) - { - Processor processor = null; - Throwable exception = null; - - try - { - processor = Manager.createProcessor(captureDevice); - } - catch (IOException ioe) - { - // TODO - exception = ioe; - } - catch (NoProcessorException npe) - { - // TODO - exception = npe; - } - - if (exception != null) - logger - .error( - "Failed to create Processor for " + captureDevice, - exception); - else - { - if (processorControllerListener == null) - processorControllerListener = new ControllerListener() - { - - /** - * Notifies this ControllerListener that - * the Controller which it is registered - * with has generated an event. - * - * @param event the ControllerEvent - * specifying the Controller which is the - * source of the event and the very type of the - * event - * @see ControllerListener#controllerUpdate( - * ControllerEvent) - */ - public void controllerUpdate(ControllerEvent event) - { - processorControllerUpdate(event); - } - }; - processor - .addControllerListener(processorControllerListener); - - if (waitForState(processor, Processor.Configured)) - { - this.processor = processor; - processorIsPrematurelyClosed = false; - } - else - { - if (processorControllerListener != null) - processor - .removeControllerListener( - processorControllerListener); - processor = null; - } - } - } - - return this.processor; - } - - /** - * Creates a ContentDescriptor to be set on a specific - * Processor of captured media to be sent to the remote peer. - * Allows extenders to override. The default implementation returns - * {@link ContentDescriptor#RAW_RTP}. - * - * @param processor the Processor of captured media to be sent to - * the remote peer which is to have its contentDescriptor set to - * the returned ContentDescriptor - * @return a ContentDescriptor to be set on the specified - * processor of captured media to be sent to the remote peer - */ - protected ContentDescriptor createProcessorContentDescriptor( - Processor processor) - { - return - (contentDescriptor == null) - ? new ContentDescriptor(ContentDescriptor.RAW_RTP) - : contentDescriptor; - } - - /** - * Makes sure {@link #captureDevice} is disconnected. - */ - private void disconnectCaptureDevice() - { - if (captureDevice != null) - { - /* - * As reported by Carlos Alexandre, stopping before disconnecting - * resolves a slow disconnect on Linux. - */ - try - { - captureDevice.stop(); - } - catch (IOException ioe) - { - /* - * We cannot do much about the exception because we're not - * really interested in the stopping but rather in calling - * DataSource#disconnect() anyway. - */ - logger - .error( - "Failed to properly stop captureDevice " - + captureDevice, - ioe); - } - - captureDevice.disconnect(); - captureDeviceIsConnected = false; - } - } - - /** - * Releases the resources allocated by the Players of - * {@link #playbacks} in the course of their execution and prepares them to - * be garbage collected. - */ - private void disposePlayer() - { - synchronized (playbacks) - { - for (Playback playback : playbacks) - if (playback.player != null) - { - disposePlayer(playback.player); - playback.player = null; - } - } - } - - /** - * Releases the resources allocated by a specific Player in the - * course of its execution and prepares it to be garbage collected. - * - * @param player the Player to dispose of - */ - protected void disposePlayer(Player player) - { - synchronized (playbacks) - { - if (playerControllerListener != null) - player.removeControllerListener(playerControllerListener); - player.stop(); - player.deallocate(); - player.close(); - } - } - - /** - * Finds the first Format instance in a specific list of - * Formats which matches a specific Format. The - * implementation considers a pair of Formats matching if they have - * the same encoding. - * - * @param formats the array of Formats to be searched for a match - * to the specified format - * @param format the Format to search for a match in the specified - * formats - * @return the first element of formats which matches - * format i.e. is of the same encoding - */ - private static Format findFirstMatchingFormat( - Format[] formats, - Format format) - { - double formatSampleRate - = (format instanceof AudioFormat) - ? ((AudioFormat) format).getSampleRate() - : Format.NOT_SPECIFIED; - ParameterizedVideoFormat parameterizedVideoFormat - = (format instanceof ParameterizedVideoFormat) - ? (ParameterizedVideoFormat) format - : null; - - for (Format match : formats) - { - if (match.isSameEncoding(format)) - { - /* - * The encoding alone is, of course, not enough. For example, - * AudioFormats may have different sample rates (i.e. clock - * rates as we call them in MediaFormat). - */ - if (match instanceof AudioFormat) - { - if (formatSampleRate != Format.NOT_SPECIFIED) - { - double matchSampleRate - = ((AudioFormat) match).getSampleRate(); - - if ((matchSampleRate != Format.NOT_SPECIFIED) - && (matchSampleRate != formatSampleRate)) - continue; - } - } - else if (match instanceof ParameterizedVideoFormat) - { - if (!((ParameterizedVideoFormat) match) - .formatParametersMatch(format)) - continue; - } - else if (parameterizedVideoFormat != null) - { - if (!parameterizedVideoFormat.formatParametersMatch(match)) - continue; - } - return match; - } - } - return null; - } - - /** - * Gets the DataSource that this instance uses to read captured - * media from. If it does not exist yet, it is created. - * - * @return the DataSource that this instance uses to read captured - * media from - */ - public synchronized DataSource getCaptureDevice() - { - if (captureDevice == null) - captureDevice = createCaptureDevice(); - return captureDevice; - } - - /** - * Gets {@link #captureDevice} in a connected state. If this instance is not - * connected to captureDevice yet, first tries to connect to it. - * Returns null if this instance fails to create - * captureDevice or to connect to it. - * - * @return {@link #captureDevice} in a connected state; null if - * this instance fails to create captureDevice or to connect to it - */ - protected DataSource getConnectedCaptureDevice() - { - DataSource captureDevice = getCaptureDevice(); - - if ((captureDevice != null) && !captureDeviceIsConnected) - { - /* - * Give this instance a chance to set up an optimized media codec - * chain by setting the output Format on the input CaptureDevice. - */ - try - { - if (this.format != null) - setCaptureDeviceFormat(captureDevice, this.format); - } - catch (Throwable t) - { - logger.warn( - "Failed to setup an optimized media codec chain" - + " by setting the output Format" - + " on the input CaptureDevice", - t); - } - - Throwable exception = null; - - try - { - getDevice().connect(captureDevice); - } - catch (IOException ioex) - { - exception = ioex; - } - - if (exception == null) - captureDeviceIsConnected = true; - else - { - logger.error( - "Failed to connect to " - + MediaStreamImpl.toString(captureDevice), - exception); - captureDevice = null; - } - } - return captureDevice; - } - - /** - * Gets the MediaDevice associated with this instance and the work - * of a MediaStream with which is represented by it. - * - * @return the MediaDevice associated with this instance and the - * work of a MediaStream with which is represented by it - */ - public AbstractMediaDevice getDevice() - { - return device; - } - - /** - * Gets the JMF Format in which this instance captures media. - * - * @return the JMF Format in which this instance captures media. - */ - public Format getProcessorFormat() - { - Processor processor = getProcessor(); - - if ((processor != null) - && (this.processor == processor) - && !processorIsPrematurelyClosed) - { - MediaType mediaType = getMediaType(); - - for (TrackControl trackControl : processor.getTrackControls()) - { - if (!trackControl.isEnabled()) - continue; - - Format jmfFormat = trackControl.getFormat(); - MediaType type - = (jmfFormat instanceof VideoFormat) - ? MediaType.VIDEO - : MediaType.AUDIO; - - if (mediaType.equals(type)) - return jmfFormat; - } - } - return null; - } - - /** - * Gets the MediaFormat in which this instance captures media from - * its associated MediaDevice. - * - * @return the MediaFormat in which this instance captures media - * from its associated MediaDevice - */ - public MediaFormatImpl getFormat() - { - /* - * If the Format of the processor is different than the format of this - * MediaDeviceSession, we'll likely run into unexpected issues so debug - * whether there are such cases. - */ - if (logger.isDebugEnabled() && (processor != null)) - { - Format processorFormat = getProcessorFormat(); - Format format - = (this.format == null) ? null : this.format.getFormat(); - boolean processorFormatMatchesFormat - = (processorFormat == null) - ? (format == null) - : processorFormat.matches(format); - - if (!processorFormatMatchesFormat) - { - logger.debug( - "processorFormat != format; processorFormat= `" - + processorFormat - + "`; format= `" - + format - + "`"); - } - } - - return format; - } - - /** - * Gets the MediaType of the media captured and played back by this - * instance. It is the same as the MediaType of its associated - * MediaDevice. - * - * @return the MediaType of the media captured and played back by - * this instance as reported by {@link MediaDevice#getMediaType()} of its - * associated MediaDevice - */ - private MediaType getMediaType() - { - return getDevice().getMediaType(); - } - - /** - * Gets the output DataSource of this instance which provides the - * captured (RTP) data to be sent by MediaStream to - * MediaStreamTarget. - * - * @return the output DataSource of this instance which provides - * the captured (RTP) data to be sent by MediaStream to - * MediaStreamTarget - */ - public DataSource getOutputDataSource() - { - Processor processor = getProcessor(); - DataSource outputDataSource; - - if ((processor == null) - || ((processor.getState() < Processor.Realized) - && !waitForState(processor, Processor.Realized))) - outputDataSource = null; - else - { - outputDataSource = processor.getDataOutput(); - if (logger.isTraceEnabled() && (outputDataSource != null)) - logger - .trace( - "Processor with hashCode " - + processor.hashCode() - + " provided " - + MediaStreamImpl.toString(outputDataSource)); - - /* - * Whoever wants the outputDataSource, they expect it to be started - * in accord with the previously-set direction. - */ - startProcessorInAccordWithDirection(processor); - } - return outputDataSource; - } - - /** - * Gets the information related to the playback of a specific - * DataSource on the MediaDevice represented by this - * MediaDeviceSession. - * - * @param dataSource the DataSource to get the information related - * to the playback of - * @return the information related to the playback of the specified - * DataSource on the MediaDevice represented by this - * MediaDeviceSession - */ - private Playback getPlayback(DataSource dataSource) - { - synchronized (playbacks) - { - for (Playback playback : playbacks) - if (playback.dataSource == dataSource) - return playback; - } - return null; - } - - /** - * Gets the information related to the playback of a specific - * ReceiveStream on the MediaDevice represented by this - * MediaDeviceSession. - * - * @param receiveStream the ReceiveStream to get the information - * related to the playback of - * @return the information related to the playback of the specified - * ReceiveStream on the MediaDevice represented by this - * MediaDeviceSession - */ - private Playback getPlayback(ReceiveStream receiveStream) - { - synchronized (playbacks) - { - for (Playback playback : playbacks) - if (playback.receiveStream == receiveStream) - return playback; - } - return null; - } - - /** - * Gets the Players rendering the ReceiveStreams of this - * instance on its associated MediaDevice. - * - * @return the Players rendering the ReceiveStreams of - * this instance on its associated MediaDevice - */ - protected List getPlayers() - { - List players; - - synchronized (playbacks) - { - players = new ArrayList(playbacks.size()); - for (Playback playback : playbacks) - if (playback.player != null) - players.add(playback.player); - } - return players; - } - - /** - * Gets the Players rendering the ReceiveStream - * corresponding to the given ssrc. - * - * @param ssrc the src-id of the receive stream, which player we're - * looking for - * @return the Players rendering the ReceiveStream - * corresponding to the given ssrc - */ - protected Player getPlayer(long ssrc) - { - synchronized (playbacks) - { - for (Playback playback : playbacks) - if (playback.receiveStream.getSSRC() == ssrc) - return playback.player; - } - return null; - } - - /** - * Gets the JMF Processor which transcodes the MediaDevice - * of this instance into the format of this instance. - * - * @return the JMF Processor which transcodes the - * MediaDevice of this instance into the format of this instance - */ - private Processor getProcessor() - { - if (processor == null) - processor = createProcessor(); - return processor; - } - - /** - * Gets a list of the ReceiveStreams being played back on the - * MediaDevice represented by this instance. - * - * @return a list of ReceiveStreams being played back on the - * MediaDevice represented by this instance - */ - public List getReceiveStreams() - { - List receiveStreams; - - synchronized (playbacks) - { - receiveStreams = new ArrayList(playbacks.size()); - for (Playback playback : playbacks) - if (playback.receiveStream != null) - receiveStreams.add(playback.receiveStream); - } - return receiveStreams; - } - - /** - * Returns the list of SSRC identifiers that this device session is handling - * streams from. In this case (i.e. the case of a device session handling - * a single remote party) we would rarely (if ever) have more than a single - * SSRC identifier returned. However, we would also be using the same method - * to query a device session operating over a mixer in which case we would - * have the SSRC IDs of all parties currently contributing to the mixing. - * - * @return a long[] array of SSRC identifiers that this device - * session is handling streams from. - */ - public long[] getRemoteSSRCList() - { - return ssrcList; - } - - /** - * Gets the MediaDirection in which this instance has been started. - * For example, a MediaDirection which returns true for - * allowsSending() signals that this instance is capturing media - * from its MediaDevice. - * - * @return the MediaDirection in which this instance has been - * started - */ - public MediaDirection getStartedDirection() - { - return startedDirection; - } - - /** - * Gets a list of the MediaFormats in which this instance is - * capable of capturing media from its associated MediaDevice. - * - * @return a new list of MediaFormats in which this instance is - * capable of capturing media from its associated MediaDevice - */ - public List getSupportedFormats() - { - Processor processor = getProcessor(); - Set supportedFormats = new HashSet(); - - if ((processor != null) - && (this.processor == processor) - && !processorIsPrematurelyClosed) - { - MediaType mediaType = getMediaType(); - - for (TrackControl trackControl : processor.getTrackControls()) - { - if (!trackControl.isEnabled()) - continue; - - for (Format supportedFormat : trackControl.getSupportedFormats()) - switch (mediaType) - { - case AUDIO: - if (supportedFormat instanceof AudioFormat) - supportedFormats.add(supportedFormat); - break; - case VIDEO: - if (supportedFormat instanceof VideoFormat) - supportedFormats.add(supportedFormat); - break; - } - } - } - - List supportedMediaFormats - = new ArrayList(supportedFormats.size()); - - for (Format format : supportedFormats) - supportedMediaFormats.add(MediaFormatImpl.createInstance(format)); - return supportedMediaFormats; - } - - /** - * Determines whether this MediaDeviceSession is set to output - * "silence" instead of the actual media fed from its - * CaptureDevice. - * - * @return true if this MediaDeviceSession is set to - * output "silence" instead of the actual media fed from its - * CaptureDevice; otherwise, false - */ - public boolean isMute() - { - DataSource captureDevice = this.captureDevice; - - if (captureDevice == null) - return mute; - if (captureDevice instanceof MuteDataSource) - return ((MuteDataSource) captureDevice).isMute(); - return false; - } - - /** - * Notifies this MediaDeviceSession that a DataSource has - * been added for playback on the represented MediaDevice. - * - * @param playbackDataSource the DataSource which has been added - * for playback on the represented MediaDevice - */ - protected void playbackDataSourceAdded(DataSource playbackDataSource) - { - } - - /** - * Notifies this MediaDeviceSession that a DataSource has - * been removed from playback on the represented MediaDevice. - * - * @param playbackDataSource the DataSource which has been removed - * from playback on the represented MediaDevice - */ - protected void playbackDataSourceRemoved(DataSource playbackDataSource) - { - } - - /** - * Notifies this instance that a specific Player of remote content - * has generated a ConfigureCompleteEvent. Allows extenders to - * carry out additional processing on the Player. - * - * @param player the Player which is the source of a - * ConfigureCompleteEvent - */ - protected void playerConfigureComplete(Processor player) - { - TrackControl[] tcs = player.getTrackControls(); - - if ((tcs != null) && (tcs.length != 0)) - { - AbstractMediaDevice device = getDevice(); - - for (int i = 0; i < tcs.length; i++) - { - TrackControl tc = tcs[i]; - Renderer renderer = device.createRenderer(); - - if (renderer != null) - try - { - tc.setRenderer(renderer); - } - catch (UnsupportedPlugInException upie) - { - logger.warn( - "Failed to set " - + renderer.getClass().getName() - + " renderer on track " - + i, - upie); - } - } - } - } - - /** - * Gets notified about ControllerEvents generated by a specific - * Player of remote content. - *

- * Extenders who choose to override are advised to override more specialized - * methods such as {@link #playerConfigureComplete(Processor)} and - * {@link #playerRealizeComplete(Processor)}. In any case, extenders - * overriding this method should call the super implementation. - *

- * - * @param event the ControllerEvent specifying the - * Controller which is the source of the event and the very type of - * the event - */ - protected void playerControllerUpdate(ControllerEvent event) - { - if (event instanceof ConfigureCompleteEvent) - { - Processor player = (Processor) event.getSourceController(); - - if (player != null) - { - playerConfigureComplete(player); - - /* - * To use the processor as a Player we must set its - * ContentDescriptor to null. - */ - try - { - player.setContentDescriptor(null); - } - catch (NotConfiguredError nce) - { - logger.error( - "Failed to set ContentDescriptor to Player.", - nce); - return; - } - - player.realize(); - } - } - else if (event instanceof RealizeCompleteEvent) - { - Processor player = (Processor) event.getSourceController(); - - if (player != null) - { - playerRealizeComplete(player); - - player.start(); - } - } - } - - /** - * Notifies this instance that a specific Player of remote content - * has generated a RealizeCompleteEvent. Allows extenders to carry - * out additional processing on the Player. - * - * @param player the Player which is the source of a - * RealizeCompleteEvent - */ - protected void playerRealizeComplete(Processor player) - { - } - - /** - * Gets notified about ControllerEvents generated by - * {@link #processor}. - * - * @param event the ControllerEvent specifying the - * Controller which is the source of the event and the very type of - * the event - */ - protected void processorControllerUpdate(ControllerEvent event) - { - if (event instanceof ConfigureCompleteEvent) - { - Processor processor = (Processor) event.getSourceController(); - - if (processor != null) - { - try - { - processor.setContentDescriptor( - createProcessorContentDescriptor(processor)); - } - catch (NotConfiguredError nce) - { - logger - .error( - "Failed to set ContentDescriptor to Processor.", - nce); - } - - if (format != null) - setProcessorFormat(processor, format); - } - } - else if (event instanceof ControllerClosedEvent) - { - Processor processor = (Processor) event.getSourceController(); - - /* - * If everything goes according to plan, we should've removed the - * ControllerListener from the processor by now. - */ - logger.warn(event); - - // TODO Should the access to processor be synchronized? - if ((processor != null) && (this.processor == processor)) - processorIsPrematurelyClosed = true; - } - } - - /** - * Removes ssrc from the array of SSRC identifiers representing - * parties that this MediaDeviceSession is currently receiving - * streams from. - * - * @param ssrc the SSRC identifier that we'd like to remove from the array - * of ssrc identifiers stored by this session. - */ - protected void removeSSRC(long ssrc) - { - //find the ssrc - int index = -1; - - if (ssrcList == null || ssrcList.length == 0) - { - //list is already empty so there's nothing to do. - return; - } - - for (int i = 0; i < ssrcList.length; i++) - { - if (ssrcList[i] == ssrc) - { - index = i; - break; - } - } - - if (index < 0 || index >= ssrcList.length) - { - //the ssrc we are trying to remove is not in the list so there's - //nothing to do. - return; - } - - //if we get here and the list has a single element this would mean we - //simply need to empty it as the only element is the one we are removing - if (ssrcList.length == 1) - { - setSsrcList(null); - return; - } - - long[] newSsrcList = new long[ssrcList.length]; - - System.arraycopy(ssrcList, 0, newSsrcList, 0, index); - if (index < ssrcList.length - 1) - { - System.arraycopy(ssrcList, index + 1, - newSsrcList, index, - ssrcList.length - index - 1); - } - - setSsrcList(newSsrcList); - } - - /** - * Notifies this instance that a specific ReceiveStream has been - * added to the list of playbacks of ReceiveStreams and/or - * DataSources performed by respective Players on the - * MediaDevice represented by this instance. - * - * @param receiveStream the ReceiveStream which has been added to - * the list of playbacks of ReceiveStreams and/or - * DataSources performed by respective Players on the - * MediaDevice represented by this instance - */ - protected void receiveStreamAdded(ReceiveStream receiveStream) - { - } - - /** - * Notifies this instance that a specific ReceiveStream has been - * removed from the list of playbacks of ReceiveStreams and/or - * DataSources performed by respective Players on the - * MediaDevice represented by this instance. - * - * @param receiveStream the ReceiveStream which has been removed - * from the list of playbacks of ReceiveStreams and/or - * DataSources performed by respective Players on the - * MediaDevice represented by this instance - */ - protected void receiveStreamRemoved(ReceiveStream receiveStream) - { - } - - protected void setCaptureDeviceFormat( - DataSource captureDevice, - MediaFormatImpl mediaFormat) - { - Format format = mediaFormat.getFormat(); - - if (format instanceof AudioFormat) - { - AudioFormat audioFormat = (AudioFormat) format; - int channels = Format.NOT_SPECIFIED; - double sampleRate - = OSUtils.IS_ANDROID - ? audioFormat.getSampleRate() - : Format.NOT_SPECIFIED; - - if ((channels != Format.NOT_SPECIFIED) - || (sampleRate != Format.NOT_SPECIFIED)) - { - FormatControl formatControl - = (FormatControl) - captureDevice.getControl( - FormatControl.class.getName()); - - if (formatControl != null) - { - Format[] supportedFormats - = formatControl.getSupportedFormats(); - - if ((supportedFormats != null) - && (supportedFormats.length != 0)) - { - if (sampleRate != Format.NOT_SPECIFIED) - { - /* - * As per RFC 3551.4.5.2, because of a mistake in - * RFC 1890 and for backward compatibility, G.722 - * should always be announced as 8000 even though it - * is wideband. - */ - String encoding = audioFormat.getEncoding(); - - if ((Constants.G722.equalsIgnoreCase(encoding) - || Constants.G722_RTP.equalsIgnoreCase( - encoding)) - && (sampleRate == 8000)) - { - sampleRate = 16000; - } - } - - Format supportedAudioFormat = null; - - for (int i = 0; i < supportedFormats.length; i++) - { - Format sf = supportedFormats[i]; - - if (sf instanceof AudioFormat) - { - AudioFormat saf = (AudioFormat) sf; - - if ((Format.NOT_SPECIFIED != channels) - && (saf.getChannels() != channels)) - continue; - if ((Format.NOT_SPECIFIED != sampleRate) - && (saf.getSampleRate() != sampleRate)) - continue; - - supportedAudioFormat = saf; - break; - } - } - - if (supportedAudioFormat != null) - formatControl.setFormat(supportedAudioFormat); - } - } - } - } - } - - /** - * Sets the ContentDescriptor which specifies the content type in - * which this MediaDeviceSession is to output the media captured by - * its MediaDevice. The default content type in which - * MediaDeviceSession outputs the media captured by its - * MediaDevice is {@link ContentDescriptor#RAW_RTP}. - * - * @param contentDescriptor the ContentDescriptor which specifies - * the content type in which this MediaDeviceSession is to output - * the media captured by its MediaDevice - */ - public void setContentDescriptor(ContentDescriptor contentDescriptor) - { - if (contentDescriptor == null) - throw new NullPointerException("contentDescriptor"); - - this.contentDescriptor = contentDescriptor; - } - - /** - * Sets the MediaFormat in which this MediaDeviceSession - * outputs the media captured by its MediaDevice. - * - * @param format the MediaFormat in which this - * MediaDeviceSession is to output the media captured by its - * MediaDevice - */ - public void setFormat(MediaFormat format) - { - if (!getMediaType().equals(format.getMediaType())) - throw new IllegalArgumentException("format"); - - /* - * We need javax.media.Format and we know how to convert MediaFormat to - * it only for MediaFormatImpl so assert early. - */ - @SuppressWarnings("unchecked") - MediaFormatImpl mediaFormatImpl - = (MediaFormatImpl) format; - - this.format = mediaFormatImpl; - if (logger.isTraceEnabled()) - { - logger.trace( - "Set format " + this.format - + " on " - + getClass().getSimpleName() + " " + hashCode()); - } - - /* - * If the processor is after Configured, setting a different format will - * silently fail. Recreate the processor in order to be able to set the - * different format. - */ - if (processor != null) - { - int processorState = processor.getState(); - - if (processorState == Processor.Configured) - setProcessorFormat(processor, this.format); - else if (processorIsPrematurelyClosed - || ((processorState > Processor.Configured) - && !this.format.getFormat().equals( - getProcessorFormat())) - || outputsizeChanged) - { - outputsizeChanged = false; - setProcessor(null); - } - } - } - - /** - * Sets the MediaFormatImpl in which a specific Processor - * producing media to be streamed to the remote peer is to output. - * - * @param processor the Processor to set the output - * MediaFormatImpl of - * @param mediaFormat the MediaFormatImpl to set on - * processor - */ - protected void setProcessorFormat( - Processor processor, - MediaFormatImpl mediaFormat) - { - TrackControl[] trackControls = processor.getTrackControls(); - MediaType mediaType = getMediaType(); - Format format = mediaFormat.getFormat(); - - for (int trackIndex = 0; - trackIndex < trackControls.length; - trackIndex++) - { - TrackControl trackControl = trackControls[trackIndex]; - - if (!trackControl.isEnabled()) - continue; - - Format[] supportedFormats = trackControl.getSupportedFormats(); - - if ((supportedFormats == null) || (supportedFormats.length < 1)) - { - trackControl.setEnabled(false); - continue; - } - - Format supportedFormat = null; - - switch (mediaType) - { - case AUDIO: - if (supportedFormats[0] instanceof AudioFormat) - { - supportedFormat - = findFirstMatchingFormat(supportedFormats, format); - - /* - * We've failed to find a supported format so try to use - * whatever we've been told and, if it fails, the caller - * will at least know why. - */ - if (supportedFormat == null) - supportedFormat = format; - } - break; - case VIDEO: - if (supportedFormats[0] instanceof VideoFormat) - { - supportedFormat - = findFirstMatchingFormat(supportedFormats, format); - - /* - * We've failed to find a supported format so try to use - * whatever we've been told and, if it fails, the caller - * will at least know why. - */ - if (supportedFormat == null) - supportedFormat = format; - if (supportedFormat != null) - supportedFormat - = assertSize((VideoFormat) supportedFormat); - } - break; - } - - if (supportedFormat == null) - trackControl.setEnabled(false); - else if (!supportedFormat.equals(trackControl.getFormat())) - { - Format setFormat - = setProcessorFormat( - trackControl, - mediaFormat, supportedFormat); - - if (setFormat == null) - logger.error( - "Failed to set format of track " - + trackIndex - + " to " - + supportedFormat - + ". Processor is in state " - + processor.getState()); - else if (setFormat != supportedFormat) - logger.warn( - "Failed to change format of track " - + trackIndex - + " from " - + setFormat - + " to " - + supportedFormat - + ". Processor is in state " - + processor.getState()); - else if (logger.isTraceEnabled()) - logger.trace( - "Set format of track " - + trackIndex - + " to " - + setFormat); - } - } - } - - /** - * Sets the MediaFormatImpl of a specific TrackControl of - * the Processor which produces the media to be streamed by this - * MediaDeviceSession to the remote peer. Allows extenders to - * override the set procedure and to detect when the JMF Format of - * the specified TrackControl changes. - * - * @param trackControl the TrackControl to set the JMF - * Format of - * @param mediaFormat the MediaFormatImpl to be set on the - * specified TrackControl. Though mediaFormat encapsulates - * a JMF Format, format is to be set on the specified - * trackControl because it may be more specific. In any case, the - * two JMF Formats match. The MediaFormatImpl is provided - * anyway because it carries additional information such as format - * parameters. - * @param format the JMF Format to be set on the specified - * TrackControl. Though mediaFormat encapsulates a JMF - * Format, the specified format is to be set on the - * specified trackControl because it may be more specific than the - * JMF Format of the mediaFormat - * @return the JMF Format set on TrackControl after the - * attempt to set the specified format or null if the - * specified format was found to be incompatible with - * trackControl - */ - protected Format setProcessorFormat( - TrackControl trackControl, - MediaFormatImpl mediaFormat, - Format format) - { - return trackControl.setFormat(format); - } - - /** - * Sets the indicator which determines whether this - * MediaDeviceSession is set to output "silence" instead of the - * actual media fed from its CaptureDevice. - * - * @param mute true to set this MediaDeviceSession to - * output "silence" instead of the actual media fed from its - * CaptureDevice; otherwise, false - */ - public void setMute(boolean mute) - { - if (this.mute != mute) - { - this.mute = mute; - - DataSource captureDevice = this.captureDevice; - - if (captureDevice instanceof MuteDataSource) - ((MuteDataSource) captureDevice).setMute(this.mute); - } - } - - /** - * Adds a new inband DTMF tone to send. - * - * @param tone the DTMF tone to send. - */ - public void addDTMF(DTMFInbandTone tone) - { - DataSource captureDevice = this.captureDevice; - - if (captureDevice instanceof InbandDTMFDataSource) - { - ((InbandDTMFDataSource) captureDevice).addDTMF(tone); - } - } - - /** - * Adds a specific DataSource to the list of playbacks of - * ReceiveStreams and/or DataSources performed by - * respective Players on the MediaDevice represented by - * this instance. - * - * @param playbackDataSource the DataSource which to be added to - * the list of playbacks of ReceiveStreams and/or - * DataSources performed by respective Players on the - * MediaDevice represented by this instance - */ - public void addPlaybackDataSource(DataSource playbackDataSource) - { - synchronized (playbacks) - { - Playback playback = getPlayback(playbackDataSource); - - if (playback == null) - { - if (playbackDataSource - instanceof ReceiveStreamPushBufferDataSource) - { - ReceiveStream receiveStream - = ((ReceiveStreamPushBufferDataSource) - playbackDataSource) - .getReceiveStream(); - - playback = getPlayback(receiveStream); - } - if (playback == null) - { - playback = new Playback(playbackDataSource); - playbacks.add(playback); - } - else - playback.dataSource = playbackDataSource; - - playback.player = createPlayer(playbackDataSource); - - playbackDataSourceAdded(playbackDataSource); - } - } - } - - /** - * Removes a specific DataSource from the list of playbacks of - * ReceiveStreams and/or DataSources performed by - * respective Players on the MediaDevice represented by - * this instance. - * - * @param playbackDataSource the DataSource which to be removed - * from the list of playbacks of ReceiveStreams and/or - * DataSources performed by respective Players on the - * MediaDevice represented by this instance - */ - public void removePlaybackDataSource(DataSource playbackDataSource) - { - synchronized (playbacks) - { - Playback playback = getPlayback(playbackDataSource); - - if (playback != null) - { - if (playback.player != null) - { - disposePlayer(playback.player); - playback.player = null; - } - - playback.dataSource = null; - if (playback.receiveStream == null) - playbacks.remove(playback); - - playbackDataSourceRemoved(playbackDataSource); - } - } - } - - /** - * Sets the JMF Processor which is to transcode - * {@link #captureDevice} into the format of this instance. - * - * @param processor the JMF Processor which is to transcode - * {@link #captureDevice} into the format of this instance - */ - private void setProcessor(Processor processor) - { - if (this.processor != processor) - { - closeProcessor(); - - this.processor = processor; - - /* - * Since the processor has changed, its output DataSource known to - * the public has also changed. - */ - firePropertyChange(OUTPUT_DATA_SOURCE, null, null); - } - } - - /** - * Adds a specific ReceiveStream to the list of playbacks of - * ReceiveStreams and/or DataSources performed by - * respective Players on the MediaDevice represented by - * this instance. - * - * @param receiveStream the ReceiveStream which to be added to the - * list of playbacks of ReceiveStreams and/or DataSources - * performed by respective Players on the MediaDevice - * represented by this instance - */ - public void addReceiveStream(ReceiveStream receiveStream) - { - synchronized (playbacks) - { - if (getPlayback(receiveStream) == null) - { - playbacks.add(new Playback(receiveStream)); - - addSSRC(receiveStream.getSSRC()); - - // playbackDataSource - DataSource receiveStreamDataSource - = receiveStream.getDataSource(); - - if (receiveStreamDataSource != null) - { - if (receiveStreamDataSource instanceof PushBufferDataSource) - { - receiveStreamDataSource - = new ReceiveStreamPushBufferDataSource( - receiveStream, - (PushBufferDataSource) - receiveStreamDataSource, - true); - } - else - { - logger.warn( - "Adding ReceiveStream with DataSource" - + " not of type PushBufferDataSource but " - + receiveStreamDataSource.getClass() - .getSimpleName() - + " which may prevent the ReceiveStream" - + " from properly transferring to another" - + " MediaDevice if such a need arises."); - } - addPlaybackDataSource(receiveStreamDataSource); - } - - receiveStreamAdded(receiveStream); - } - } - } - - /** - * Removes a specific ReceiveStream from the list of playbacks of - * ReceiveStreams and/or DataSources performed by - * respective Players on the MediaDevice represented by - * this instance. - * - * @param receiveStream the ReceiveStream which to be removed from - * the list of playbacks of ReceiveStreams and/or - * DataSources performed by respective Players on the - * MediaDevice represented by this instance - */ - public void removeReceiveStream(ReceiveStream receiveStream) - { - synchronized (playbacks) - { - Playback playback = getPlayback(receiveStream); - - if (playback != null) - { - removeSSRC(receiveStream.getSSRC()); - if (playback.dataSource != null) - removePlaybackDataSource(playback.dataSource); - - if (playback.dataSource != null) - { - logger.warn( - "Removing ReceiveStream" - + " with associated DataSource"); - } - playbacks.remove(playback); - - receiveStreamRemoved(receiveStream); - } - } - } - - /** - * Sets the list of SSRC identifiers that this device stores to - * newSsrcList and fires a PropertyChangeEvent for the - * SSRC_LIST property. - * - * @param newSsrcList that SSRC array that we'd like to replace the existing - * SSRC list with. - */ - private void setSsrcList(long[] newSsrcList) - { - // use getRemoteSSRCList() instead of direct access to ssrcList - // as the extender may override it - long[] oldSsrcList = getRemoteSSRCList(); - ssrcList = newSsrcList; - - firePropertyChange(SSRC_LIST, oldSsrcList, getRemoteSSRCList()); - } - - /** - * Starts the processing of media in this instance in a specific direction. - * - * @param direction a MediaDirection value which represents the - * direction of the processing of media to be started. For example, - * {@link MediaDirection#SENDRECV} to start both capture and playback of - * media in this instance or {@link MediaDirection#SENDONLY} to only start - * the capture of media in this instance - */ - public void start(MediaDirection direction) - { - if (direction == null) - throw new NullPointerException("direction"); - - MediaDirection oldValue = startedDirection; - - startedDirection = startedDirection.or(direction); - if (!oldValue.equals(startedDirection)) - startedDirectionChanged(oldValue, startedDirection); - } - - /** - * Notifies this instance that the value of its startedDirection - * property has changed from a specific oldValue to a specific - * newValue. Allows extenders to override and perform additional - * processing of the change. Overriding implementations must call this - * implementation in order to ensure the proper execution of this - * MediaDeviceSession. - * - * @param oldValue the MediaDirection which used to be the value of - * the startedDirection property of this instance - * @param newValue the MediaDirection which is the value of the - * startedDirection property of this instance - */ - protected void startedDirectionChanged( - MediaDirection oldValue, - MediaDirection newValue) - { - if (newValue.allowsSending()) - { - Processor processor = getProcessor(); - - if (processor != null) - startProcessorInAccordWithDirection(processor); - } - else if ((processor != null) - && (processor.getState() > Processor.Configured)) - { - processor.stop(); - if (logger.isTraceEnabled()) - { - logger.trace( - "Stopped Processor with hashCode " - + processor.hashCode()); - } - } - } - - /** - * Starts a specific Processor if this MediaDeviceSession - * has been started and the specified Processor is not started. - * - * @param processor the Processor to start - */ - protected void startProcessorInAccordWithDirection(Processor processor) - { - if (startedDirection.allowsSending() - && (processor.getState() != Processor.Started)) - { - processor.start(); - if (logger.isTraceEnabled()) - { - logger.trace( - "Started Processor with hashCode " - + processor.hashCode()); - } - } - } - - /** - * Stops the processing of media in this instance in a specific direction. - * - * @param direction a MediaDirection value which represents the - * direction of the processing of media to be stopped. For example, - * {@link MediaDirection#SENDRECV} to stop both capture and playback of - * media in this instance or {@link MediaDirection#SENDONLY} to only stop - * the capture of media in this instance - */ - public void stop(MediaDirection direction) - { - if (direction == null) - throw new NullPointerException("direction"); - - MediaDirection oldValue = startedDirection; - - switch (startedDirection) - { - case SENDRECV: - if (direction.allowsReceiving()) - startedDirection - = direction.allowsSending() - ? MediaDirection.INACTIVE - : MediaDirection.SENDONLY; - else if (direction.allowsSending()) - startedDirection = MediaDirection.RECVONLY; - break; - case SENDONLY: - if (direction.allowsSending()) - startedDirection = MediaDirection.INACTIVE; - break; - case RECVONLY: - if (direction.allowsReceiving()) - startedDirection = MediaDirection.INACTIVE; - break; - case INACTIVE: - /* - * This MediaDeviceSession is already inactive so there's nothing to - * stop. - */ - break; - default: - throw new IllegalArgumentException("direction"); - } - - if (!oldValue.equals(startedDirection)) - startedDirectionChanged(oldValue, startedDirection); - } - - /** - * Waits for the specified JMF Processor to enter the specified - * state and returns true if processor has - * successfully entered state or false if process - * has failed to enter state. - * - * @param processor the JMF Processor to wait on - * @param state the state as defined by the respective Processor - * state constants to wait processor to enter - * @return true if processor has successfully entered - * state; otherwise, false - */ - private static boolean waitForState(Processor processor, int state) - { - return new ProcessorUtility().waitForState(processor, state); - } - - /** - * Copies the playback part of a specific MediaDeviceSession into - * this instance. - * - * @param deviceSession the MediaDeviceSession to copy the playback - * part of into this instance - */ - public void copyPlayback(MediaDeviceSession deviceSession) - { - if (deviceSession.disposePlayerOnClose) - { - logger.error( - "Cannot copy playback" - + " if MediaDeviceSession has closed it"); - } - else - { - playbacks.addAll(deviceSession.playbacks); - setSsrcList(deviceSession.ssrcList); - } - } - - /** - * Represents the information related to the playback of a - * DataSource on the MediaDevice represented by a - * MediaDeviceSession. The DataSource may have an - * associated ReceiveStream. - */ - private static class Playback - { - /** - * The DataSource the information related to the playback of - * which is represented by this instance and which is associated with - * {@link #receiveStream}. - */ - public DataSource dataSource; - - /** - * The ReceiveStream the information related to the playback of - * which is represented by this instance and which is associated with - * {@link #dataSource}. - */ - public ReceiveStream receiveStream; - - /** - * The Player which performs the actual playback. - */ - public Player player; - - /** - * Initializes a new Playback instance which is to represent - * the information related to the playback of a specific - * DataSource. - * - * @param dataSource the DataSource the information related to - * the playback of which is to be represented by the new instance - */ - public Playback(DataSource dataSource) - { - this.dataSource = dataSource; - } - - /** - * Initializes a new Playback instance which is to represent - * the information related to the playback of a specific - * ReceiveStream. - * - * @param receiveStream the ReceiveStream the information - * related to the playback of which is to be represented by the new - * instance - */ - public Playback(ReceiveStream receiveStream) - { - this.receiveStream = receiveStream; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/NoneAudioSystem.java b/src/net/java/sip/communicator/impl/neomedia/device/NoneAudioSystem.java deleted file mode 100644 index 139dfb978..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/NoneAudioSystem.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -/** - * Implements an AudioSystem without any devices which allows the user - * to select to use no audio capture, notification and playback. - * - * @author Lyubomir Marinov - */ -public class NoneAudioSystem - extends AudioSystem -{ - public static final String LOCATOR_PROTOCOL = "none"; - - public NoneAudioSystem() - throws Exception - { - super(LOCATOR_PROTOCOL); - } - - protected void doInitialize() - throws Exception - { - } - - @Override - public String toString() - { - return "None"; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/PortAudioSystem.java b/src/net/java/sip/communicator/impl/neomedia/device/PortAudioSystem.java deleted file mode 100644 index d8638b8ea..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/PortAudioSystem.java +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import java.util.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.audio.*; -import net.java.sip.communicator.impl.neomedia.portaudio.*; -import net.java.sip.communicator.util.*; - -/** - * Creates PortAudio capture devices by enumerating all host devices that have - * input channels. - * - * @author Damian Minkov - * @author Lyubomir Marinov - */ -public class PortAudioSystem - extends AudioSystem -{ - /** - * The Logger used by the PortAudioSystem class and its - * instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(PortAudioSystem.class); - - /** - * The protocol of the MediaLocators identifying PortAudio - * CaptureDevices - */ - private static final String LOCATOR_PROTOCOL = LOCATOR_PROTOCOL_PORTAUDIO; - - private Runnable devicesChangedCallback; - - /** - * Initializes a new PortAudioSystem instance which creates PortAudio - * capture devices by enumerating all host devices with input channels. - * - * @throws Exception if anything wrong happens while creating the PortAudio - * capture devices - */ - PortAudioSystem() - throws Exception - { - super( - LOCATOR_PROTOCOL, - FEATURE_DENOISE - | FEATURE_ECHO_CANCELLATION - | FEATURE_NOTIFY_AND_PLAYBACK_DEVICES - | FEATURE_REINITIALIZE); - } - - @Override - public Renderer createRenderer(boolean playback) - { - MediaLocator locator; - - if (playback) - locator = null; - else - { - CaptureDeviceInfo notifyDevice = getNotifyDevice(); - - if (notifyDevice == null) - return null; - else - locator = notifyDevice.getLocator(); - } - - PortAudioRenderer renderer = new PortAudioRenderer(playback); - - if ((renderer != null) && (locator != null)) - renderer.setLocator(locator); - - return renderer; - } - - protected void doInitialize() - throws Exception - { - /* - * If PortAudio fails to initialize because of, for example, a missing - * native counterpart, it will throw an exception here and the PortAudio - * Renderer will not be initialized. - */ - int deviceCount = PortAudio.Pa_GetDeviceCount(); - int channels = 1; - int sampleSizeInBits = 16; - long sampleFormat = PortAudio.getPaSampleFormat(sampleSizeInBits); - int defaultInputDeviceIndex = PortAudio.Pa_GetDefaultInputDevice(); - int defaultOutputDeviceIndex = PortAudio.Pa_GetDefaultOutputDevice(); - List captureDevices - = new LinkedList(); - List playbackDevices - = new LinkedList(); - - for (int deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) - { - long deviceInfo = PortAudio.Pa_GetDeviceInfo(deviceIndex); - String name = PortAudio.PaDeviceInfo_getName(deviceInfo); - - if (name != null) - name = name.trim(); - - int maxInputChannels - = PortAudio.PaDeviceInfo_getMaxInputChannels(deviceInfo); - int maxOutputChannels - = PortAudio.PaDeviceInfo_getMaxOutputChannels(deviceInfo); - - CaptureDeviceInfo cdi - = new CaptureDeviceInfo( - name, - new MediaLocator(LOCATOR_PROTOCOL + ":#" + deviceIndex), - new Format[] - { - new AudioFormat( - AudioFormat.LINEAR, - (maxInputChannels > 0) - ? getSupportedSampleRate( - true, - deviceIndex, - channels, - sampleFormat) - : PortAudio.DEFAULT_SAMPLE_RATE, - sampleSizeInBits, - channels, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED /* frameSizeInBits */, - Format.NOT_SPECIFIED /* frameRate */, - Format.byteArray) - }); - - if (maxInputChannels > 0) - { - if (deviceIndex == defaultInputDeviceIndex) - { - captureDevices.add(0, cdi); - if (logger.isDebugEnabled()) - logger.debug("Added default capture device: " + name); - } - else - { - captureDevices.add(cdi); - if (logger.isDebugEnabled()) - logger.debug("Added capture device: " + name); - } - } - if (maxOutputChannels > 0) - { - if (deviceIndex == defaultOutputDeviceIndex) - { - playbackDevices.add(0, cdi); - if (logger.isDebugEnabled()) - logger.debug("Added default playback device: " + name); - } - else - { - playbackDevices.add(cdi); - if (logger.isDebugEnabled()) - logger.debug("Added playback device: " + name); - } - } - } - - setCaptureDevices(captureDevices); - setPlaybackDevices(playbackDevices); - - if (devicesChangedCallback == null) - { - devicesChangedCallback - = new Runnable() - { - public void run() - { - try - { - PortAudio.Pa_UpdateAvailableDeviceList(); - initialize(); - } - catch (Throwable t) - { - if (t instanceof ThreadDeath) - throw (ThreadDeath) t; - - logger.warn( - "Failed to reinitialize PortAudio devices", - t); - } - } - }; - PortAudio.setDevicesChangedCallback(devicesChangedCallback); - } - } - - /** - * Gets a sample rate supported by a PortAudio device with a specific device - * index with which it is to be registered with JMF. - * - * @param input true if the supported sample rate is to be retrieved for - * the PortAudio device with the specified device index as an input device - * or false for an output device - * @param deviceIndex the device index of the PortAudio device for which a - * supported sample rate is to be retrieved - * @param channelCount number of channel - * @param sampleFormat sample format - * @return a sample rate supported by the PortAudio device with the - * specified device index with which it is to be registered with JMF - */ - private static double getSupportedSampleRate( - boolean input, - int deviceIndex, - int channelCount, - long sampleFormat) - { - long deviceInfo = PortAudio.Pa_GetDeviceInfo(deviceIndex); - double supportedSampleRate; - - if (deviceInfo != 0) - { - double defaultSampleRate - = PortAudio.PaDeviceInfo_getDefaultSampleRate(deviceInfo); - - if (defaultSampleRate >= MediaUtils.MAX_AUDIO_SAMPLE_RATE) - supportedSampleRate = defaultSampleRate; - else - { - long streamParameters - = PortAudio.PaStreamParameters_new( - deviceIndex, - channelCount, - sampleFormat, - PortAudio.LATENCY_UNSPECIFIED); - - if (streamParameters == 0) - supportedSampleRate = defaultSampleRate; - else - { - try - { - long inputParameters; - long outputParameters; - - if (input) - { - inputParameters = streamParameters; - outputParameters = 0; - } - else - { - inputParameters = 0; - outputParameters = streamParameters; - } - - boolean formatIsSupported - = PortAudio.Pa_IsFormatSupported( - inputParameters, - outputParameters, - PortAudio.DEFAULT_SAMPLE_RATE); - - supportedSampleRate - = formatIsSupported - ? PortAudio.DEFAULT_SAMPLE_RATE - : defaultSampleRate; - } - finally - { - PortAudio.PaStreamParameters_free(streamParameters); - } - } - } - } - else - supportedSampleRate = PortAudio.DEFAULT_SAMPLE_RATE; - return supportedSampleRate; - } - - @Override - public String toString() - { - return "PortAudio"; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/PulseAudioSystem.java b/src/net/java/sip/communicator/impl/neomedia/device/PulseAudioSystem.java deleted file mode 100644 index ac3b528af..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/PulseAudioSystem.java +++ /dev/null @@ -1,628 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import java.io.*; -import java.util.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.audio.*; -import net.java.sip.communicator.impl.neomedia.pulseaudio.*; -import net.java.sip.communicator.service.version.*; - -public class PulseAudioSystem - extends AudioSystem -{ - private static final String LOCATOR_PROTOCOL = LOCATOR_PROTOCOL_PULSEAUDIO; - - public static final String MEDIA_ROLE_EVENT = "event"; - - public static final String MEDIA_ROLE_PHONE = "phone"; - - private static final String NULL_DEV_CAPTURE_DEVICE_INFO_NAME = "Default"; - - public static void corkStream(long stream, boolean b) - throws IOException - { - if (stream == 0) - throw new IOException("stream"); - - long o = PA.stream_cork(stream, b, null); - - if (o == 0) - throw new IOException("pa_stream_cork"); - - PA.operation_unref(o); - } - - public static PulseAudioSystem getPulseAudioSystem() - { - AudioSystem audioSystem - = AudioSystem.getAudioSystem(PulseAudioSystem.LOCATOR_PROTOCOL); - - return - (audioSystem instanceof PulseAudioSystem) - ? (PulseAudioSystem) audioSystem - : null; - } - - private boolean createContext; - - private long context; - - private long mainloop; - - public PulseAudioSystem() - throws Exception - { - super(LOCATOR_PROTOCOL, FEATURE_NOTIFY_AND_PLAYBACK_DEVICES); - } - - private void createContext() - { - if (this.context != 0) - throw new IllegalStateException("context"); - - startMainloop(); - try - { - long proplist = PA.proplist_new(); - - if (proplist == 0) - throw new RuntimeException("pa_proplist_new"); - - try - { - populateContextProplist(proplist); - - long context - = PA.context_new_with_proplist( - PA.threaded_mainloop_get_api(mainloop), - null /* PA_PROP_APPLICATION_NAME */, - proplist); - - if (context == 0) - throw new RuntimeException("pa_context_new_with_proplist"); - - try - { - if (proplist != 0) - { - PA.proplist_free(proplist); - proplist = 0; - } - - Runnable stateCallback - = new Runnable() - { - public void run() - { - signalMainloop(false); - } - }; - - lockMainloop(); - try - { - PA.context_set_state_callback(context, stateCallback); - PA.context_connect( - context, - null, - PA.CONTEXT_NOFLAGS, - 0); - - try - { - int state - = waitForContextState( - context, - PA.CONTEXT_READY); - - if (state != PA.CONTEXT_READY) - throw new IllegalStateException( - "context.state"); - - this.context = context; - } - finally - { - if (this.context == 0) - PA.context_disconnect(context); - } - } - finally - { - unlockMainloop(); - } - } - finally - { - if (this.context == 0) - PA.context_unref(context); - } - } - finally - { - if (proplist != 0) - PA.proplist_free(proplist); - } - } - finally - { - if (this.context == 0) - stopMainloop(); - } - } - - @Override - public Renderer createRenderer(boolean playback) - { - MediaLocator locator; - - if (playback) - locator = null; - else - { - CaptureDeviceInfo notifyDevice = getNotifyDevice(); - - if (notifyDevice == null) - return null; - else - locator = notifyDevice.getLocator(); - } - - PulseAudioRenderer renderer - = new PulseAudioRenderer( - playback ? MEDIA_ROLE_PHONE : MEDIA_ROLE_EVENT); - - if ((renderer != null) && (locator != null)) - renderer.setLocator(locator); - - return renderer; - } - - public long createStream( - int sampleRate, - int channels, - String mediaName, - String mediaRole) - throws IllegalStateException, - RuntimeException - { - long context = getContext(); - - if (context == 0) - throw new IllegalStateException("context"); - - long sampleSpec - = PA.sample_spec_new(PA.SAMPLE_S16LE, sampleRate, channels); - - if (sampleSpec == 0) - throw new RuntimeException("pa_sample_spec_new"); - - long ret = 0; - - try - { - long proplist = PA.proplist_new(); - - if (proplist == 0) - throw new RuntimeException("pa_proplist_new"); - - try - { - PA.proplist_sets(proplist, PA.PROP_MEDIA_NAME, mediaRole); - PA.proplist_sets(proplist, PA.PROP_MEDIA_ROLE, mediaRole); - - long stream - = PA.stream_new_with_proplist( - context, - null, - sampleSpec, - 0, - proplist); - - if (stream == 0) - throw new RuntimeException( - "pa_stream_new_with_proplist"); - - try - { - ret = stream; - } - finally - { - if (ret == 0) - PA.stream_unref(stream); - } - } - finally - { - if (proplist != 0) - PA.proplist_free(proplist); - } - } - finally - { - if (sampleSpec != 0) - PA.sample_spec_free(sampleSpec); - } - - return ret; - } - - protected synchronized void doInitialize() - throws Exception - { - long context = getContext(); - - final List captureDevices - = new LinkedList(); - final List captureDeviceFormats = new LinkedList(); - PA.source_info_cb_t sourceInfoListCallback - = new PA.source_info_cb_t() - { - public void callback(long c, long i, int eol) - { - try - { - if ((eol == 0) && (i != 0)) - { - sourceInfoListCallback( - c, - i, - captureDevices, - captureDeviceFormats); - } - } - finally - { - signalMainloop(false); - } - } - }; - - final List playbackDevices - = new LinkedList(); - final List playbackDeviceFormats = new LinkedList(); - PA.sink_info_cb_t sinkInfoListCallback - = new PA.sink_info_cb_t() - { - public void callback(long c, long i, int eol) - { - try - { - if ((eol == 0) && (i != 0)) - { - sinkInfoListCallback( - c, - i, - playbackDevices, - playbackDeviceFormats); - } - } - finally - { - signalMainloop(false); - } - } - }; - - lockMainloop(); - try - { - long o - = PA.context_get_source_info_list( - context, - sourceInfoListCallback); - - if (o == 0) - throw new RuntimeException("pa_context_get_source_info_list"); - - try - { - while (PA.operation_get_state(o) == PA.OPERATION_RUNNING) - waitMainloop(); - } - finally - { - PA.operation_unref(o); - } - - o - = PA.context_get_sink_info_list( - context, - sinkInfoListCallback); - - if (o == 0) - throw new RuntimeException("pa_context_get_sink_info_list"); - - try - { - while (PA.operation_get_state(o) == PA.OPERATION_RUNNING) - waitMainloop(); - } - finally - { - PA.operation_unref(o); - } - } - finally - { - unlockMainloop(); - } - - if (!captureDeviceFormats.isEmpty()) - { - captureDevices.add( - 0, - new CaptureDeviceInfo( - NULL_DEV_CAPTURE_DEVICE_INFO_NAME, - new MediaLocator(LOCATOR_PROTOCOL + ":"), - captureDeviceFormats.toArray( - new Format[captureDeviceFormats.size()]))); - } - if (!playbackDevices.isEmpty()) - { - playbackDevices.add( - 0, - new CaptureDeviceInfo( - NULL_DEV_CAPTURE_DEVICE_INFO_NAME, - new MediaLocator(LOCATOR_PROTOCOL + ":"), - null)); - } - - setCaptureDevices(captureDevices); - setPlaybackDevices(playbackDevices); - } - - public synchronized long getContext() - { - if (context == 0) - { - if (!createContext) - { - createContext = true; - createContext(); - } - if (context == 0) - throw new IllegalStateException("context"); - } - return context; - } - - public void lockMainloop() - { - PA.threaded_mainloop_lock(mainloop); - } - - /** - * Populates a specific pa_proplist which is to be used with a - * pa_context with properties such as the application name and - * version. - * - * @param proplist the pa_proplist which is to be populated with - * pa_context-related properties such as the application name and - * version - */ - private void populateContextProplist(long proplist) - { - /* - * XXX For the sake of simplicity while working on libjitsi, get the - * version information in the form of System property values instead of - * going through the VersionService. - */ - String applicationName - = System.getProperty(Version.PNAME_APPLICATION_NAME); - - if (applicationName != null) - PA.proplist_sets( - proplist, - PA.PROP_APPLICATION_NAME, - applicationName); - - String applicationVersion - = System.getProperty(Version.PNAME_APPLICATION_VERSION); - - if (applicationVersion != null) - PA.proplist_sets( - proplist, - PA.PROP_APPLICATION_VERSION, - applicationVersion); - } - - public void signalMainloop(boolean waitForAccept) - { - PA.threaded_mainloop_signal(mainloop, waitForAccept); - } - - private void sinkInfoListCallback( - long context, - long sinkInfo, - List deviceList, - List formatList) - { - int sampleSpecFormat = PA.sink_info_get_sample_spec_format(sinkInfo); - - if (sampleSpecFormat != PA.SAMPLE_S16LE) - return; - - String description = PA.sink_info_get_description(sinkInfo); - String name = PA.sink_info_get_name(sinkInfo); - - if (description == null) - description = name; - deviceList.add( - new CaptureDeviceInfo( - description, - new MediaLocator( - LOCATOR_PROTOCOL - + ":" - + name), - null)); - } - - private void sourceInfoListCallback( - long context, - long sourceInfo, - List deviceList, - List formatList) - { - int monitorOfSink = PA.source_info_get_monitor_of_sink(sourceInfo); - - if (monitorOfSink != PA.INVALID_INDEX) - return; - - int sampleSpecFormat - = PA.source_info_get_sample_spec_format(sourceInfo); - - if (sampleSpecFormat != PA.SAMPLE_S16LE) - return; - - int channels = PA.source_info_get_sample_spec_channels(sourceInfo); - int rate = PA.source_info_get_sample_spec_rate(sourceInfo); - List sourceInfoFormatList = new LinkedList(); - - if ((MediaUtils.MAX_AUDIO_CHANNELS != Format.NOT_SPECIFIED) - && (MediaUtils.MAX_AUDIO_CHANNELS < channels)) - channels = MediaUtils.MAX_AUDIO_CHANNELS; - if ((MediaUtils.MAX_AUDIO_SAMPLE_RATE != Format.NOT_SPECIFIED) - && (MediaUtils.MAX_AUDIO_SAMPLE_RATE < rate)) - rate = (int) MediaUtils.MAX_AUDIO_SAMPLE_RATE; - - AudioFormat audioFormat - = new AudioFormat( - AudioFormat.LINEAR, - rate, - 16, - channels, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED /* frameSizeInBits */, - Format.NOT_SPECIFIED /* frameRate */, - Format.byteArray); - - if (!sourceInfoFormatList.contains(audioFormat)) - { - sourceInfoFormatList.add(audioFormat); - if (!formatList.contains(audioFormat)) - formatList.add(audioFormat); - } - if (!formatList.isEmpty()) - { - String description = PA.source_info_get_description(sourceInfo); - String name = PA.source_info_get_name(sourceInfo); - - if (description == null) - description = name; - deviceList.add( - new CaptureDeviceInfo( - description, - new MediaLocator( - LOCATOR_PROTOCOL - + ":" - + name), - sourceInfoFormatList.toArray( - new Format[sourceInfoFormatList.size()]))); - } - } - - private void startMainloop() - { - if (this.mainloop != 0) - throw new IllegalStateException("mainloop"); - - long mainloop = PA.threaded_mainloop_new(); - - if (mainloop == 0) - throw new RuntimeException("pa_threaded_mainloop_new"); - - try - { - if (PA.threaded_mainloop_start(mainloop) < 0) - throw new RuntimeException("pa_threaded_mainloop_start"); - - this.mainloop = mainloop; - } - finally - { - if (this.mainloop == 0) - PA.threaded_mainloop_free(mainloop); - } - } - - private void stopMainloop() - { - if (this.mainloop == 0) - throw new IllegalStateException("mainloop"); - - long mainloop = this.mainloop; - - this.mainloop = 0; - PA.threaded_mainloop_stop(mainloop); - PA.threaded_mainloop_free(mainloop); - } - - @Override - public String toString() - { - return "PulseAudio"; - } - - public void unlockMainloop() - { - PA.threaded_mainloop_unlock(mainloop); - } - - private int waitForContextState( - long context, - int stateToWaitFor) - { - int state; - - while (true) - { - state = PA.context_get_state(context); - if ((PA.CONTEXT_FAILED == state) - || (stateToWaitFor == state) - || (PA.CONTEXT_TERMINATED == state)) - break; - - waitMainloop(); - } - - return state; - } - - public int waitForStreamState( - long stream, - int stateToWaitFor) - { - int state; - - while (true) - { - state = PA.stream_get_state(stream); - if ((stateToWaitFor == state) - || (PA.STREAM_FAILED == state) - || (PA.STREAM_TERMINATED == state)) - break; - - waitMainloop(); - } - - return state; - } - - public void waitMainloop() - { - PA.threaded_mainloop_wait(mainloop); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/QuickTimeSystem.java b/src/net/java/sip/communicator/impl/neomedia/device/QuickTimeSystem.java deleted file mode 100644 index 6df89f6d7..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/QuickTimeSystem.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.codec.video.*; -import net.java.sip.communicator.impl.neomedia.quicktime.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.util.*; - -/** - * Discovers and registers QuickTime/QTKit capture devices with JMF. - * - * @author Lyubomir Marinov - */ -public class QuickTimeSystem - extends DeviceSystem -{ - - /** - * The Logger used by the QuickTimeSystem class and its - * instances for logging output. - */ - private static final Logger logger = Logger.getLogger(QuickTimeSystem.class); - - /** - * The protocol of the MediaLocators identifying QuickTime/QTKit - * capture devices. - */ - private static final String LOCATOR_PROTOCOL = LOCATOR_PROTOCOL_QUICKTIME; - - /** - * Initializes a new QuickTimeSystem instance which discovers and - * registers QuickTime/QTKit capture devices with JMF. - * - * @throws Exception if anything goes wrong while discovering and - * registering QuickTime/QTKit capture defines with JMF - */ - public QuickTimeSystem() - throws Exception - { - super(MediaType.VIDEO, LOCATOR_PROTOCOL); - } - - protected void doInitialize() - throws Exception - { - QTCaptureDevice[] inputDevices - = QTCaptureDevice.inputDevicesWithMediaType(QTMediaType.Video); - boolean captureDeviceInfoIsAdded = false; - - for (QTCaptureDevice inputDevice : inputDevices) - { - CaptureDeviceInfo device - = new CaptureDeviceInfo( - inputDevice.localizedDisplayName(), - new MediaLocator( - LOCATOR_PROTOCOL - + ':' - + inputDevice.uniqueID()), - new Format[] - { - new AVFrameFormat(FFmpeg.PIX_FMT_ARGB), - new RGBFormat() - }); - - if(logger.isInfoEnabled()) - { - for(QTFormatDescription f : inputDevice.formatDescriptions()) - { - logger.info( - "Webcam available resolution for " - + inputDevice.localizedDisplayName() - + ":" - + f.sizeForKey( - QTFormatDescription - .VideoEncodedPixelsSizeAttribute)); - } - } - - CaptureDeviceManager.addDevice(device); - captureDeviceInfoIsAdded = true; - if (logger.isDebugEnabled()) - logger.debug("Added CaptureDeviceInfo " + device); - } - if (captureDeviceInfoIsAdded - && !MediaServiceImpl.isJmfRegistryDisableLoad()) - CaptureDeviceManager.commit(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/ReceiveStreamPushBufferDataSource.java b/src/net/java/sip/communicator/impl/neomedia/device/ReceiveStreamPushBufferDataSource.java deleted file mode 100644 index 4bb895801..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/ReceiveStreamPushBufferDataSource.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import javax.media.protocol.*; -import javax.media.rtp.*; - -import net.java.sip.communicator.impl.neomedia.protocol.*; - -/** - * Wraps the DataSource of a specific ReceiveStream so that - * calls to its {@link DataSource#disconnect()} can be explicitly controlled. It - * is introduced because it seems that after the DataSource of a - * ReceiveStream is disconnected, it cannot be connected to or started - * and if a Processor is created on it, it freezes in the - * {@link javax.media.Processor#Configuring} state. - * - * @author Lubomir Marinov - */ -public class ReceiveStreamPushBufferDataSource - extends PushBufferDataSourceDelegate -{ - - /** - * The ReceiveStream which has its DataSource wrapped by - * this instance. Currently, remembered just to be made available to callers - * in case they need it and not used by this instance. - */ - private final ReceiveStream receiveStream; - - /** - * The indicator which determines whether {@link DataSource#disconnect()} is - * to be called on the wrapped DataSource when it is called on this - * instance. - */ - private boolean suppressDisconnect; - - /** - * Initializes a new ReceiveStreamPushBufferDataSource instance - * which is to wrap a specific DataSource of a specific - * ReceiveStream for the purposes of enabling explicity control of - * calls to its {@link DataSource#disconnect()}. - * - * @param receiveStream the ReceiveStream which is to have its - * DataSource - * @param dataSource the DataSource of receiveStream which - * is to be wrapped by this instance - */ - public ReceiveStreamPushBufferDataSource( - ReceiveStream receiveStream, - PushBufferDataSource dataSource) - { - super(dataSource); - - this.receiveStream = receiveStream; - } - - /** - * Initializes a new ReceiveStreamPushBufferDataSource instance - * which is to wrap a specific DataSource of a specific - * ReceiveStream for the purposes of enabling explicity control of - * calls to its {@link DataSource#disconnect()} and, optionally, activates - * the suppresses the call in question. - * - * @param receiveStream the ReceiveStream which is to have its - * DataSource - * @param dataSource the DataSource of receiveStream which - * is to be wrapped by this instance - * @param suppressDisconnect true if calls to - * DataSource#disconnect() on the wrapped dataSource are - * to be suppressed when there are such calls on the new instance; - * otherwise, false - */ - public ReceiveStreamPushBufferDataSource( - ReceiveStream receiveStream, - PushBufferDataSource dataSource, - boolean suppressDisconnect) - { - this(receiveStream, dataSource); - - setSuppressDisconnect(suppressDisconnect); - } - - /** - * Implements {@link DataSource#disconnect()}. Disconnects the wrapped - * DataSource if it has not been explicitly suppressed by setting - * the suppressDisconnect property of this instance. - */ - @Override - public void disconnect() - { - if (!suppressDisconnect) - super.disconnect(); - } - - /** - * Gets the ReceiveStream which has its DataSource wrapped - * by this instance. - * - * @return the ReceiveStream which has its DataSource - * wrapped by this instance - */ - public ReceiveStream getReceiveStream() - { - return receiveStream; - } - - /** - * Implements {@link PushBufferDataSource#getStreams()}. Delegates to the - * wrapped DataSource of the ReceiveStream. - * - * @return an array of the PushBufferStreams of the wrapped - * DataSource of the ReceiveStream - */ - public PushBufferStream[] getStreams() - { - return dataSource.getStreams(); - } - - /** - * Sets the indicator which determines whether calls to - * {@link DataSource#disconnect()} on the wrapped DataSource are to - * be suppressed when there are such calls on this instance. - * - * @param suppressDisconnect true to suppress calls to - * DataSource#disconnect() on the wrapped DataSource when - * there are such calls on this instance; otherwise, false - */ - public void setSuppressDisconnect(boolean suppressDisconnect) - { - this.suppressDisconnect = suppressDisconnect; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/ScreenDeviceImpl.java b/src/net/java/sip/communicator/impl/neomedia/device/ScreenDeviceImpl.java deleted file mode 100644 index 01220a6ba..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/ScreenDeviceImpl.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import java.awt.*; - -import net.java.sip.communicator.service.neomedia.device.*; - -/** - * Implementation of ScreenDevice. - * - * @author Sebastien Vincent - * @author Lyubomir Marinov - */ -public class ScreenDeviceImpl implements ScreenDevice -{ - private static final ScreenDevice[] EMPTY_SCREEN_DEVICE_ARRAY - = new ScreenDevice[0]; - - /** - * AWT GraphicsDevice. - */ - final GraphicsDevice screen; - - /** - * Screen index. - */ - private final int index; - - /** - * Returns all available ScreenDevice instances. - * - * @return array of ScreenDevice instances - */ - public static ScreenDevice[] getAvailableScreenDevices() - { - GraphicsEnvironment ge; - - try - { - ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); - } - catch(NoClassDefFoundError ncdfe) - { - ge = null; - } - - ScreenDevice[] screens = null; - - /* - * Make sure the GraphicsEnvironment is not headless in order to avoid a - * HeadlessException. - */ - if ((ge != null) && !ge.isHeadlessInstance()) - { - GraphicsDevice[] devices = ge.getScreenDevices(); - - if ((devices != null) && (devices.length != 0)) - { - screens = new ScreenDevice[devices.length]; - - int i = 0; - - for (GraphicsDevice dev : devices) - { - // We know that GraphicsDevice type is TYPE_RASTER_SCREEN. - screens[i] = new ScreenDeviceImpl(i, dev); - i++; - } - } - } - - return (screens == null) ? EMPTY_SCREEN_DEVICE_ARRAY : screens; - } - - public static ScreenDevice getDefaultScreenDevice() - { - ScreenDevice[] screens = getAvailableScreenDevices(); - int width = 0; - int height = 0; - ScreenDevice best = null; - - for (ScreenDevice screen : screens) - { - java.awt.Dimension res = screen.getSize(); - - if ((res != null) && ((width < res.width) || (height < res.height))) - { - width = res.width; - height = res.height; - best = screen; - } - } - return best; - } - - /** - * Constructor. - * - * @param index screen index - * @param screen screen device - */ - protected ScreenDeviceImpl(int index, GraphicsDevice screen) - { - this.index = index; - this.screen = screen; - } - - /** - * Get the screen index. - * - * @return screen index - */ - public int getIndex() - { - return index; - } - - /** - * Get current resolution of ScreenDevice device. - * - * @return current resolution of the screen - */ - public Dimension getSize() - { - /* get current display resolution */ - DisplayMode mode = screen.getDisplayMode(); - - return - (mode == null) - ? null - : new Dimension(mode.getWidth(), mode.getHeight()); - } - - /** - * Get the identifier of the screen. - * - * @return ID of the screen - */ - public String getName() - { - return screen.getIDstring(); - } - - /** - * If the screen contains specified point. - * - * @param p point coordinate - * @return true if point belongs to screen, false otherwise - */ - public boolean containsPoint(Point p) - { - return screen.getDefaultConfiguration().getBounds().contains(p); - } - - /** - * Get bounds of the screen. - * - * @return bounds of the screen - */ - public Rectangle getBounds() - { - return screen.getDefaultConfiguration().getBounds(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/Video4Linux2System.java b/src/net/java/sip/communicator/impl/neomedia/device/Video4Linux2System.java deleted file mode 100644 index 436ff19ae..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/Video4Linux2System.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import javax.media.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.codec.video.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.video4linux2.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.util.*; - -/** - * Discovers and registers CaptureDevices which implement the Video for - * Linux Two API Specification with JMF. - * - * @author Lyubomir Marinov - */ -public class Video4Linux2System - extends DeviceSystem -{ - /** - * The Logger used by the Video4Linux2System class and its - * instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(Video4Linux2System.class); - - /** - * The protocol of the MediaLocators identifying - * CaptureDevice which implement the Video for Linux Two API - * Specification. - */ - private static final String LOCATOR_PROTOCOL - = LOCATOR_PROTOCOL_VIDEO4LINUX2; - - /** - * Initializes a new Video4Linux2System instance which discovers and - * registers CaptureDevices which implement the Video for Linux Two - * API Specification with JMF. - * - * @throws Exception if anything goes wrong while discovering and - * registering CaptureDevices which implement the Video for Linux - * Two API Specification with JMF - */ - public Video4Linux2System() - throws Exception - { - super(MediaType.VIDEO, LOCATOR_PROTOCOL); - } - - /** - * Discovers and registers a CaptureDevice implementing the Video - * for Linux Two API Specification with a specific device name with JMF. - * - * @param deviceName the device name of a candidate for a - * CaptureDevice implementing the Video for Linux Two API - * Specification to be discovered and registered with JMF - * @return true if a CaptureDeviceInfo for the specified - * CaptureDevice has been added to CaptureDeviceManager; - * otherwise, false - * @throws Exception if anything goes wrong while discovering and - * registering the specified CaptureDevice with JMF - */ - private boolean discoverAndRegister(String deviceName) - throws Exception - { - int fd = Video4Linux2.open(deviceName, Video4Linux2.O_RDWR); - boolean captureDeviceInfoIsAdded = false; - - if (-1 != fd) - { - try - { - long v4l2_capability = Video4Linux2.v4l2_capability_alloc(); - - if (0 != v4l2_capability) - { - try - { - if ((Video4Linux2.ioctl( - fd, - Video4Linux2.VIDIOC_QUERYCAP, - v4l2_capability) - != -1) - && ((Video4Linux2 - .v4l2_capability_getCapabilities( - v4l2_capability) - & Video4Linux2.V4L2_CAP_VIDEO_CAPTURE) - == Video4Linux2.V4L2_CAP_VIDEO_CAPTURE)) - { - captureDeviceInfoIsAdded - = register(deviceName, fd, v4l2_capability); - } - } - finally - { - Video4Linux2.free(v4l2_capability); - } - } - } - finally - { - Video4Linux2.close(fd); - } - } - return captureDeviceInfoIsAdded; - } - - protected void doInitialize() - throws Exception - { - String baseDeviceName = "/dev/video"; - boolean captureDeviceInfoIsAdded = discoverAndRegister(baseDeviceName); - - for (int deviceMinorNumber = 0; - deviceMinorNumber <= 63; - deviceMinorNumber++) - { - captureDeviceInfoIsAdded - = discoverAndRegister(baseDeviceName + deviceMinorNumber) - || captureDeviceInfoIsAdded; - } - if (captureDeviceInfoIsAdded - && !MediaServiceImpl.isJmfRegistryDisableLoad()) - CaptureDeviceManager.commit(); - } - - /** - * Registers a CaptureDevice implementing the Video for Linux Two - * API Specification with a specific device name, a specific open() - * file descriptor and a specific v4l2_capability with JMF. - * - * @param deviceName name of the device (i.e. /dev/videoX) - * @param fd file descriptor of the device - * @param v4l2_capability device V4L2 capability - * @return true if a CaptureDeviceInfo for the specified - * CaptureDevice has been added to CaptureDeviceManager; - * otherwise, false - * @throws Exception if anything goes wrong while registering the specified - * CaptureDevice with JMF - */ - private boolean register(String deviceName, int fd, long v4l2_capability) - throws Exception - { - long v4l2_format - = Video4Linux2.v4l2_format_alloc( - Video4Linux2.V4L2_BUF_TYPE_VIDEO_CAPTURE); - int pixelformat = 0; - String supportedRes = null; - - if (0 != v4l2_format) - { - try - { - if (Video4Linux2.ioctl( - fd, - Video4Linux2.VIDIOC_G_FMT, - v4l2_format) - != -1) - { - long fmtPix - = Video4Linux2.v4l2_format_getFmtPix(v4l2_format); - - pixelformat - = Video4Linux2.v4l2_pix_format_getPixelformat(fmtPix); - - if (FFmpeg.PIX_FMT_NONE - == DataSource.getFFmpegPixFmt(pixelformat)) - { - Video4Linux2.v4l2_pix_format_setPixelformat( - fmtPix, - Video4Linux2.V4L2_PIX_FMT_RGB24); - if (Video4Linux2.ioctl( - fd, - Video4Linux2.VIDIOC_S_FMT, - v4l2_format) - != -1) - { - pixelformat - = Video4Linux2.v4l2_pix_format_getPixelformat( - fmtPix); - } - } - - if(logger.isInfoEnabled()) - { - supportedRes = - Video4Linux2.v4l2_pix_format_getWidth(fmtPix) - + "x" - + Video4Linux2.v4l2_pix_format_getHeight(fmtPix); - } - } - } - finally - { - Video4Linux2.free(v4l2_format); - } - } - - Format format; - int ffmpegPixFmt = DataSource.getFFmpegPixFmt(pixelformat); - - if (FFmpeg.PIX_FMT_NONE != ffmpegPixFmt) - format = new AVFrameFormat(ffmpegPixFmt, pixelformat); - else - return false; - - String name = Video4Linux2.v4l2_capability_getCard(v4l2_capability); - - if ((name == null) || (name.length() == 0)) - name = deviceName; - else - name += " (" + deviceName + ")"; - - if(logger.isInfoEnabled() && supportedRes != null) - { - logger.info("Webcam available resolution for " + name - + ":" + supportedRes); - } - - CaptureDeviceManager.addDevice( - new CaptureDeviceInfo( - name, - new MediaLocator(LOCATOR_PROTOCOL + ":" + deviceName), - new Format[] { format })); - return true; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java b/src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java deleted file mode 100644 index 74368f274..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java +++ /dev/null @@ -1,1836 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import java.awt.*; -import java.awt.event.*; -import java.io.*; -import java.util.*; -import java.util.List; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; -import javax.media.protocol.*; -import javax.swing.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.codec.video.*; -import net.java.sip.communicator.impl.neomedia.codec.video.h264.*; -import net.java.sip.communicator.impl.neomedia.format.*; -import net.java.sip.communicator.impl.neomedia.transform.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.control.*; -import net.java.sip.communicator.service.neomedia.control.KeyFrameControl; // disambiguation -import net.java.sip.communicator.service.neomedia.format.*; -import net.java.sip.communicator.service.resources.*; -import net.java.sip.communicator.util.*; -import net.java.sip.communicator.util.event.*; - -/** - * Extends MediaDeviceSession to add video-specific functionality. - * - * @author Lyubomir Marinov - * @author Sebastien Vincent - */ -public class VideoMediaDeviceSession - extends MediaDeviceSession -{ - /** - * The Logger used by the VideoMediaDeviceSession class - * and its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(VideoMediaDeviceSession.class); - - /** - * The image ID of the icon which is to be displayed as the local visual - * Component depicting the streaming of the desktop of the local - * peer to the remote peer. - */ - private static final String DESKTOP_STREAMING_ICON - = "impl.media.DESKTOP_STREAMING_ICON"; - - /** - * The KeyFrameControl used by thisVideoMediaDeviceSession - * as a means to control its key frame-related logic. - */ - private KeyFrameControl keyFrameControl; - - /** - * The KeyFrameRequester implemented by this - * VideoMediaDeviceSession and provided to - * {@link #keyFrameControl}. - */ - private KeyFrameControl.KeyFrameRequester keyFrameRequester; - - /** - * The Player which provides the local visual/video - * Component. - */ - private Player localPlayer; - - /** - * The Object which synchronizes the access to - * {@link #localPlayer}. - */ - private final Object localPlayerSyncRoot = new Object(); - - /** - * Local SSRC. - */ - private long localSSRC = -1; - - /** - * Output size of the stream. - * - * It is used to specify a different size (generally lesser ones) - * than the capture device provides. Typically one usage can be - * in desktop streaming/sharing session when sender desktop is bigger - * than remote ones. - */ - private Dimension outputSize; - - /** - * The SwScaler inserted into the codec chain of the - * Player rendering the media received from the remote peer and - * enabling the explicit setting of the video size. - */ - private SwScaler playerScaler; - - /** - * Remote SSRC. - */ - private long remoteSSRC = -1; - - /** - * The RTPConnector with which the RTPManager of this - * instance is to be or is already initialized. - */ - private AbstractRTPConnector rtpConnector; - - /** - * Use or not RTCP feedback Picture Loss Indication. - */ - private boolean usePLI = false; - - /** - * The facility which aids this instance in managing a list of - * VideoListeners and firing VideoEvents to them. - */ - private final VideoNotifierSupport videoNotifierSupport - = new VideoNotifierSupport(this, false); - - /** - * Tells to flip the local video display (true, in case of diplaying the - * webcam as a mirror), or not (false, for desktop streaming). - */ - private boolean flipLocalVideoDisplay = true; - - /** - * Initializes a new VideoMediaDeviceSession instance which is to - * represent the work of a MediaStream with a specific video - * MediaDevice. - * - * @param device the video MediaDevice the use of which by a - * MediaStream is to be represented by the new instance - */ - public VideoMediaDeviceSession(AbstractMediaDevice device) - { - super(device); - } - - /** - * Adds a specific VideoListener to this instance in order to - * receive notifications when visual/video Components are being - * added and removed. - *

- * Adding a listener which has already been added does nothing i.e. it is - * not added more than once and thus does not receive one and the same - * VideoEvent multiple times. - *

- * - * @param listener the VideoListener to be notified when - * visual/video Components are being added or removed in this - * instance - */ - public void addVideoListener(VideoListener listener) - { - videoNotifierSupport.addVideoListener(listener); - } - - /** - * Creates the DataSource that this instance is to read captured - * media from. - * - * @return the DataSource that this instance is to read captured - * media from - */ - @Override - protected DataSource createCaptureDevice() - { - /* - * Create our DataSource as SourceCloneable so we can use it to both - * display local video and stream to remote peer. - */ - DataSource captureDevice = super.createCaptureDevice(); - - if (captureDevice != null) - { - MediaLocator locator = captureDevice.getLocator(); - String protocol = (locator == null) ? null : locator.getProtocol(); - float frameRate; - DeviceConfiguration deviceConfig - = NeomediaActivator - .getMediaServiceImpl() - .getDeviceConfiguration(); - - // Apply the video size and the frame rate configured by the user. - if (DeviceSystem.LOCATOR_PROTOCOL_IMGSTREAMING.equals(protocol)) - { - /* - * It is not clear at this time what the default frame rate for - * desktop streaming should be. - */ - frameRate = 10; - } - else - { - Dimension videoSize = deviceConfig.getVideoSize(); - - // if we have an output size that is smaller than our current - // settings, respect that size - if(outputSize != null - && videoSize.height > outputSize.height - && videoSize.width > outputSize.width) - videoSize = outputSize; - - Dimension dim = VideoMediaStreamImpl.selectVideoSize( - captureDevice, - videoSize.width, videoSize.height); - - frameRate = deviceConfig.getFrameRate(); - - // print initial video resolution, when starting video - if(logger.isInfoEnabled() && dim != null) - logger.info("video send resolution: " - + dim.width + "x" + dim.height); - } - - FrameRateControl frameRateControl - = (FrameRateControl) - captureDevice.getControl(FrameRateControl.class.getName()); - - if (frameRateControl != null) - { - float maxSupportedFrameRate - = frameRateControl.getMaxSupportedFrameRate(); - - if ((maxSupportedFrameRate > 0) - && (frameRate > maxSupportedFrameRate)) - frameRate = maxSupportedFrameRate; - if(frameRate > 0) - frameRateControl.setFrameRate(frameRate); - - // print initial video frame rate, when starting video - if(logger.isInfoEnabled()) - { - logger.info("video send FPS: " + (frameRate == -1 ? - "default(no restriction)" : frameRate)); - } - } - - if (!(captureDevice instanceof SourceCloneable)) - { - DataSource cloneableDataSource - = Manager.createCloneableDataSource(captureDevice); - - if (cloneableDataSource != null) - captureDevice = cloneableDataSource; - } - } - return captureDevice; - } - - /** - * Asserts that a specific MediaDevice is acceptable to be set as - * the MediaDevice of this instance. Makes sure that its - * MediaType is {@link MediaType#VIDEO}. - * - * @param device the MediaDevice to be checked for suitability to - * become the MediaDevice of this instance - * @see MediaDeviceSession#checkDevice(AbstractMediaDevice) - */ - @Override - protected void checkDevice(AbstractMediaDevice device) - { - if (!MediaType.VIDEO.equals(device.getMediaType())) - throw new IllegalArgumentException("device"); - } - - /** - * Releases the resources allocated by a specific Player in the - * course of its execution and prepares it to be garbage collected. If the - * specified Player is rendering video, notifies the - * VideoListeners of this instance that its visual - * Component is to no longer be used by firing a - * {@link VideoEvent#VIDEO_REMOVED} VideoEvent. - * - * @param player the Player to dispose of - * @see MediaDeviceSession#disposePlayer(Player) - */ - @Override - protected void disposePlayer(Player player) - { - /* - * The player is being disposed so let the (interested) listeners know - * its Player#getVisualComponent() (if any) should be released. - */ - Component visualComponent = getVisualComponent(player); - - super.disposePlayer(player); - - if (visualComponent != null) - { - fireVideoEvent( - VideoEvent.VIDEO_REMOVED, visualComponent, VideoEvent.REMOTE, - false); - } - } - - /** - * Notifies the VideoListeners registered with this instance about - * a specific type of change in the availability of a specific visual - * Component depicting video. - * - * @param type the type of change as defined by VideoEvent in the - * availability of the specified visual Component depicting video - * @param visualComponent the visual Component depicting video - * which has been added or removed in this instance - * @param origin {@link VideoEvent#LOCAL} if the origin of the video is - * local (e.g. it is being locally captured); {@link VideoEvent#REMOTE} if - * the origin of the video is remote (e.g. a remote peer is streaming it) - * @param wait true if the call is to wait till the specified - * VideoEvent has been delivered to the VideoListeners; - * otherwise, false - * @return true if this event and, more specifically, the visual - * Component it describes have been consumed and should be - * considered owned, referenced (which is important because - * Components belong to a single Container at a time); - * otherwise, false - */ - protected boolean fireVideoEvent( - int type, Component visualComponent, int origin, - boolean wait) - { - if (logger.isTraceEnabled()) - { - logger.trace( - "Firing VideoEvent with type " - + VideoEvent.typeToString(type) - + " and origin " - + VideoEvent.originToString(origin)); - } - - return - videoNotifierSupport.fireVideoEvent( - type, visualComponent, origin, - wait); - } - - /** - * Notifies the VideoListeners registered with this instance about - * a specific VideoEvent. - * - * @param videoEvent the VideoEvent to be fired to the - * VideoListeners registered with this instance - * @param wait true if the call is to wait till the specified - * VideoEvent has been delivered to the VideoListeners; - * otherwise, false - */ - protected void fireVideoEvent(VideoEvent videoEvent, boolean wait) - { - videoNotifierSupport.fireVideoEvent(videoEvent, wait); - } - - /** - * Gets the JMF Format of the captureDevice of this - * MediaDeviceSession. - * - * @return the JMF Format of the captureDevice of this - * MediaDeviceSession - */ - private Format getCaptureDeviceFormat() - { - DataSource captureDevice = getCaptureDevice(); - - if (captureDevice != null) - { - FormatControl[] formatControls = null; - - if (captureDevice instanceof CaptureDevice) - { - formatControls - = ((CaptureDevice) captureDevice).getFormatControls(); - } - if ((formatControls == null) || (formatControls.length == 0)) - { - FormatControl formatControl - = (FormatControl) - captureDevice.getControl(FormatControl.class.getName()); - - if (formatControl != null) - formatControls = new FormatControl[] { formatControl }; - } - if (formatControls != null) - { - for (FormatControl formatControl : formatControls) - { - Format format = formatControl.getFormat(); - - if (format != null) - return format; - } - } - } - return null; - } - - /** - * Initializes a new Player instance which is to provide the local - * visual/video Component. The new instance is initialized to - * render the media of the captureDevice of this - * MediaDeviceSession. - * - * @return a new Player instance which is to provide the local - * visual/video Component - */ - private Player createLocalPlayer() - { - return createLocalPlayer(getCaptureDevice()); - } - - /** - * Initializes a new Player instance which is to provide the local - * visual/video Component. The new instance is initialized to - * render the media of a specific DataSource. - * - * @param captureDevice the DataSource which is to have its media - * rendered by the new instance as the local visual/video Component - * @return a new Player instance which is to provide the local - * visual/video Component - */ - protected Player createLocalPlayer(DataSource captureDevice) - { - DataSource dataSource - = (captureDevice instanceof SourceCloneable) - ? ((SourceCloneable) captureDevice).createClone() - : null; - Processor localPlayer = null; - - if (dataSource != null) - { - Exception exception = null; - - try - { - localPlayer = Manager.createProcessor(dataSource); - } - catch (Exception ex) - { - exception = ex; - } - - if (exception == null) - { - if (localPlayer != null) - { - localPlayer.addControllerListener( - new ControllerListener() - { - public void controllerUpdate(ControllerEvent event) - { - controllerUpdateForCreateLocalVisualComponent( - event); - } - }); - localPlayer.configure(); - } - } - else - { - logger.error( - "Failed to connect to " - + MediaStreamImpl.toString(dataSource), - exception); - } - } - - return localPlayer; - } - - /** - * Gets notified about ControllerEvents generated by - * {@link #localPlayer}. - * - * @param controllerEvent the ControllerEvent specifying the - * Controller which is the source of the event and the very type of - * the event - */ - private void controllerUpdateForCreateLocalVisualComponent( - ControllerEvent controllerEvent) - { - if (controllerEvent instanceof ConfigureCompleteEvent) - { - Processor player - = (Processor) controllerEvent.getSourceController(); - - /* - * Use SwScaler for the scaling since it produces an image with - * better quality and add the "flip" effect to the video. - */ - TrackControl[] trackControls = player.getTrackControls(); - - if ((trackControls != null) && (trackControls.length != 0)) - try - { - for (TrackControl trackControl : trackControls) - { - // If the local video is a desktop sharing stream, then - // we do not need to flip the video. - if (!this.flipLocalVideoDisplay) - { - trackControl.setCodecChain( - new Codec[]{new SwScaler()}); - } - // else the local video is a webcam stream, then - // we need to flip the video in order to display it like - // a mirror. - else - { - trackControl.setCodecChain( - new Codec[]{new HFlip(), new SwScaler()}); - } - break; - } - } - catch (UnsupportedPlugInException upiex) - { - logger.warn( - "Failed to add SwScaler/VideoFlipEffect to " + - "codec chain", upiex); - } - - // Turn the Processor into a Player. - try - { - player.setContentDescriptor(null); - } - catch (NotConfiguredError nce) - { - logger.error( - "Failed to set ContentDescriptor of Processor", - nce); - } - - player.realize(); - } - else if (controllerEvent instanceof RealizeCompleteEvent) - { - Player player = (Player) controllerEvent.getSourceController(); - Component visualComponent = player.getVisualComponent(); - boolean start; - - if (visualComponent == null) - start = false; - else - { - start - = fireVideoEvent( - VideoEvent.VIDEO_ADDED, - visualComponent, - VideoEvent.LOCAL, - true); - } - if (start) - player.start(); - else - { - // No listener is interested in our event so free the resources. - synchronized (localPlayerSyncRoot) - { - if (localPlayer == player) - localPlayer = null; - } - - player.stop(); - player.deallocate(); - player.close(); - } - } - } - - /** - * Creates the visual Component depicting the video being streamed - * from the local peer to the remote peer. - * - * @param flipLocalVideoDisplay Tells to flip the local video display (true, - * in case of diplaying the webcam as a mirror), or not (false, for desktop - * streaming). - * - * @return the visual Component depicting the video being streamed - * from the local peer to the remote peer if it was immediately created or - * null if it was not immediately created and it is to be delivered - * to the currently registered VideoListeners in a - * VideoEvent with type {@link VideoEvent#VIDEO_ADDED} and origin - * {@link VideoEvent#LOCAL} - */ - public Component createLocalVisualComponent(boolean flipLocalVideoDisplay) - { - this.flipLocalVideoDisplay = flipLocalVideoDisplay; - - /* - * Displaying the currently streamed desktop is perceived as unnecessary - * because the user sees the whole desktop anyway. Instead, a static - * image will be presented. - */ - DataSource captureDevice = getCaptureDevice(); - - if (captureDevice != null) - { - MediaLocator locator = captureDevice.getLocator(); - - if ((locator != null) - && DeviceSystem.LOCATOR_PROTOCOL_IMGSTREAMING.equals( - locator.getProtocol())) - return createLocalVisualComponentForDesktopStreaming(); - } - - /* - * The visual Component to depict the video being streamed from the - * local peer to the remote peer is created by JMF and its Player so it - * is likely to take noticeably long time. Consequently, we will deliver - * it to the currently registered VideoListeners in a VideoEvent after - * returning from the call. - */ - Component localVisualComponent; - - synchronized (localPlayerSyncRoot) - { - if (localPlayer == null) - localPlayer = createLocalPlayer(); - localVisualComponent - = (localPlayer == null) - ? null - : getVisualComponent(localPlayer); - } - /* - * If the local visual/video Component exists at this time, it has - * likely been created by a previous call to this method. However, the - * caller may still depend on a VIDEO_ADDED event being fired for it. - */ - if (localVisualComponent != null) - fireVideoEvent( - VideoEvent.VIDEO_ADDED, - localVisualComponent, - VideoEvent.LOCAL, - false); - return localVisualComponent; - } - - /** - * Creates the visual Component to depict the streaming of the - * desktop of the local peer to the remote peer. - * - * @return the visual Component to depict the streaming of the - * desktop of the local peer to the remote peer - */ - private Component createLocalVisualComponentForDesktopStreaming() - { - ResourceManagementService resources = NeomediaActivator.getResources(); - ImageIcon icon - = (resources == null) - ? null - : resources.getImage(DESKTOP_STREAMING_ICON); - Canvas canvas; - - if (icon == null) - canvas = null; - else - { - final Image img = icon.getImage(); - - canvas = new Canvas() - { - public static final long serialVersionUID = 0L; - - @Override - public void paint(Graphics g) - { - int width = getWidth(); - int height = getHeight(); - - g.setColor(Color.BLACK); - g.fillRect(0, 0, width, height); - - int imgWidth = img.getWidth(this); - int imgHeight = img.getHeight(this); - - if ((imgWidth < 1) || (imgHeight < 1)) - return; - - boolean scale = false; - float scaleFactor = 1; - - if (imgWidth > width) - { - scale = true; - scaleFactor = width / (float) imgWidth; - } - if (imgHeight > height) - { - scale = true; - scaleFactor - = Math.min(scaleFactor, height / (float) imgHeight); - } - - int dstWidth; - int dstHeight; - - if (scale) - { - dstWidth = Math.round(imgWidth * scaleFactor); - dstHeight = Math.round(imgHeight * scaleFactor); - } - else - { - dstWidth = imgWidth; - dstHeight = imgHeight; - } - - int dstX = (width - dstWidth) / 2; - int dstY = (height - dstWidth) / 2; - - g.drawImage( - img, - dstX, dstY, dstX + dstWidth, dstY + dstHeight, - 0, 0, imgWidth, imgHeight, - this); - } - }; - - Dimension iconSize - = new Dimension(icon.getIconWidth(), icon.getIconHeight()); - - canvas.setMaximumSize(iconSize); - canvas.setPreferredSize(iconSize); - - /* - * Set a clue so that we can recognize it if it gets received as an - * argument to #disposeLocalVisualComponent(). - */ - canvas.setName(DESKTOP_STREAMING_ICON); - - fireVideoEvent( - VideoEvent.VIDEO_ADDED, canvas, VideoEvent.LOCAL, - false); - } - return canvas; - } - - /** - * Disposes of the local visual Component of the local peer. - * - * @param component the local visual Component of the local peer to - * dispose of - */ - public void disposeLocalVisualComponent(Component component) - { - if (component != null) - { - /* - * Desktop streaming does not use a Player but a Canvas with its - * name equal to the value of DESKTOP_STREAMING_ICON. - */ - if (DESKTOP_STREAMING_ICON.equals(component.getName())) - { - fireVideoEvent( - VideoEvent.VIDEO_REMOVED, component, VideoEvent.LOCAL, - false); - } - else - { - Player localPlayer; - - synchronized (localPlayerSyncRoot) - { - localPlayer = this.localPlayer; - } - if (localPlayer != null) - { - Component localPlayerVisualComponent - = getVisualComponent(localPlayer); - - if ((localPlayerVisualComponent == null) - || (localPlayerVisualComponent == component)) - disposeLocalPlayer(localPlayer); - } - } - } - } - - /** - * Releases the resources allocated by a specific local Player in - * the course of its execution and prepares it to be garbage collected. If - * the specified Player is rendering video, notifies the - * VideoListeners of this instance that its visual - * Component is to no longer be used by firing a - * {@link VideoEvent#VIDEO_REMOVED} VideoEvent. - * - * @param player the Player to dispose of - * @see MediaDeviceSession#disposePlayer(Player) - */ - private void disposeLocalPlayer(Player player) - { - /* - * The player is being disposed so let the (interested) listeners know - * its Player#getVisualComponent() (if any) should be released. - */ - Component visualComponent = null; - - try - { - visualComponent = getVisualComponent(player); - - player.stop(); - player.deallocate(); - player.close(); - } - finally - { - synchronized (localPlayerSyncRoot) - { - if (localPlayer == player) - localPlayer = null; - } - - if (visualComponent != null) - fireVideoEvent( - VideoEvent.VIDEO_REMOVED, visualComponent, VideoEvent.LOCAL, - false); - } - } - - /** - * Gets the visual Components where video from the remote peer is - * being rendered. - * - * @return the visual Components where video from the remote peer - * is being rendered - */ - public List getVisualComponents() - { - List visualComponents = new LinkedList(); - - /* - * When we know (through means such as SDP) that we don't want to - * receive, it doesn't make sense to wait for the remote peer to - * acknowledge our desire. So we'll just stop depicting the video of the - * remote peer regardless of whether it stops or continues its sending. - */ - if (getStartedDirection().allowsReceiving()) - { - for (Player player : getPlayers()) - { - Component visualComponent = getVisualComponent(player); - - if (visualComponent != null) - visualComponents.add(visualComponent); - } - } - return visualComponents; - } - - /** - * Gets the visual Components rendering the ReceiveStream - * corresponding to the given ssrc. - * - * @param ssrc the src-id of the receive stream, which visual - * Component we're looking for - * @return the visual Component rendering the - * ReceiveStream corresponding to the given ssrc - */ - public Component getVisualComponent(long ssrc) - { - Player player = getPlayer(ssrc); - - if (player != null) - return player.getVisualComponent(); - - return null; - } - - /** - * Gets the visual Component of a specific Player if it - * has one and ignores the failure to access it if the specified - * Player is unrealized. - * - * @param player the Player to get the visual Component of - * if it has one - * @return the visual Component of the specified Player if - * it has one; null if the specified Player does not have - * a visual Component or the Player is unrealized - */ - private static Component getVisualComponent(Player player) - { - Component visualComponent = null; - - if (player.getState() >= Player.Realized) - { - try - { - visualComponent = player.getVisualComponent(); - } - catch (NotRealizedError nre) - { - if (logger.isDebugEnabled()) - logger.debug( - "Called Player#getVisualComponent() " - + "on unrealized player " - + player, - nre); - } - } - return visualComponent; - } - - /** - * Notifies this instance that a specific Player of remote content - * has generated a ConfigureCompleteEvent. - * - * @param player the Player which is the source of a - * ConfigureCompleteEvent - * @see MediaDeviceSession#playerConfigureComplete(Processor) - */ - @Override - protected void playerConfigureComplete(final Processor player) - { - super.playerConfigureComplete(player); - - TrackControl[] trackControls = player.getTrackControls(); - SwScaler playerScaler = null; - - if ((trackControls != null) && (trackControls.length != 0)) - { - try - { - for (TrackControl trackControl : trackControls) - { - /* - * Since SwScaler will scale any input size into the - * configured output size, we may never get SizeChangeEvent - * from the player. We'll generate it ourselves then. - */ - playerScaler = new PlayerScaler(player); - - /* - * For H.264, we will use RTCP feedback. For example, to - * tell the sender that we've missed a frame. - */ - if ("h264/rtp".equalsIgnoreCase( - getFormat().getJMFEncoding())) - { - final DePacketizer depacketizer = new DePacketizer(); - JNIDecoder decoder = new JNIDecoder(); - - if (keyFrameControl != null) - { - depacketizer.setKeyFrameControl(keyFrameControl); - decoder.setKeyFrameControl( - new KeyFrameControlAdapter() - { - @Override - public boolean requestKeyFrame( - boolean urgent) - { - return - depacketizer.requestKeyFrame( - urgent); - } - }); - } - - trackControl.setCodecChain( - new Codec[] - { - depacketizer, - decoder, - playerScaler - }); - } - else - { - trackControl.setCodecChain( - new Codec[] { playerScaler }); - } - break; - } - } - catch (UnsupportedPlugInException upiex) - { - logger.error( - "Failed to add SwScaler or H.264 DePacketizer to codec" - + " chain", - upiex); - playerScaler = null; - } - } - this.playerScaler = playerScaler; - } - - /** - * Gets notified about ControllerEvents generated by a specific - * Player of remote content. - * - * @param event the ControllerEvent specifying the - * Controller which is the source of the event and the very type of - * the event - * @see MediaDeviceSession#playerControllerUpdate(ControllerEvent) - */ - @Override - protected void playerControllerUpdate(ControllerEvent event) - { - super.playerControllerUpdate(event); - - /* - * If SwScaler is in the chain and it forces a specific size of the - * output, the SizeChangeEvents of the Player do not really notify about - * changes in the size of the input. Besides, playerScaler will take - * care of the events in such a case. - */ - if ((event instanceof SizeChangeEvent) - && ((playerScaler == null) - || (playerScaler.getOutputSize() == null))) - { - SizeChangeEvent sizeChangeEvent = (SizeChangeEvent) event; - - playerSizeChange( - sizeChangeEvent.getSourceController(), - sizeChangeEvent.getWidth(), - sizeChangeEvent.getHeight()); - } - } - - /** - * Notifies this instance that a specific Player of remote content - * has generated a RealizeCompleteEvent. - * - * @param player the Player which is the source of a - * RealizeCompleteEvent. - * @see MediaDeviceSession#playerRealizeComplete(Processor) - */ - @Override - protected void playerRealizeComplete(final Processor player) - { - super.playerRealizeComplete(player); - - Component visualComponent = getVisualComponent(player); - - if (visualComponent != null) - { - /* - * SwScaler seems to be very good at scaling with respect to image - * quality so use it for the scaling in the player replacing the - * scaling it does upon rendering. - */ - visualComponent.addComponentListener(new ComponentAdapter() - { - @Override - public void componentResized(ComponentEvent e) - { - playerVisualComponentResized(player, e); - } - }); - - fireVideoEvent( - VideoEvent.VIDEO_ADDED, visualComponent, VideoEvent.REMOTE, - false); - } - } - - /** - * Notifies this instance that a specific Player of remote content - * has generated a SizeChangeEvent. - * - * @param sourceController the Player which is the source of the - * event - * @param width the width reported in the event - * @param height the height reported in the event - * @see SizeChangeEvent - */ - protected void playerSizeChange( - final Controller sourceController, - final int width, - final int height) - { - /* - * Invoking anything that is likely to change the UI in the Player - * thread seems like a performance hit so bring it into the event - * thread. - */ - if (!SwingUtilities.isEventDispatchThread()) - { - SwingUtilities.invokeLater(new Runnable() - { - public void run() - { - playerSizeChange(sourceController, width, height); - } - }); - return; - } - - Player player = (Player) sourceController; - Component visualComponent = getVisualComponent(player); - - if (visualComponent != null) - { - fireVideoEvent( - new SizeChangeVideoEvent( - this, - visualComponent, - SizeChangeVideoEvent.REMOTE, - width, - height), - false); - } - } - - /** - * Notifies this instance that the visual Component of a - * Player rendering remote content has been resized. - * - * @param player the Player rendering remote content the visual - * Component of which has been resized - * @param e a ComponentEvent which specifies the resized - * Component - */ - private void playerVisualComponentResized( - Processor player, - ComponentEvent e) - { - if (playerScaler == null) - return; - - Component visualComponent = e.getComponent(); - - /* - * When the visualComponent is not in an UI hierarchy, its size isn't - * expected to be representative of what the user is seeing. - */ - if (visualComponent.getParent() == null) - return; - - Dimension outputSize = visualComponent.getSize(); - float outputWidth = outputSize.width; - float outputHeight = outputSize.height; - - if ((outputWidth < 1) || (outputHeight < 1)) - return; - - /* - * The size of the output video will be calculated so that it fits into - * the visualComponent and the video aspect ratio is preserved. The - * presumption here is that the inputFormat holds the video size with - * the correct aspect ratio. - */ - Format inputFormat = playerScaler.getInputFormat(); - - if (inputFormat == null) - return; - - Dimension inputSize = ((VideoFormat) inputFormat).getSize(); - - if (inputSize == null) - return; - - int inputWidth = inputSize.width; - int inputHeight = inputSize.height; - - if ((inputWidth < 1) || (inputHeight < 1)) - return; - - // Preserve the aspect ratio. - outputHeight = outputWidth * inputHeight / (float) inputWidth; - - // Fit the output video into the visualComponent. - boolean scale = false; - float widthRatio; - float heightRatio; - - if (Math.abs(outputWidth - inputWidth) < 1) - { - scale = true; - widthRatio = outputWidth / (float) inputWidth; - } - else - widthRatio = 1; - if (Math.abs(outputHeight - inputHeight) < 1) - { - scale = true; - heightRatio = outputHeight / (float) inputHeight; - } - else - heightRatio = 1; - if (scale) - { - float scaleFactor = Math.min(widthRatio, heightRatio); - - outputWidth = inputWidth * scaleFactor; - outputHeight = inputHeight * scaleFactor; - } - - outputSize.width = (int) outputWidth; - outputSize.height = (int) outputHeight; - - Dimension playerScalerOutputSize = playerScaler.getOutputSize(); - - if (playerScalerOutputSize == null) - playerScaler.setOutputSize(outputSize); - else - { - /* - * If we are not going to make much of a change, do not even bother - * because any scaling in the Renderer will not be noticeable - * anyway. - */ - int outputWidthDelta - = outputSize.width - playerScalerOutputSize.width; - int outputHeightDelta - = outputSize.height - playerScalerOutputSize.height; - - if ((outputWidthDelta < -1) - || (outputWidthDelta > 1) - || (outputHeightDelta < -1) - || (outputHeightDelta > 1)) - { - playerScaler.setOutputSize(outputSize); - } - } - } - - /** - * Removes a specific VideoListener from this instance in order to - * have to no longer receive notifications when visual/video - * Components are being added and removed. - * - * @param listener the VideoListener to no longer be notified when - * visual/video Components are being added or removed in this - * instance - */ - public void removeVideoListener(VideoListener listener) - { - videoNotifierSupport.removeVideoListener(listener); - } - - /** - * Use or not RTCP feedback Picture Loss Indication. - * - * @param usePLI true to use PLI; otherwise, false - */ - public void setRtcpFeedbackPLI(boolean usePLI) - { - if (this.usePLI != usePLI) - { - this.usePLI = usePLI; - - if (this.usePLI) - { - if (keyFrameRequester == null) - { - keyFrameRequester - = new KeyFrameControl.KeyFrameRequester() - { - public boolean requestKeyFrame() - { - boolean requested = false; - - if (VideoMediaDeviceSession.this.usePLI) - { - try - { - new RTCPFeedbackPacket( - 1, - 206, - localSSRC, - remoteSSRC) - .writeTo( - rtpConnector - .getControlOutputStream()); - requested = true; - } - catch (IOException ioe) - { - /* - * Apart from logging the ioe, there are - * not a lot of ways to handle it. - */ - } - } - return requested; - } - }; - } - if (keyFrameControl != null) - keyFrameControl.addKeyFrameRequester(-1, keyFrameRequester); - } - else if (keyFrameRequester != null) - { - if (keyFrameControl != null) - keyFrameControl.removeKeyFrameRequester(keyFrameRequester); - keyFrameRequester = null; - } - } - } - - /** - * Sets the size of the output video. - * - * @param size the size of the output video - */ - public void setOutputSize(Dimension size) - { - if((size != null && outputSize == null) - || (size == null && outputSize != null) - || (size != null && outputSize != null && !outputSize.equals(size))) - outputsizeChanged = true; - - outputSize = size; - } - - /** - * Sets the RTPConnector that will be used to - * initialize some codec for RTCP feedback. - * - * @param rtpConnector the RTP connector - */ - public void setConnector(AbstractRTPConnector rtpConnector) - { - this.rtpConnector = rtpConnector; - } - - /** - * Sets the KeyFrameControl to be used by this - * VideoMediaDeviceSession as a means of control over its - * key frame-related logic. - * - * @param keyFrameControl the KeyFrameControl to be used by this - * VideoMediaDeviceSession as a means of control over its - * key frame-related logic - */ - public void setKeyFrameControl(KeyFrameControl keyFrameControl) - { - if (this.keyFrameControl != keyFrameControl) - { - if ((this.keyFrameControl != null) && (keyFrameRequester != null)) - this.keyFrameControl.removeKeyFrameRequester(keyFrameRequester); - - this.keyFrameControl = keyFrameControl; - - if ((this.keyFrameControl != null) && (keyFrameRequester != null)) - this.keyFrameControl.addKeyFrameRequester(-1, keyFrameRequester); - } - } - - /** - * Set the local SSRC. - * - * @param localSSRC local SSRC - */ - public void setLocalSSRC(long localSSRC) - { - this.localSSRC = localSSRC; - } - - /** - * Set the remote SSRC. - * - * @param remoteSSRC remote SSRC - */ - public void setRemoteSSRC(long remoteSSRC) - { - this.remoteSSRC = remoteSSRC; - } - - /** - * Sets the MediaFormatImpl in which a specific Processor - * producing media to be streamed to the remote peer is to output. - * - * @param processor the Processor to set the output - * MediaFormatImpl of - * @param mediaFormat the MediaFormatImpl to set on - * processor - * @see MediaDeviceSession#setProcessorFormat(Processor, MediaFormatImpl) - */ - @Override - protected void setProcessorFormat( - Processor processor, - MediaFormatImpl mediaFormat) - { - Format format = mediaFormat.getFormat(); - - if ("h263-1998/rtp".equalsIgnoreCase(format.getEncoding())) - { - /* - * If no output size has been defined, then no SDP fmtp has been - * found with QCIF, CIF, VGA or CUSTOM parameters. Let's default to - * QCIF (176x144). - */ - if (outputSize == null) - outputSize = new Dimension(176, 144); - } - - /* - * Add a size in the output format. As VideoFormat has no setter, we - * recreate the object. Also check whether capture device can output - * such a size. - */ - if ((outputSize != null) - && (outputSize.width > 0) - && (outputSize.height > 0)) - { - Dimension deviceSize - = ((VideoFormat) getCaptureDeviceFormat()).getSize(); - - if ((deviceSize != null) - && ((deviceSize.width > outputSize.width) - || (deviceSize.height > outputSize.height))) - { - VideoFormat videoFormat = (VideoFormat) format; - - format - = new VideoFormat( - videoFormat.getEncoding(), - outputSize, - videoFormat.getMaxDataLength(), - videoFormat.getDataType(), - videoFormat.getFrameRate()); - } - else - { - VideoFormat videoFormat = (VideoFormat) format; - - format - = new VideoFormat( - videoFormat.getEncoding(), - deviceSize, - videoFormat.getMaxDataLength(), - videoFormat.getDataType(), - videoFormat.getFrameRate()); - - outputSize = null; - } - } - else - outputSize = null; - - super.setProcessorFormat(processor, mediaFormat); - } - - /** - * Sets the MediaFormatImpl of a specific TrackControl of - * the Processor which produces the media to be streamed by this - * MediaDeviceSession to the remote peer. Allows extenders to - * override the set procedure and to detect when the JMF Format of - * the specified TrackControl changes. - * - * @param trackControl the TrackControl to set the JMF - * Format of - * @param mediaFormat the MediaFormatImpl to be set on the - * specified TrackControl. Though mediaFormat encapsulates - * a JMF Format, format is to be set on the specified - * trackControl because it may be more specific. In any case, the - * two JMF Formats match. The MediaFormatImpl is provided - * anyway because it carries additional information such as format - * parameters. - * @param format the JMF Format to be set on the specified - * TrackControl. Though mediaFormat encapsulates a JMF - * Format, the specified format is to be set on the - * specified trackControl because it may be more specific than the - * JMF Format of the mediaFormat - * @return the JMF Format set on TrackControl after the - * attempt to set the specified mediaFormat or null if the - * specified format was found to be incompatible with - * trackControl - * @see MediaDeviceSession#setProcessorFormat(TrackControl, MediaFormatImpl, - * Format) - */ - @Override - protected Format setProcessorFormat( - TrackControl trackControl, - MediaFormatImpl mediaFormat, - Format format) - { - JNIEncoder encoder = null; - SwScaler scaler = null; - int codecCount = 0; - - /* - * For H.264 we will monitor RTCP feedback. For example, if we receive a - * PLI/FIR message, we will send a keyframe. - */ - if ("h264/rtp".equalsIgnoreCase(format.getEncoding())) - { - encoder = new JNIEncoder(); - - // packetization-mode - { - Map formatParameters - = mediaFormat.getFormatParameters(); - String packetizationMode - = (formatParameters == null) - ? null - : formatParameters.get( - JNIEncoder.PACKETIZATION_MODE_FMTP); - - encoder.setPacketizationMode(packetizationMode); - } - - // additional codec settings - { - Map settings = - mediaFormat.getAdditionalCodecSettings(); - - encoder.setAdditionalCodecSettings(settings); - } - - if (usePLI) - { - /* - * The H.264 encoder needs to be notified of RTCP feedback - * messages. - */ - try - { - ((ControlTransformInputStream) - rtpConnector.getControlInputStream()) - .addRTCPFeedbackListener(encoder); - } - catch (IOException ioe) - { - logger.error("Error cannot get RTCP input stream", ioe); - } - } - if (keyFrameControl != null) - encoder.setKeyFrameControl(keyFrameControl); - - codecCount++; - } - - if (outputSize != null) - { - /* We have been explicitly told to use a specified output size so - * create a custom SwScaler that will scale and convert color spaces - * in one call. - */ - scaler = new SwScaler(); - scaler.setOutputSize(outputSize); - codecCount++; - } - - Codec[] codecs = new Codec[codecCount]; - - codecCount = 0; - if(scaler != null) - codecs[codecCount++] = scaler; - if(encoder != null) - codecs[codecCount++] = encoder; - - if (codecCount != 0) - { - /* Add our custom SwScaler and possibly RTCP aware codec to the - * codec chain so that it will be used instead of default. - */ - try - { - trackControl.setCodecChain(codecs); - } - catch(UnsupportedPlugInException upiex) - { - logger.error( - "Failed to add SwScaler/JNIEncoder to codec chain", - upiex); - } - } - - return super.setProcessorFormat(trackControl, mediaFormat, format); - } - - /** - * Sets the MediaFormat in which this MediaDeviceSession - * outputs the media captured by its MediaDevice. - * - * @param format the MediaFormat in which this - * MediaDeviceSession is to output the media captured by its - * MediaDevice - */ - public void setFormat(MediaFormat format) - { - if(format instanceof VideoMediaFormat && - ((VideoMediaFormat)format).getFrameRate() != -1) - { - FrameRateControl frameRateControl - = (FrameRateControl) - getCaptureDevice().getControl(FrameRateControl.class.getName()); - - if (frameRateControl != null) - { - float frameRate = ((VideoMediaFormat)format).getFrameRate(); - - float maxSupportedFrameRate - = frameRateControl.getMaxSupportedFrameRate(); - - if ((maxSupportedFrameRate > 0) - && (frameRate > maxSupportedFrameRate)) - frameRate = maxSupportedFrameRate; - if(frameRate > 0) - { - frameRateControl.setFrameRate(frameRate); - - if(logger.isInfoEnabled()) - { - logger.info("video send FPS: " + frameRate); - } - } - } - } - - super.setFormat(format); - } - - /** - * Notifies this instance that the value of its startedDirection - * property has changed from a specific oldValue to a specific - * newValue. - * - * @param oldValue the MediaDirection which used to be the value of - * the startedDirection property of this instance - * @param newValue the MediaDirection which is the value of the - * startedDirection property of this instance - */ - @Override - protected void startedDirectionChanged( - MediaDirection oldValue, - MediaDirection newValue) - { - super.startedDirectionChanged(oldValue, newValue); - - for (Player player : getPlayers()) - { - int state = player.getState(); - - /* - * The visual Component of a Player is safe to access and, - * respectively, report through a VideoEvent only when the Player is - * Realized. - */ - if (state < Player.Realized) - continue; - - if (newValue.allowsReceiving()) - { - if (state != Player.Started) - { - player.start(); - - Component visualComponent = getVisualComponent(player); - - if (visualComponent != null) - { - fireVideoEvent( - VideoEvent.VIDEO_ADDED, - visualComponent, - VideoEvent.REMOTE, - false); - } - } - } - else if (state > Processor.Configured) - { - Component visualComponent = getVisualComponent(player); - - player.stop(); - - if (visualComponent != null) - { - fireVideoEvent( - VideoEvent.VIDEO_REMOVED, - visualComponent, - VideoEvent.REMOTE, - false); - } - } - } - } - - /** - * Extends SwScaler in order to provide scaling with high quality - * to a specific Player of remote video. - */ - private class PlayerScaler - extends SwScaler - { - /** - * The last size reported in the form of a SizeChangeEvent. - */ - private Dimension lastSize; - - /** - * The Player into the codec chain of which this - * SwScaler is set. - */ - private final Player player; - - /** - * Initializes a new PlayerScaler instance which is to provide - * scaling with high quality to a specific Player of remote - * video. - * - * @param player the Player of remote video into the codec - * chain of which the new instance is to be set - */ - public PlayerScaler(Player player) - { - super(true); - - this.player = player; - } - - /** - * Determines when the input video sizes changes and reports it as a - * SizeChangeVideoEvent because Player is unable to - * do it when this SwScaler is scaling to a specific - * outputSize. - * - * @param input input buffer - * @param output output buffer - * @return the native PaSampleFormat - * @see SwScaler#process(Buffer, Buffer) - */ - @Override - public int process(Buffer input, Buffer output) - { - int result = super.process(input, output); - - if (result == BUFFER_PROCESSED_OK) - { - Format inputFormat = getInputFormat(); - - if (inputFormat != null) - { - Dimension size = ((VideoFormat) inputFormat).getSize(); - - if ((size != null) - && ((lastSize == null) || !lastSize.equals(size))) - { - lastSize = size; - playerSizeChange( - player, - lastSize.width, lastSize.height); - } - } - } - return result; - } - - /** - * Ensures that this SwScaler preserves the aspect ratio of its - * input video when scaling. - * - * @param inputFormat format to set - * @return format - * @see SwScaler#setInputFormat(Format) - */ - @Override - public Format setInputFormat(Format inputFormat) - { - inputFormat = super.setInputFormat(inputFormat); - if (inputFormat instanceof VideoFormat) - { - Dimension inputSize = ((VideoFormat) inputFormat).getSize(); - - if ((inputSize != null) && (inputSize.width > 0)) - { - Dimension outputSize = getOutputSize(); - - if ((outputSize != null) && (outputSize.width > 0)) - { - int outputHeight - = (int) - (outputSize.width - * inputSize.height - / (float) inputSize.width); - int outputHeightDelta - = outputHeight - outputSize.height; - - if ((outputHeightDelta < -1) || (outputHeightDelta > 1)) - { - outputSize.height = outputHeight; - setOutputSize(outputSize); - } - } - } - } - return inputFormat; - } - } - - /** - * Returns the format of the video we are receiving from the remote peer. - * - * @return The video format of the received video. Null, if no video is - * received. - */ - public VideoFormat getReceivedVideoFormat() - { - if(this.playerScaler != null) - { - Format format = this.playerScaler.getInputFormat(); - - if (format instanceof VideoFormat) - { - return ((VideoFormat) format); - } - } - - return null; - } - - /** - * Returns the format of the video we are streaming to the remote peer. - * - * @return The video format of the sent video. Null, if no video is sent. - */ - public VideoFormat getSentVideoFormat() - { - DataSource capture = this.getCaptureDevice(); - if(capture instanceof PullBufferDataSource) - { - PullBufferStream[] streams = - ((PullBufferDataSource) capture).getStreams(); - for(int i = 0; i < streams.length; ++i) - { - VideoFormat format = (VideoFormat) streams[i].getFormat(); - if(format != null) - { - return format; - } - } - } - return null; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/VideoTranslatorMediaDevice.java b/src/net/java/sip/communicator/impl/neomedia/device/VideoTranslatorMediaDevice.java deleted file mode 100644 index 06d62939e..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/device/VideoTranslatorMediaDevice.java +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.device; - -import java.util.*; - -import javax.media.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.format.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.format.*; - -/** - * Implements a MediaDevice which is to be used in video conferencing - * implemented with an RTP translator. - * - * @author Lyubomir Marinov - */ -public class VideoTranslatorMediaDevice - extends AbstractMediaDevice - implements MediaDeviceWrapper -{ - /** - * The MediaDevice which this instance enables to be used in a - * video conference implemented with an RTP translator. - */ - private final MediaDeviceImpl device; - - /** - * The MediaDeviceSession of {@link #device} the - * outputDataSource of which is the captureDevice of - * {@link #streamDeviceSessions}. - */ - private MediaDeviceSession deviceSession; - - /** - * The MediaStreamMediaDeviceSessions sharing the - * outputDataSource of {@link #device} as their - * captureDevice. - */ - private final List streamDeviceSessions - = new LinkedList(); - - /** - * Initializes a new VideoTranslatorMediaDevice which enables a - * specific MediaDevice to be used in video conferencing - * implemented with an RTP translator. - * - * @param device the MediaDevice which the new instance is to - * enable to be used in video conferencing implemented with an RTP - * translator - */ - public VideoTranslatorMediaDevice(MediaDeviceImpl device) - { - this.device = device; - } - - /** - * Releases the resources allocated by this instance in the course of its - * execution and prepares it to be garbage collected when all - * {@link #streamDeviceSessions} have been closed. - * - * @param streamDeviceSession the MediaStreamMediaDeviceSession - * which has been closed - */ - private synchronized void close( - MediaStreamMediaDeviceSession streamDeviceSession) - { - streamDeviceSessions.remove(streamDeviceSession); - if (streamDeviceSessions.isEmpty()) - { - if(deviceSession != null) - deviceSession.close(); - deviceSession = null; - } - else - updateDeviceSessionStartedDirection(); - } - - /** - * Creates a DataSource instance for this MediaDevice - * which gives access to the captured media. - * - * @return a DataSource instance which gives access to the media - * captured by this MediaDevice - * @see AbstractMediaDevice#createOutputDataSource() - */ - synchronized DataSource createOutputDataSource() - { - if (deviceSession == null) - { - MediaFormatImpl format = null; - MediaDirection startedDirection = MediaDirection.INACTIVE; - - for (MediaStreamMediaDeviceSession streamDeviceSession - : streamDeviceSessions) - { - MediaFormatImpl streamFormat - = streamDeviceSession.getFormat(); - - if ((streamFormat != null) && (format == null)) - format = streamFormat; - startedDirection - = startedDirection.or( - streamDeviceSession.getStartedDirection()); - } - - deviceSession = device.createSession(); - if (format != null) - deviceSession.setFormat(format); - deviceSession.start(startedDirection); - } - return - (deviceSession == null) - ? null - : deviceSession.getOutputDataSource(); - } - - /** - * Initializes a new Renderer instance which is to play back media - * on this MediaDevice. - * - * @return a new Renderer instance which is to play back media on - * this MediaDevice or null if a suitable - * Renderer is to be chosen irrespective of this - * MediaDevice - */ - Renderer createRenderer() - { - return null; - } - - /** - * Creates a new MediaDeviceSession instance which is to represent - * the use of this MediaDevice by a MediaStream. - * - * @return a new MediaDeviceSession instance which is to represent - * the use of this MediaDevice by a MediaStream - * @see AbstractMediaDevice#createSession() - */ - @Override - public synchronized MediaDeviceSession createSession() - { - MediaStreamMediaDeviceSession streamDeviceSession - = new MediaStreamMediaDeviceSession(); - - streamDeviceSessions.add(streamDeviceSession); - return streamDeviceSession; - } - - /** - * Returns the MediaDirection supported by this device. - * - * @return MediaDirection.SENDONLY if this is a read-only device, - * MediaDirection.RECVONLY if this is a write-only device and - * MediaDirection.SENDRECV if this MediaDevice can both - * capture and render media - * @see MediaDevice#getDirection() - */ - public MediaDirection getDirection() - { - return device.getDirection(); - } - - /** - * Returns the MediaFormat that this device is currently set to use - * when capturing data. - * - * @return the MediaFormat that this device is currently set to - * provide media in. - * @see MediaDevice#getFormat() - */ - public MediaFormat getFormat() - { - return device.getFormat(); - } - - /** - * Returns the MediaType that this device supports. - * - * @return MediaType.AUDIO if this is an audio device or - * MediaType.VIDEO in case of a video device - * @see MediaDevice#getMediaType() - */ - public MediaType getMediaType() - { - return device.getMediaType(); - } - - /** - * Returns a list of MediaFormat instances representing the media - * formats supported by this MediaDevice. - * - * @param localPreset the preset used to set the send format parameters, - * used for video and settings - * @param remotePreset the preset used to set the receive format parameters, - * used for video and settings - * @return the list of MediaFormats supported by this device - * @see MediaDevice#getSupportedFormats(QualityPreset, QualityPreset) - */ - public List getSupportedFormats( - QualityPreset localPreset, - QualityPreset remotePreset) - { - return device.getSupportedFormats(localPreset, remotePreset); - } - - /** - * Gets the actual MediaDevice which this MediaDevice is - * effectively built on top of and forwarding to. - * - * @return the actual MediaDevice which this MediaDevice - * is effectively built on top of and forwarding to - * @see MediaDeviceWrapper#getWrappedDevice() - */ - public MediaDevice getWrappedDevice() - { - return device; - } - - /** - * Updates the value of the startedDirection property of - * {@link #deviceSession} to be in accord with the values of the property - * of {@link #streamDeviceSessions}. - */ - private synchronized void updateDeviceSessionStartedDirection() - { - if (deviceSession == null) - return; - - MediaDirection startDirection = MediaDirection.INACTIVE; - - for (MediaStreamMediaDeviceSession streamDeviceSession - : streamDeviceSessions) - { - startDirection - = startDirection.or(streamDeviceSession.getStartedDirection()); - } - deviceSession.start(startDirection); - - MediaDirection stopDirection = MediaDirection.INACTIVE; - - if (!startDirection.allowsReceiving()) - stopDirection = stopDirection.or(MediaDirection.RECVONLY); - if (!startDirection.allowsSending()) - stopDirection = stopDirection.or(MediaDirection.SENDONLY); - deviceSession.stop(stopDirection); - } - - /** - * Represents the use of this VideoTranslatorMediaDevice by a - * MediaStream. - */ - private class MediaStreamMediaDeviceSession - extends VideoMediaDeviceSession - { - /** - * Initializes a new MediaStreamMediaDeviceSession which is to - * represent the use of this VideoTranslatorMediaDevice by a - * MediaStream. - */ - public MediaStreamMediaDeviceSession() - { - super(VideoTranslatorMediaDevice.this); - } - - /** - * Releases the resources allocated by this instance in the course of - * its execution and prepares it to be garbage collected. - */ - @Override - public void close() - { - super.close(); - - VideoTranslatorMediaDevice.this.close(this); - } - - /** - * Creates the DataSource that this instance is to read - * captured media from. - * - * @return the DataSource that this instance is to read - * captured media from - * @see VideoMediaDeviceSession#createCaptureDevice() - */ - @Override - protected DataSource createCaptureDevice() - { - return VideoTranslatorMediaDevice.this.createOutputDataSource(); - } - - /** - * Initializes a new Player instance which is to provide the - * local visual/video Component. The new instance is - * initialized to render the media of a specific DataSource. - * - * @param captureDevice the DataSource which is to have its - * media rendered by the new instance as the local visual/video - * Component - * @return a new Player instance which is to provide the local - * visual/video Component - */ - @Override - protected Player createLocalPlayer(DataSource captureDevice) - { - synchronized (VideoTranslatorMediaDevice.this) - { - if (deviceSession != null) - captureDevice = deviceSession.getCaptureDevice(); - } - - return super.createLocalPlayer(captureDevice); - } - - /** - * Initializes a new FMJ Processor which is to transcode - * {@link #captureDevice} into the format of this instance. - * - * @return a new FMJ Processor which is to transcode - * captureDevice into the format of this instance - */ - @Override - protected Processor createProcessor() - { - return null; - } - - /** - * Gets the output DataSource of this instance which provides - * the captured (RTP) data to be sent by MediaStream to - * MediaStreamTarget. - * - * @return the output DataSource of this instance which - * provides the captured (RTP) data to be sent by MediaStream - * to MediaStreamTarget - * @see MediaDeviceSession#getOutputDataSource() - */ - @Override - public DataSource getOutputDataSource() - { - return getConnectedCaptureDevice(); - } - - /** - * Notifies this instance that the value of its - * startedDirection property has changed from a specific - * oldValue to a specific newValue. - * - * @param oldValue the MediaDirection which used to be the - * value of the startedDirection property of this instance - * @param newValue the MediaDirection which is the value of the - * startedDirection property of this instance - */ - @Override - protected void startedDirectionChanged( - MediaDirection oldValue, - MediaDirection newValue) - { - super.startedDirectionChanged(oldValue, newValue); - - VideoTranslatorMediaDevice.this - .updateDeviceSessionStartedDirection(); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/directshow/DSCaptureDevice.java b/src/net/java/sip/communicator/impl/neomedia/directshow/DSCaptureDevice.java deleted file mode 100644 index 49e28f039..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/directshow/DSCaptureDevice.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.directshow; - -/** - * DirectShow capture device. - * - * @author Sebastien Vincent - */ -public class DSCaptureDevice -{ - /** - * Empty array with DSFormat element type. Explicitly defined - * in order to avoid unnecessary allocations. - */ - private static final DSFormat EMPTY_FORMATS[] = new DSFormat[0]; - - /** - * Native pointer of DSCaptureDevice. - * - * This pointer is hold and will be released by DSManager - * singleton. - */ - private long ptr = 0; - - /** - * Constructor. - * - * @param ptr native pointer - */ - public DSCaptureDevice(long ptr) - { - /* do not allow 0 pointer value */ - if(ptr == 0) - throw new IllegalArgumentException("invalid ptr value (0)"); - - this.ptr = ptr; - } - - /** - * Open and initialize the capture device. - */ - public void open() - { - open(ptr); - } - - /** - * Stop and close the capture device. - */ - public void close() - { - close(ptr); - } - - /** - * Get name of the capture device. - * - * @return name of the capture device - */ - public String getName() - { - return getName(ptr).trim(); - } - - /** - * Set format to use with this capture device. - * - * @param format format to set - */ - public void setFormat(DSFormat format) - { - setFormat(ptr, format); - } - - /** - * Get current format. - * - * @return current format used - */ - public DSFormat getFormat() - { - return getFormat(ptr); - } - - /** - * Get the supported video format this capture device supports. - * - * @return array of DSFormat - */ - public DSFormat[] getSupportedFormats() - { - DSFormat formats[] = getSupportedFormats(ptr); - - if(formats == null) - { - formats = EMPTY_FORMATS; - } - - return formats; - } - - /** - * Set a delegate to use when a frame is received. - * @param delegate delegate - */ - public void setDelegate(GrabberDelegate delegate) - { - setDelegate(ptr, delegate); - } - - /** - * Native method to open capture device. - * - * @param ptr native pointer of DSCaptureDevice - */ - private native void open(long ptr); - - /** - * Native method to close capture device. - * - * @param ptr native pointer of DSCaptureDevice - */ - private native void close(long ptr); - - /** - * Native method to get name of the capture device. - * - * @param ptr native pointer of DSCaptureDevice - * @return name of the capture device - */ - private native String getName(long ptr); - - /** - * Native method to set format on the capture device. - * - * @param ptr native pointer of DSCaptureDevice - * @param format format to set - */ - private native void setFormat(long ptr, DSFormat format); - - /** - * Native method to get format on the capture device. - * - * @param ptr native pointer of DSCaptureDevice - * @return format current format - */ - private native DSFormat getFormat(long ptr); - - /** - * Native method to get supported formats from capture device. - * - * @param ptr native pointer of DSCaptureDevice - * @return array of native pointer corresponding to formats - */ - private native DSFormat[] getSupportedFormats(long ptr); - - /** - * Native method to set a delegate to use when a frame is received. - * @param ptr native pointer - * @param delegate delegate - */ - public native void setDelegate(long ptr, GrabberDelegate delegate); - - /** - * Get bytes from buf native pointer and copy them - * to ptr byte native pointer. - * - * @param ptr pointer to native data - * @param buf byte native pointer (see ByteBufferPool) - * @param length length of buf pointed by ptr - * @return length written to buf - */ - public static native int getBytes(long ptr, long buf, int length); - - /** - * Delegate class to handle grabbing frames. - * - * @author Sebastien Vincent - */ - public static abstract class GrabberDelegate - { - /** - * Callback method when receiving frames. - * - * @param ptr native pointer to data - * @param length length of data - */ - public abstract void frameReceived(long ptr, int length); - } -} - diff --git a/src/net/java/sip/communicator/impl/neomedia/directshow/DSFormat.java b/src/net/java/sip/communicator/impl/neomedia/directshow/DSFormat.java deleted file mode 100644 index ca4f9e7ef..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/directshow/DSFormat.java +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.directshow; - -/** - * DirectShow video format. - * - * @author Sebastien Vincent - */ -public class DSFormat -{ - - static - { - System.loadLibrary("jndirectshow"); - - RGB24 = getRGB24PixelFormat(); - RGB32 = getRGB32PixelFormat(); - ARGB32 = getARGBPixelFormat(); - YUY2 = getYUY2PixelFormat(); - UYVY = getUYVYPixelFormat(); - NV12 = getNV12PixelFormat(); - Y411 = getY411PixelFormat(); - Y41P = getY41PPixelFormat(); - I420 = getI420PixelFormat(); - } - - /* supported formats */ - - /** - * The RGB24 constant. - */ - public static final long RGB24; - - /** - * The RGB32 constant. - */ - public static final long RGB32; - - /** - * The ARGB32 constant. - */ - public static final long ARGB32; - - /** - * The YUY2 constant. - */ - public static final long YUY2; - - /** - * The UYVY constant. - */ - public static final long UYVY; - - /** - * The Y411 constant. - */ - public static final long Y411; - - /** - * The Y41P constant. - */ - public static final long Y41P; - - /** - * The NV12 constant. - */ - public static final long NV12; - - /** - * The I420 constant. - */ - public static final long I420; - - /** - * Video width. - */ - private int width = 0; - - /** - * Video height. - */ - private int height = 0; - - /** - * Color space. - */ - private long pixelFormat = -1; - - /** - * Constructor. - * - * @param width video width - * @param height video height - * @param pixelFormat pixel format - */ - public DSFormat(int width, int height, long pixelFormat) - { - this.width = width; - this.height = height; - this.pixelFormat = pixelFormat; - } - - /** - * Get video width. - * - * @return video width - */ - public int getWidth() - { - return width; - } - - /** - * Get video height. - * - * @return video height - */ - public int getHeight() - { - return height; - } - - /** - * Get color space. - * - * @return color space - */ - public long getPixelFormat() - { - return pixelFormat; - } - - /* RGB */ - /** - * Get the RGB24 native pixel format - * - * @return RGB24 native format value - */ - public static native long getRGB24PixelFormat(); - - /** - * Get the RGB32 native pixel format - * - * @return RGB32 native format value - */ - public static native long getRGB32PixelFormat(); - - /** - * Get the ARGB32 native pixel format - * - * @return ARGB32 native format value - */ - public static native long getARGBPixelFormat(); - - /* YUV */ - - /** - * Get the AYUV native pixel format - * - * @return AYUV native format value - */ - public static native long getAYUVPixelFormat(); - - /** - * Get the YUY2 native pixel format - * - * @return YUY2 native format value - */ - public static native long getYUY2PixelFormat(); - - /** - * Get the UYVY native pixel format - * - * @return UYVY native format value - */ - public static native long getUYVYPixelFormat(); - - /** - * Get the IMC1 native pixel format - * - * @return IMC1 native format value - */ - public static native long getIMC1PixelFormat(); - - /** - * Get the IMC2 native pixel format - * - * @return IMC2 native format value - */ - public static native long getIMC2PixelFormat(); - - /** - * Get the IMC3 native pixel format - * - * @return IMC3 native format value - */ - public static native long getIMC3PixelFormat(); - - /** - * Get the IMC4 native pixel format - * - * @return IMC4 native format value - */ - public static native long getIMC4PixelFormat(); - - /** - * Get the YV12 native pixel format - * - * @return YV12 native format value - */ - public static native long getYV12PixelFormat(); - - /** - * Get the NV12 native pixel format - * - * @return NV12 native format value - */ - public static native long getNV12PixelFormat(); - - /** - * Get the IF09 native pixel format - * - * @return IF09 native format value - */ - public static native long getIF09PixelFormat(); - - /** - * Get the IYUV native pixel format - * - * @return IYUV native format value - */ - public static native long getIYUVPixelFormat(); - - /** - * Get the Y211 native pixel format - * - * @return Y211 native format value - */ - public static native long getY211PixelFormat(); - - /** - * Get the Y411 native pixel format - * - * @return Y411 native format value - */ - public static native long getY411PixelFormat(); - - /** - * Get the Y41P native pixel format - * - * @return Y41P native format value - */ - public static native long getY41PPixelFormat(); - - /** - * Get the YVU9 native pixel format - * - * @return YVU9 native format value - */ - public static native long getYVU9PixelFormat(); - - /** - * Get the YVYU native pixel format - * - * @return YVYU native format value - */ - public static native long getYVYUPixelFormat(); - - /** - * Get the I420 native pixel format - * - * @return I420 native format value - */ - public static native long getI420PixelFormat(); -} - diff --git a/src/net/java/sip/communicator/impl/neomedia/directshow/DSManager.java b/src/net/java/sip/communicator/impl/neomedia/directshow/DSManager.java deleted file mode 100644 index 0ab7eb421..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/directshow/DSManager.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.directshow; - -/** - * DirectShow capture device manager. - * - * DSManager act as a singleton. When you need it - * call getInstance and don't forget to call dispose() - * when you have finished. - * - * - * DSManager manager = DSManager.getInstance(); - * - * DSCaptureDevice[] devices = manager.getCaptureDevices(); - * - * // do stuff with capture devices - * // ... - * - * DSManager.dispose(); - * - * // do not use any of DSCaptureDevice objects obtained by - * // manager - * - * - * @author Sebastien Vincent - */ -public class DSManager -{ - static - { - /* load DLL */ - System.loadLibrary("jndirectshow"); - } - - /** - * Empty array of DSCaptureDevices. Explicitly defined in order to - * avoid unnecessary allocations. - */ - private static DSCaptureDevice[] EMPTY_DEVICES = new DSCaptureDevice[0]; - - /** - * Unique instance of DSManager. - */ - private static DSManager instance = null; - - /** - * Reference count. - */ - private static int ref = 0; - - /** - * Synchronization object. - */ - private static Object sync = new Object(); - - /** - * Array of all DSCaptureDevice found - * on the OS. - */ - private DSCaptureDevice[] devices = null; - - /** - * Native pointer. - */ - private long ptr = 0; - - /** - * Get the instance. - * - * @return unique instance of DSManager - */ - public static synchronized DSManager getInstance() - { - synchronized(sync) - { - if(instance == null) - { - long ptr = init(); - - if(ptr != 0) - { - instance = new DSManager(ptr); - } - } - - /* increment reference if object is valid */ - if(instance != null) - { - ref++; - } - } - return instance; - } - - /** - * Dispose the object. - */ - public static synchronized void dispose() - { - synchronized(sync) - { - ref--; - - if(ref == 0 && instance != null && instance.ptr != 0) - { - destroy(instance.ptr); - } - instance = null; - ref = 0; - } - } - - /** - * Constructor. - * - * @param ptr native pointer of DSManager - */ - private DSManager(long ptr) - { - if(ptr == 0) - { - throw new IllegalArgumentException("invalid ptr value (0)"); - } - - this.ptr = ptr; - } - - /** - * Get the array of capture devices. - * - * @return array of DSCaptureDevices - */ - public DSCaptureDevice[] getCaptureDevices() - { - if(devices == null) - { - long nativeDevices[] = getCaptureDevices(ptr); - - if(nativeDevices != null && nativeDevices.length > 0) - { - devices = new DSCaptureDevice[nativeDevices.length]; - - for(int i = 0 ; i < nativeDevices.length ; i++) - { - devices[i] = new DSCaptureDevice(nativeDevices[i]); - } - } - else - { - devices = EMPTY_DEVICES; - } - } - return devices; - } - - /** - * Initialize and gather existing capture device. - * - * @return native pointer - */ - private static native long init(); - - /** - * Delete native pointer. - * - * @param ptr native pointer to delete - */ - private static native void destroy(long ptr); - - /** - * Native method to get capture devices pointers. - * - * @param ptr native pointer of DSManager - * @return array of native pointer to DSCaptureDevice - */ - private native long[] getCaptureDevices(long ptr); -} - diff --git a/src/net/java/sip/communicator/impl/neomedia/format/AudioMediaFormatImpl.java b/src/net/java/sip/communicator/impl/neomedia/format/AudioMediaFormatImpl.java deleted file mode 100644 index 7471960a7..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/format/AudioMediaFormatImpl.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.format; - -import java.util.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.format.*; - -/** - * Implements AudioMediaFormat for the JMF AudioFormat. - * - * @author Lubomir Marinov - */ -public class AudioMediaFormatImpl - extends MediaFormatImpl - implements AudioMediaFormat -{ - - /** - * Initializes a new AudioMediaFormatImpl instance which is to - * provide an implementation of AudioMediaFormat for a specific - * JMF AudioFormat. - * - * @param format the JMF AudioFormat the new instance is to wrap - * and provide an implementation of AudioMediaFormat for - */ - AudioMediaFormatImpl(AudioFormat format) - { - this(format, null, null); - } - - /** - * Initializes a new AudioMediaFormatImpl instance which is to - * provide an implementation of AudioMediaFormat for a specific - * JMF AudioFormat and to have a specific set of format-specific - * parameters. - * - * @param format the JMF AudioFormat the new instance is to wrap - * and provide an implementation of AudioMediaFormat for - * @param formatParameters the set of format-specific parameters of the new - * instance - * @param advancedParameters the set of format-specific parameters of the new - * instance - */ - AudioMediaFormatImpl( - AudioFormat format, - Map formatParameters, - Map advancedParameters) - { - super(fixChannels(format), formatParameters, advancedParameters); - } - - /** - * Initializes a new AudioMediaFormatImpl instance with the - * specified encoding and a single audio channel. - * - * @param encoding the encoding of the new AudioMediaFormatImpl - * instance - */ - public AudioMediaFormatImpl(String encoding) - { - this(new AudioFormat(encoding)); - } - - /** - * Initializes a new AudioMediaFormatImpl instance with the - * specified encoding and clock rate and a single audio channel. - * - * @param encoding the encoding of the new AudioMediaFormatImpl - * instance - * @param clockRate the clock (i.e. sample) rate of the new - * AudioMediaFormatImpl instance - */ - AudioMediaFormatImpl(String encoding, double clockRate) - { - this(encoding, clockRate, 1); - } - - /** - * Initializes a new AudioMediaFormatImpl instance with the - * specified encoding, clock rate and number of audio channels. - * - * @param encoding the encoding of the new AudioMediaFormatImpl - * instance - * @param clockRate the clock (i.e. sample) rate of the new - * AudioMediaFormatImpl instance - * @param channels the number of available channels (1 for mono, 2 for - * stereo) - */ - AudioMediaFormatImpl(String encoding, double clockRate, int channels) - { - this(encoding, clockRate, channels, null, null); - } - - /** - * Initializes a new AudioMediaFormatImpl instance with the - * specified encoding, clock rate and format parameters and a single audio - * channel. - * - * @param encoding the encoding of the new AudioMediaFormatImpl - * instance - * @param clockRate the clock (i.e. sample) rate of the new - * AudioMediaFormatImpl instance - * @param formatParameters any codec-specific parameters that have been - * received via SIP/SDP or XMPP/Jingle. - * @param advancedParameters set of advanced parameters that have been - * received by SIP/SDP or XMPP/Jingle - */ - AudioMediaFormatImpl( - String encoding, - double clockRate, - Map formatParameters, - Map advancedParameters) - { - this(encoding, clockRate, 1, formatParameters, advancedParameters); - } - - /** - * Initializes a new AudioMediaFormatImpl instance with the - * specified encoding, clock rate, number of audio channels and format - * parameters. - * - * @param encoding the encoding of the new AudioMediaFormatImpl - * instance - * @param clockRate the clock (i.e. sample) rate of the new - * AudioMediaFormatImpl instance - * @param channels the number of available channels (1 for mono, 2 for - * stereo) - * @param formatParameters any codec-specific parameters that have been - * received via SIP/SDP or XMPP/Jingle - * @param advancedParameters any parameters that have been - * received via SIP/SDP or XMPP/Jingle - */ - AudioMediaFormatImpl( - String encoding, - double clockRate, - int channels, - Map formatParameters, - Map advancedParameters) - { - this( - new AudioFormat( - encoding, - clockRate, - AudioFormat.NOT_SPECIFIED, - channels), - formatParameters, - advancedParameters); - } - - /** - * Gets an AudioFormat instance which matches a specific - * AudioFormat and has 1 channel if the specified - * AudioFormat has its number of channels not specified. - * - * @param format the AudioFormat to get a match of - * @return if the specified format has a specific number of - * channels, format; otherwise, a new AudioFormat instance - * which matches format and has 1 channel - */ - private static AudioFormat fixChannels(AudioFormat format) - { - if (Format.NOT_SPECIFIED == format.getChannels()) - format - = (AudioFormat) - format - .intersects( - new AudioFormat( - format.getEncoding(), - format.getSampleRate(), - format.getSampleSizeInBits(), - 1)); - return format; - } - - /** - * Gets the number of audio channels associated with this - * AudioMediaFormat. - * - * @return the number of audio channels associated with this - * AudioMediaFormat - * @see AudioMediaFormat#getChannels() - */ - public int getChannels() - { - int channels = format.getChannels(); - - return (Format.NOT_SPECIFIED == channels) ? 1 : channels; - } - - /** - * Gets the clock rate associated with this MediaFormat. - * - * @return the clock rate associated with this MediaFormat - * @see MediaFormat#getClockRate() - */ - public double getClockRate() - { - return format.getSampleRate(); - } - - /** - * Gets the type of this MediaFormat which is - * {@link MediaType#AUDIO} for AudioMediaFormatImpl instances. - * - * @return the MediaType that this format represents and which is - * MediaType.AUDIO for AudioMediaFormatImpl instances - * @see MediaFormat#getMediaType() - */ - public final MediaType getMediaType() - { - return MediaType.AUDIO; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatFactoryImpl.java b/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatFactoryImpl.java deleted file mode 100644 index 75a27c964..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatFactoryImpl.java +++ /dev/null @@ -1,487 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.format; - -import java.util.*; -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.format.*; -import net.java.sip.communicator.util.*; - -/** - * Implements MediaFormatFactory for the JMF Format types. - * - * @author Lyubomir Marinov - */ -public class MediaFormatFactoryImpl - implements MediaFormatFactory -{ - /** - * The Logger used by the MediaFormatFactoryImpl class and - * its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(MediaFormatFactoryImpl.class); - - /** - * Creates an unknown MediaFormat. - * - * @param type MediaType - * @return unknown MediaFormat - */ - public MediaFormat createUnknownMediaFormat(MediaType type) - { - Format unknown = null; - - /* - * FIXME Why is a VideoFormat instance created for MediaType.AUDIO and - * an AudioFormat instance for MediaType.VIDEO? - */ - if(type.equals(MediaType.AUDIO)) - unknown = new VideoFormat("unknown"); - else if(type.equals(MediaType.VIDEO)) - unknown = new AudioFormat("unknown"); - return MediaFormatImpl.createInstance(unknown); - } - - /** - * Creates a MediaFormat for the specified encoding with - * default clock rate and set of format parameters. If encoding is - * known to this MediaFormatFactory, returns a - * MediaFormat which is either an AudioMediaFormat or a - * VideoMediaFormat instance. Otherwise, returns null. - * - * @param encoding the well-known encoding (name) to create a - * MediaFormat for - * @return a MediaFormat with the specified encoding which - * is either an AudioMediaFormat or a VideoMediaFormat - * instance if encoding is known to this - * MediaFormatFactory; otherwise, null - * @see MediaFormatFactory#createMediaFormat(String) - */ - public MediaFormat createMediaFormat(String encoding) - { - return createMediaFormat(encoding, CLOCK_RATE_NOT_SPECIFIED); - } - - /** - * Creates a MediaFormat for the specified RTP payload type with - * default clock rate and set of format parameters. If - * rtpPayloadType is known to this MediaFormatFactory, - * returns a MediaFormat which is either an - * AudioMediaFormat or a VideoMediaFormat instance. - * Otherwise, returns null. - * - * @param rtpPayloadType the RTP payload type of the MediaFormat to - * create - * @return a MediaFormat with the specified rtpPayloadType - * which is either an AudioMediaFormat or a - * VideoMediaFormat instance if rtpPayloadType is known to - * this MediaFormatFactory; otherwise, null - * @see MediaFormatFactory#createMediaFormat(byte) - */ - public MediaFormat createMediaFormat(byte rtpPayloadType) - { - /* - * We know which are the MediaFormat instances with the specified - * rtpPayloadType but we cannot directly return them because they do not - * reflect the user's configuration with respect to being enabled and - * disabled. - */ - for (MediaFormat rtpPayloadTypeMediaFormat - : MediaUtils.getMediaFormats(rtpPayloadType)) - { - MediaFormat mediaFormat - = createMediaFormat( - rtpPayloadTypeMediaFormat.getEncoding(), - rtpPayloadTypeMediaFormat.getClockRate()); - if (mediaFormat != null) - return mediaFormat; - } - return null; - } - - /** - * Creates a MediaFormat for the specified encoding with - * the specified clockRate and a default set of format parameters. - * If encoding is known to this MediaFormatFactory, - * returns a MediaFormat which is either an - * AudioMediaFormat or a VideoMediaFormat instance. - * Otherwise, returns null. - * - * @param encoding the well-known encoding (name) to create a - * MediaFormat for - * @param clockRate the clock rate in Hz to create a MediaFormat - * for - * @return a MediaFormat with the specified encoding and - * clockRate which is either an AudioMediaFormat or a - * VideoMediaFormat instance if encoding is known to this - * MediaFormatFactory; otherwise, null - * @see MediaFormatFactory#createMediaFormat(String, double) - */ - public MediaFormat createMediaFormat(String encoding, double clockRate) - { - return createMediaFormat(encoding, clockRate, 1); - } - - /** - * Creates a MediaFormat for the specified encoding, - * clockRate and channels and a default set of format - * parameters. If encoding is known to this - * MediaFormatFactory, returns a MediaFormat which is - * either an AudioMediaFormat or a VideoMediaFormat - * instance. Otherwise, returns null. - * - * @param encoding the well-known encoding (name) to create a - * MediaFormat for - * @param clockRate the clock rate in Hz to create a MediaFormat - * for - * @param channels the number of available channels (1 for mono, 2 for - * stereo) if it makes sense for the MediaFormat with the specified - * encoding; otherwise, ignored - * @return a MediaFormat with the specified encoding, - * clockRate and channels and a default set of format - * parameters which is either an AudioMediaFormat or a - * VideoMediaFormat instance if encoding is known to this - * MediaFormatFactory; otherwise, null - * @see MediaFormatFactory#createMediaFormat(String, double, int) - */ - public MediaFormat createMediaFormat( - String encoding, double clockRate, int channels) - { - return createMediaFormat(encoding, clockRate, channels, null); - } - - private MediaFormat createMediaFormat( - String encoding, double clockRate, int channels, - Map fmtps) - { - for (MediaFormat format : getSupportedMediaFormats(encoding, clockRate)) - { - /* - * The mediaType, encoding and clockRate properties are sure to - * match because format is the result of the search for encoding and - * clockRate. We just want to make sure that the channels and the - * format parameters match. - */ - if (AbstractMediaStream.matches( - format, - format.getMediaType(), - format.getEncoding(), format.getClockRate(), channels, - fmtps)) - return format; - } - return null; - } - - /** - * Creates a MediaFormat for the specified encoding, - * clockRate and set of format parameters. If encoding is - * known to this MediaFormatFactory, returns a MediaFormat - * which is either an AudioMediaFormat or a - * VideoMediaFormat instance. Otherwise, returns null. - * - * @param encoding the well-known encoding (name) to create a - * MediaFormat for - * @param clockRate the clock rate in Hz to create a MediaFormat - * for - * @param formatParams any codec specific parameters which have been - * received via SIP/SDP or XMPP/Jingle - * @return a MediaFormat with the specified encoding, - * clockRate and set of format parameters which is either an - * AudioMediaFormat or a VideoMediaFormat instance if - * encoding is known to this MediaFormatFactory; - * otherwise, null - * @see MediaFormatFactory#createMediaFormat(String, double, Map, Map) - */ - public MediaFormat createMediaFormat( - String encoding, double clockRate, - Map formatParams, - Map advancedParams) - { - return - createMediaFormat( - encoding, clockRate, 1, -1, - formatParams, - advancedParams); - } - - /** - * Creates a MediaFormat for the specified encoding, - * clockRate, channels and set of format parameters. If - * encoding is known to this MediaFormatFactory, returns a - * MediaFormat which is either an AudioMediaFormat or a - * VideoMediaFormat instance. Otherwise, returns null. - * - * @param encoding the well-known encoding (name) to create a - * MediaFormat for - * @param clockRate the clock rate in Hz to create a MediaFormat - * for - * @param frameRate the frame rate in number of frames per second to - * create a MediaFormat for - * @param channels the number of available channels (1 for mono, 2 for - * stereo) if it makes sense for the MediaFormat with the specified - * encoding; otherwise, ignored - * @param formatParams any codec specific parameters which have been - * received via SIP/SDP or XMPP/Jingle - * @param advancedParams any parameters which have been - * received via SIP/SDP or XMPP/Jingle - * @return a MediaFormat with the specified encoding, - * clockRate, channels and set of format parameters which - * is either an AudioMediaFormat or a VideoMediaFormat - * instance if encoding is known to this - * MediaFormatFactory; otherwise, null - * @see MediaFormatFactory#createMediaFormat(String, double, int, float, Map, Map) - */ - public MediaFormat createMediaFormat( - String encoding, double clockRate, int channels, float frameRate, - Map formatParams, - Map advancedParams) - { - MediaFormat mediaFormat - = createMediaFormat(encoding, clockRate, channels, formatParams); - - if (mediaFormat == null) - return null; - - /* - * MediaFormatImpl is immutable so if the caller wants to change the - * format parameters and/or the advanced attributes, we'll have to - * create a new MediaFormatImpl. - */ - Map formatParameters = null; - Map advancedParameters = null; - - if ((formatParams != null) && !formatParams.isEmpty()) - formatParameters = formatParams; - if ((advancedParams != null ) && !advancedParams.isEmpty()) - advancedParameters = advancedParams; - - if ((formatParameters != null) || (advancedParameters != null)) - { - switch (mediaFormat.getMediaType()) - { - case AUDIO: - mediaFormat - = new AudioMediaFormatImpl( - ((AudioMediaFormatImpl) mediaFormat).getFormat(), - formatParameters, advancedParameters); - break; - case VIDEO: - VideoMediaFormatImpl videoMediaFormatImpl - = (VideoMediaFormatImpl) mediaFormat; - - /* - * If the format of VideoMediaFormatImpl is - * a ParameterizedVideoFormat, it's possible for the format - * parameters of that ParameterizedVideoFormat and of the new - * VideoMediaFormatImpl (to be created) to be out of sync. While - * it's not technically perfect, it should be practically safe - * for the format parameters which distinguish VideoFormats with - * the same encoding and clock rate because mediaFormat has - * already been created in sync with formatParams (with respect - * to the format parameters which distinguish VideoFormats with - * the same encoding and clock rate). - */ - mediaFormat - = new VideoMediaFormatImpl( - videoMediaFormatImpl.getFormat(), - videoMediaFormatImpl.getClockRate(), - frameRate, - formatParameters, advancedParameters); - break; - default: - mediaFormat = null; - } - } - return mediaFormat; - } - - /** - * Creates a MediaFormat either for the specified - * rtpPayloadType or for the specified encoding, - * clockRate, channels and set of format parameters. If - * encoding is known to this MediaFormatFactory, ignores - * rtpPayloadType and returns a MediaFormat which is - * either an AudioMediaFormat or a VideoMediaFormat - * instance. If rtpPayloadType is not - * {@link MediaFormat#RTP_PAYLOAD_TYPE_UNKNOWN} and encoding is - * null, uses the encoding associated with rtpPayloadType. - * - * @param rtpPayloadType the RTP payload type to create a - * MediaFormat for; {@link MediaFormat#RTP_PAYLOAD_TYPE_UNKNOWN} if - * encoding is not null. If rtpPayloadType is not - * MediaFormat#RTP_PAYLOAD_TYPE_UNKNOWN and encoding is - * not null, rtpPayloadType is ignored - * @param encoding the well-known encoding (name) to create a - * MediaFormat for; null - * @param clockRate the clock rate in Hz to create a MediaFormat - * for - * @param frameRate the frame rate in number of frames per second to - * create a MediaFormat for - * @param channels the number of available channels (1 for mono, 2 for - * stereo) if it makes sense for the MediaFormat with the specified - * encoding; otherwise, ignored - * @param formatParams any codec specific parameters which have been - * received via SIP/SDP or XMPP/Jingle - * @param advancedParams any parameters which have been - * received via SIP/SDP or XMPP/Jingle - * @return a MediaFormat with the specified encoding, - * clockRate, channels and set of format parameters which - * is either an AudioMediaFormat or a VideoMediaFormat - * instance if encoding is known to this - * MediaFormatFactory; otherwise, null - */ - public MediaFormat createMediaFormat( - byte rtpPayloadType, - String encoding, double clockRate, int channels, float frameRate, - Map formatParams, - Map advancedParams) - { - - /* - * If rtpPayloadType is specified, use it only to figure out encoding - * and/or clockRate in case either one of them is unknown. - */ - if ((MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN != rtpPayloadType) - && ((encoding == null) - || (CLOCK_RATE_NOT_SPECIFIED == clockRate))) - { - MediaFormat[] rtpPayloadTypeMediaFormats - = MediaUtils.getMediaFormats(rtpPayloadType); - - if (rtpPayloadTypeMediaFormats.length > 0) - { - if (encoding == null) - encoding = rtpPayloadTypeMediaFormats[0].getEncoding(); - - // Assign or check the clock rate. - if (CLOCK_RATE_NOT_SPECIFIED == clockRate) - clockRate = rtpPayloadTypeMediaFormats[0].getClockRate(); - else - { - boolean clockRateIsValid = false; - - for (MediaFormat rtpPayloadTypeMediaFormat - : rtpPayloadTypeMediaFormats) - if (rtpPayloadTypeMediaFormat - .getEncoding().equals(encoding) - && (rtpPayloadTypeMediaFormat.getClockRate() - == clockRate)) - { - clockRateIsValid = true; - break; - } - - if (!clockRateIsValid) - return null; - } - } - } - - return - createMediaFormat( - encoding, clockRate, channels, frameRate, - formatParams, - advancedParams); - } - - /** - * Gets the MediaFormats among the specified mediaFormats - * which have the specified encoding and, optionally, - * clockRate. - * - * @param mediaFormats the MediaFormats from which to filter out - * only the ones which have the specified encoding and, optionally, - * clockRate - * @param encoding the well-known encoding (name) of the - * MediaFormats to be retrieved - * @param clockRate the clock rate of the MediaFormats to be - * retrieved; {@link #CLOCK_RATE_NOT_SPECIFIED} if any clock rate is - * acceptable - * @return a List of the MediaFormats among - * mediaFormats which have the specified encoding and, - * optionally, clockRate - */ - private List getMatchingMediaFormats( - MediaFormat[] mediaFormats, - String encoding, double clockRate) - { - /* - * XXX Use String#equalsIgnoreCase(String) because some clients transmit - * some of the codecs starting with capital letters. - */ - - /* - * As per RFC 3551.4.5.2, because of a mistake in RFC 1890 and for - * backward compatibility, G.722 should always be announced as 8000 even - * though it is wideband. So, if someone is looking for G722/16000, - * then: Forgive them, for they know not what they do! - */ - if("G722".equalsIgnoreCase(encoding) && (16000 == clockRate)) - { - clockRate = 8000; - if (logger.isInfoEnabled()) - logger.info("Suppressing erroneous 16000 announcement for G.722"); - } - - List supportedMediaFormats = new ArrayList(); - - for (MediaFormat mediaFormat : mediaFormats) - { - if (mediaFormat.getEncoding().equalsIgnoreCase(encoding) - && ((CLOCK_RATE_NOT_SPECIFIED == clockRate) - || (mediaFormat.getClockRate() == clockRate))) - { - supportedMediaFormats.add(mediaFormat); - } - } - return supportedMediaFormats; - } - - /** - * Gets the MediaFormats supported by this - * MediaFormatFactory and the MediaService associated with - * it and having the specified encoding and, optionally, - * clockRate. - * - * @param encoding the well-known encoding (name) of the - * MediaFormats to be retrieved - * @param clockRate the clock rate of the MediaFormats to be - * retrieved; {@link #CLOCK_RATE_NOT_SPECIFIED} if any clock rate is - * acceptable - * @return a List of the MediaFormats supported by the - * MediaService associated with this MediaFormatFactory - * and having the specified encoding and, optionally, clock rate - */ - private List getSupportedMediaFormats( - String encoding, double clockRate) - { - EncodingConfiguration encodingConfiguration - = NeomediaActivator.getMediaServiceImpl() - .getEncodingConfiguration(); - List supportedMediaFormats - = getMatchingMediaFormats( - encodingConfiguration.getSupportedEncodings( - MediaType.AUDIO), - encoding, - clockRate); - - if (supportedMediaFormats.isEmpty()) - supportedMediaFormats - = getMatchingMediaFormats( - encodingConfiguration.getSupportedEncodings( - MediaType.VIDEO), - encoding, - clockRate); - return supportedMediaFormats; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatImpl.java b/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatImpl.java deleted file mode 100644 index 5f0c13f11..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatImpl.java +++ /dev/null @@ -1,611 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.format; - -import java.util.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.format.*; - -/** - * Implements MediaFormat for the JMF Format. - * - * @param the type of the wrapped Format - * - * @author Lyubomir Marinov - */ -public abstract class MediaFormatImpl - implements MediaFormat -{ - /** - * The name of the clockRate property of MediaFormatImpl. - */ - public static final String CLOCK_RATE_PNAME = "clockRate"; - - /** - * The value of the formatParameters property of - * MediaFormatImpl when no codec-specific parameters have been - * received via SIP/SDP or XMPP/Jingle. Explicitly defined in order to - * reduce unnecessary allocations. - */ - static final Map EMPTY_FORMAT_PARAMETERS - = Collections.emptyMap(); - - /** - * The value of the codecSettings property of - * MediaFormatImpl when no codec-specific settings. - * Explicitly defined in order to reduce unnecessary allocations. - */ - static final Map EMPTY_CODEC_SETTINGS - = Collections.emptyMap(); - - /** - * The name of the encoding property of MediaFormatImpl. - */ - public static final String ENCODING_PNAME = "encoding"; - - /** - * The name of the formatParameters property of - * MediaFormatImpl. - */ - public static final String FORMAT_PARAMETERS_PNAME = "fmtps"; - - /** - * The additional codec settings. - */ - private Map codecSettings = EMPTY_CODEC_SETTINGS; - - /** - * Creates a new MediaFormat instance for a specific JMF - * Format. - * - * @param format the JMF Format the new instance is to provide an - * implementation of MediaFormat for - * @return a new MediaFormat instance for the specified JMF - * Format - */ - public static MediaFormat createInstance(Format format) - { - MediaFormat mediaFormat = MediaUtils.getMediaFormat(format); - - if (mediaFormat == null) - { - if (format instanceof AudioFormat) - mediaFormat = new AudioMediaFormatImpl((AudioFormat) format); - else if (format instanceof VideoFormat) - mediaFormat = new VideoMediaFormatImpl((VideoFormat) format); - } - return mediaFormat; - } - - /** - * Creates a new MediaFormat instance for a specific JMF - * Format and assigns it specific clock rate and set of - * format-specific parameters. - * - * @param format the JMF Format the new instance is to provide an - * implementation of MediaFormat for - * @param clockRate the clock rate of the new instance - * @param formatParameters the set of format-specific parameters of the new - * instance - * @param advancedAttrs advanced attributes of the new instance - * @return a new MediaFormat instance for the specified JMF - * Format and with the specified clock rate and set of - * format-specific parameters - */ - public static MediaFormatImpl createInstance( - Format format, - double clockRate, - Map formatParameters, - Map advancedAttrs) - { - if (format instanceof AudioFormat) - { - AudioFormat audioFormat = (AudioFormat) format; - AudioFormat clockRateAudioFormat - = new AudioFormat( - audioFormat.getEncoding(), - clockRate, - audioFormat.getSampleSizeInBits(), - audioFormat.getChannels()); - - return - new AudioMediaFormatImpl( - (AudioFormat) - clockRateAudioFormat.intersects(audioFormat), - formatParameters, - advancedAttrs); - } - else if (format instanceof VideoFormat) - return - new VideoMediaFormatImpl( - (VideoFormat) format, - clockRate, - -1, - formatParameters, - advancedAttrs); - else - return null; - } - - /** - * Determines whether a specific set of advanced attributes is equal to - * another set of advanced attributes in the sense that they define an equal - * number of parameters and assign them equal values. Since the values are - * Strings, presumes that a value of null is equal to the - * empty String. - *

- * - * @param adv the first set of advanced attributes to be tested for - * equality - * @param adv2 the second set of advanced attributes to be tested for - * equality - * @return true if the specified sets of advanced attributes - * equal; false, otherwise - */ - public boolean advancedAttributesAreEqual(Map adv, - Map adv2) - { - if(adv == null && adv2 != null || adv != null && adv2 == null) - return false; - - if(adv == null && adv2 == null) - return true; - - if(adv.size() != adv2.size()) - return false; - - for(Map.Entry a : adv.entrySet()) - { - String value = adv2.get(a.getKey()); - if(value == null) - return false; - else - if(!value.equals(a.getValue())) - return false; - } - return true; - } - - /** - * Determines whether a specific set of format parameters is equal to - * another set of format parameters in the sense that they define an equal - * number of parameters and assign them equal values. Since the values are - * Strings, presumes that a value of null is equal to the - * empty String. - *

- * The two Map instances of format parameters to be checked for - * equality are presumed to be modifiable in the sense that if the lack of a - * format parameter in a given Map is equivalent to it having a - * specific value, an association of the format parameter to the value in - * question may be added to or removed from the respective Map - * instance for the purposes of determining equality. - *

- * - * @param fmtps1 the first set of format parameters to be tested for - * equality - * @param fmtps2 the second set of format parameters to be tested for - * equality - * @return true if the specified sets of format parameters are - * equal; false, otherwise - */ - protected boolean formatParametersAreEqual( - Map fmtps1, - Map fmtps2) - { - return formatParametersAreEqual(getEncoding(), fmtps1, fmtps2); - } - - /** - * Determines whether a specific set of format parameters is equal to - * another set of format parameters in the sense that they define an equal - * number of parameters and assign them equal values. Since the values are - * Strings, presumes that a value of null is equal to the - * empty String. - *

- * The two Map instances of format parameters to be checked for - * equality are presumed to be modifiable in the sense that if the lack of a - * format parameter in a given Map is equivalent to it having a - * specific value, an association of the format parameter to the value in - * question may be added to or removed from the respective Map - * instance for the purposes of determining equality. - *

- * - * @param encoding the encoding (name) related to the two sets of format - * parameters to be tested for equality - * @param fmtps1 the first set of format parameters to be tested for - * equality - * @param fmtps2 the second set of format parameters to be tested for - * equality - * @return true if the specified sets of format parameters are - * equal; false, otherwise - */ - public static boolean formatParametersAreEqual( - String encoding, - Map fmtps1, Map fmtps2) - { - if (fmtps1 == null) - return (fmtps2 == null) || fmtps2.isEmpty(); - if (fmtps2 == null) - return (fmtps1 == null) || fmtps1.isEmpty(); - if (fmtps1.size() == fmtps2.size()) - { - for (Map.Entry fmtp1 : fmtps1.entrySet()) - { - String key1 = fmtp1.getKey(); - - if (!fmtps2.containsKey(key1)) - return false; - - String value1 = fmtp1.getValue(); - String value2 = fmtps2.get(key1); - - /* - * Since the values are strings, allow null to be equal to the - * empty string. - */ - if ((value1 == null) || (value1.length() == 0)) - { - if ((value2 != null) && (value2.length() != 0)) - return false; - } - else if (!value1.equals(value2)) - return false; - } - return true; - } - else - return false; - } - - /** - * {@inheritDoc} - *

- * The default implementation of MediaFormatImpl always returns - * true because format parameters in general do not cause the - * distinction of payload types. - *

- */ - public boolean formatParametersMatch(Map fmtps) - { - return true; - } - - /** - * The JMF Format this instance wraps and provides an - * implementation of MediaFormat for. - */ - protected final T format; - - /** - * The codec-specific parameters of this instance which have been received - * via SIP/SDP or XMPP/Jingle. - */ - private final Map formatParameters; - - /** - * The advanced parameters of this instance which have been received - * via SIP/SDP or XMPP/Jingle. - */ - private final Map advancedParameters; - - /** - * Initializes a new MediaFormatImpl instance which is to provide - * an implementation of MediaFormat for a specific Format. - * - * @param format the JMF Format the new instance is to provide an - * implementation of MediaFormat for - */ - protected MediaFormatImpl(T format) - { - this(format, null, null); - } - - /** - * Initializes a new MediaFormatImpl instance which is to provide - * an implementation of MediaFormat for a specific Format - * and which is to have a specific set of codec-specific parameters. - * - * @param format the JMF Format the new instance is to provide an - * implementation of MediaFormat for - * @param formatParameters any codec-specific parameters that have been - * received via SIP/SDP or XMPP/Jingle - * @param advancedParameters any parameters that have been - * received via SIP/SDP or XMPP/Jingle - */ - protected MediaFormatImpl( - T format, - Map formatParameters, - Map advancedParameters) - { - if (format == null) - throw new NullPointerException("format"); - - this.format = format; - this.formatParameters - = ((formatParameters == null) || formatParameters.isEmpty()) - ? EMPTY_FORMAT_PARAMETERS - : new HashMap(formatParameters); - this.advancedParameters - = ((advancedParameters == null) || advancedParameters.isEmpty()) - ? EMPTY_FORMAT_PARAMETERS - : new HashMap(advancedParameters); - } - - /** - * Implements MediaFormat#equals(Object) and actually compares the - * encapsulated JMF Format instances. - * - * @param mediaFormat the object that we'd like to compare this one - * to. - 8* - * @return true if the JMF Format instances encapsulated - * by this class are equal and false otherwise. - */ - @Override - public boolean equals(Object mediaFormat) - { - if (this == mediaFormat) - return true; - - if (!getClass().isInstance(mediaFormat)) - return false; - - @SuppressWarnings("unchecked") - MediaFormatImpl mediaFormatImpl = (MediaFormatImpl) mediaFormat; - - return getFormat().equals(mediaFormatImpl.getFormat()) - && formatParametersAreEqual( - getFormatParameters(), - mediaFormatImpl.getFormatParameters()); - } - - /** - * Implements MediaFormat#getEncoding() and returns the encoding of the JMF - * Format that we are encapsulating here but it is the RFC-known - * encoding and not the internal JMF encoding. - * - * @return the RFC-known encoding of the JMF Format that we are - * encapsulating - */ - public String getEncoding() - { - String jmfEncoding = getJMFEncoding(); - String encoding = MediaUtils.jmfEncodingToEncoding(jmfEncoding); - - if (encoding == null) - { - encoding = jmfEncoding; - - int encodingLength = encoding.length(); - - if (encodingLength > 3) - { - int rtpPos = encodingLength - 4; - - if ("/rtp".equalsIgnoreCase(encoding.substring(rtpPos))) - encoding = encoding.substring(0, rtpPos); - } - } - return encoding; - } - - /** - * Returns the JMF Format instance that we are wrapping here. - * - * @return a reference to that JMF Format instance that this class - * is wrapping. - */ - public T getFormat() - { - return format; - } - - /** - * Implements MediaFormat#getFormatParameters(). Returns a copy of the - * format properties of this instance. Modifications to the returned Map do - * no affect the format properties of this instance. - * - * @return a copy of the format properties of this instance. Modifications - * to the returned Map do no affect the format properties of this instance. - */ - public Map getFormatParameters() - { - return (formatParameters == EMPTY_FORMAT_PARAMETERS) - ? EMPTY_FORMAT_PARAMETERS - : new HashMap(formatParameters); - } - - /** - * Implements MediaFormat#getAdvancedParameters(). Returns a copy of the - * attribute properties of this instance. Modifications to the returned Map - * do no affect the format properties of this instance. - * - * @return a copy of the attribute properties of this instance. - * Modifications to the returned Map do no affect the format properties of - * this instance. - */ - public Map getAdvancedAttributes() - { - return (advancedParameters == EMPTY_FORMAT_PARAMETERS) - ? EMPTY_FORMAT_PARAMETERS - : new HashMap(advancedParameters); - } - - /** - * Gets the encoding of the JMF Format represented by this - * instance as it is known to JMF (in contrast to its RFC name). - * - * @return the encoding of the JMF Format represented by this - * instance as it is known to JMF (in contrast to its RFC name) - */ - public String getJMFEncoding() - { - return format.getEncoding(); - } - - /** - * Gets the RTP payload type (number) of this MediaFormat as it is - * known in RFC 3551 "RTP Profile for Audio and Video Conferences with - * Minimal Control". - * - * @return the RTP payload type of this MediaFormat if it is known - * in RFC 3551 "RTP Profile for Audio and Video Conferences with Minimal - * Control"; otherwise, {@link #RTP_PAYLOAD_TYPE_UNKNOWN} - * @see MediaFormat#getRTPPayloadType() - */ - public byte getRTPPayloadType() - { - return MediaUtils.getRTPPayloadType(getJMFEncoding(), getClockRate()); - } - - /** - * Overrides Object#hashCode() because Object#equals(Object) is overridden. - * - * @return a hash code value for this MediaFormat. - */ - @Override - public int hashCode() - { - /* - * XXX We've experienced a case of JMF's VideoFormat#hashCode() - * returning different values for instances which are reported equal by - * VideoFormat#equals(Object) which is inconsistent with the protocol - * covering the two methods in question and causes problems, - * for example, with Map. While jmfEncoding is more generic than format, - * it still provides a relatively good distribution given that we do not - * have a lot of instances with one and the same jmfEncoding. - */ - return getJMFEncoding().hashCode() | getFormatParameters().hashCode(); - } - - /** - * Returns a String representation of the clock rate associated - * with this MediaFormat making sure that the value appears as - * an integer (i.e. its long-casted value is equal to its original one) - * unless it is actually a non integer. - * - * @return a String representation of the clock rate associated - * with this MediaFormat. - */ - public String getClockRateString() - { - double clockRate = getClockRate(); - long clockRateL = (long) clockRate; - - if (clockRateL == clockRate) - return Long.toString(clockRateL); - else - return Double.toString(clockRate); - } - - /** - * Returns a String representation of the real used clock rate - * associated with this MediaFormat making sure that the value - * appears as an integer (i.e. contains no decimal point) unless it is - * actually a non integer. - * This function corrects the problem of the G.722 codec which advertises - * its clock rate to be 8 kHz while 16 kHz is really used to encode the - * stream (that's an error noted in the respective RFC and kept for the sake - * of compatibility.). - * - * @return a String representation of the real used clock rate - * associated with this MediaFormat. - */ - public String getRealUsedClockRateString() - { - // RFC 1890 erroneously assigned 8 kHz to the RTP clock rate for the - // G722 payload format. The actual sampling rate for G.722 audio is 16 - // kHz. - if(this.getEncoding().equalsIgnoreCase("G722")) - { - return "16000"; - } - return this.getClockRateString(); - } - - /** - * Sets additional codec settings. - * - * @param settings additional settings represented by a map. - */ - public void setAdditionalCodecSettings(Map settings) - { - codecSettings = settings; - } - - /** - * Returns additional codec settings. - * - * @return additional settings represented by a map. - */ - public Map getAdditionalCodecSettings() - { - return codecSettings; - } - - /** - * Returns a String representation of this MediaFormat - * containing, among other things, its encoding and clockrate values. - * - * @return a String representation of this MediaFormat. - */ - @Override - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("rtpmap:"); - str.append(getRTPPayloadType()); - str.append(' '); - str.append(getEncoding()); - str.append('/'); - str.append(getClockRateString()); - - /* - * If the number of channels is 1, it does not have to be mentioned - * because it is the default. - */ - if (MediaType.AUDIO.equals(getMediaType())) - { - int channels = ((AudioFormat) getFormat()).getChannels(); - - if (channels != 1) - { - str.append('/'); - str.append(channels); - } - } - - Map formatParameters = getFormatParameters(); - - if (!formatParameters.isEmpty()) - { - str.append(" fmtp:"); - - boolean prependSeparator = false; - - for (Map.Entry formatParameter - : formatParameters.entrySet()) - { - if (prependSeparator) - str.append(';'); - else - prependSeparator = true; - str.append(formatParameter.getKey()); - str.append('='); - str.append(formatParameter.getValue()); - } - } - - return str.toString(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/format/ParameterizedVideoFormat.java b/src/net/java/sip/communicator/impl/neomedia/format/ParameterizedVideoFormat.java deleted file mode 100644 index 390f69826..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/format/ParameterizedVideoFormat.java +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.format; - -import java.awt.*; -import java.util.*; - -import javax.media.*; -import javax.media.format.*; - -/** - * Implements a VideoFormat with format parameters (like - * {@link VideoMediaFormatImpl}) (some of) which (could) distinguish payload - * types. - * - * @author Lyubomir Marinov - */ -public class ParameterizedVideoFormat - extends VideoFormat -{ - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * The format parameters of this ParameterizedVideoFormat instance. - */ - private Map fmtps; - - /** - * Constructs a new ParametizedVideoFormat. - * - * @param encoding encoding - * @param size video size - * @param maxDataLength maximum data length - * @param dataType data type - * @param frameRate frame rate - * @param fmtps format parameters - */ - public ParameterizedVideoFormat( - String encoding, - Dimension size, - int maxDataLength, - Class dataType, - float frameRate, - Map fmtps) - { - super(encoding, size, maxDataLength, dataType, frameRate); - - this.fmtps - = ((fmtps == null) || fmtps.isEmpty()) - ? MediaFormatImpl.EMPTY_FORMAT_PARAMETERS - : new HashMap(fmtps); - } - - /** - * Initializes a new ParameterizedVideoFormat with a specific - * encoding and a specific set of format parameters. - * - * @param encoding the encoding of the new instance - * @param fmtps the format parameters of the new instance - */ - public ParameterizedVideoFormat(String encoding, Map fmtps) - { - super(encoding); - - this.fmtps - = ((fmtps == null) || fmtps.isEmpty()) - ? MediaFormatImpl.EMPTY_FORMAT_PARAMETERS - : new HashMap(fmtps); - } - - /** - * Initializes a new ParameterizedVideoFormat with a specific - * encoding and a specific set of format parameters. - * - * @param encoding the encoding of the new instance - * @param fmtps the format parameters of the new instance in the form of an - * array of Strings in which the key and the value of an - * association are expressed as consecutive elements. - */ - public ParameterizedVideoFormat(String encoding, String... fmtps) - { - this(encoding, toMap(fmtps)); - } - - /** - * Initializes a new ParameterizedVideoFormat instance which has - * the same properties as this instance. - * - * @return a new ParameterizedVideoFormat instance which has the - * same properties as this instance - */ - @Override - public Object clone() - { - ParameterizedVideoFormat f - = new ParameterizedVideoFormat( - getEncoding(), - getSize(), - getMaxDataLength(), - getDataType(), - getFrameRate(), - /* - * The formatParameters will be copied by - * ParameterizedVideoFormat#copy(Format) bellow. - */ - null); - - f.copy(this); - return f; - } - - /** - * Copies the properties of the specified Format into this - * instance. - * - * @param f the Format the properties of which are to be copied - * into this instance - */ - @Override - protected void copy(Format f) - { - super.copy(f); - - if (f instanceof ParameterizedVideoFormat) - { - ParameterizedVideoFormat pvf = (ParameterizedVideoFormat) f; - Map pvfFmtps = pvf.getFormatParameters(); - - fmtps - = ((pvfFmtps == null) || pvfFmtps.isEmpty()) - ? MediaFormatImpl.EMPTY_FORMAT_PARAMETERS - : new HashMap(pvfFmtps); - } - } - - /** - * Determines whether a specific Object represents a value that is - * equal to the value represented by this instance. - * - * @param obj the Object to be determined whether it represents a - * value that is equal to the value represented by this instance - * @return true if the specified obj represents a value - * that is equal to the value represented by this instance; otherwise, - * false - */ - @Override - public boolean equals(Object obj) - { - if (!super.equals(obj)) - return false; - - Map objFmtps = null; - - if (obj instanceof ParameterizedVideoFormat) - objFmtps = ((ParameterizedVideoFormat) obj).getFormatParameters(); - return - VideoMediaFormatImpl.formatParametersAreEqual( - getEncoding(), - getFormatParameters(), objFmtps); - } - - /** - * Returns whether or not the format parameters match. - * - * @param format format to test - * @return true if the format parameters match. - */ - public boolean formatParametersMatch(Format format) - { - Map formatFmtps = null; - - if (format instanceof ParameterizedVideoFormat) - formatFmtps - = ((ParameterizedVideoFormat) format).getFormatParameters(); - return - VideoMediaFormatImpl.formatParametersMatch( - getEncoding(), - getFormatParameters(), formatFmtps); - } - - /** - * Returns the format parameters value for the specified name. - * - * @param name format parameters name - * @return value for the specified format parameters name - */ - public String getFormatParameter(String name) - { - return fmtps.get(name); - } - - /** - * Returns the format parameters Map. - * - * @return the format parameters Map. - */ - public Map getFormatParameters() - { - return new HashMap(fmtps); - } - - /** - * Finds the attributes shared by two matching Formats. If the - * specified Format does not match this one, the result is - * undefined. - * - * @param format the matching Format to intersect with this one - * @return a Format with its attributes set to the attributes - * common to this instance and the specified format - */ - @Override - public Format intersects(Format format) - { - Format intersection = super.intersects(format); - - if (intersection == null) - return null; - - ((ParameterizedVideoFormat) intersection).fmtps - = fmtps.isEmpty() - ? MediaFormatImpl.EMPTY_FORMAT_PARAMETERS - : getFormatParameters(); - return intersection; - } - - /** - * Determines whether a specific format matches this instance i.e. whether - * their attributes match according to the definition of "match" given by - * {@link Format#matches(Format)}. - * - * @param format the Format to compare to this instance - * @return true if the specified format matches this one; - * otherwise, false - */ - @Override - public boolean matches(Format format) - { - return super.matches(format) && formatParametersMatch(format); - } - - /** - * Initializes a new Map from an array in which the key and the - * value of an association are expressed as consecutive elements. - * - * @param the very type of the keys and the values to be associated in - * the new Map - * @param entries the associations to be created in the new Map - * where the key and value of an association are expressed as consecutive - * elements - * @return a new Map with the associations specified by - * entries - */ - public static Map toMap(T... entries) - { - Map map; - - if ((entries == null) || (entries.length == 0)) - map = null; - else - { - map = new HashMap(); - for (int i = 0; i < entries.length; i++) - map.put(entries[i++], entries[i]); - } - return map; - } - - @Override - public String toString() - { - StringBuilder s = new StringBuilder(); - - s.append(super.toString()); - - // fmtps - { - s.append(", fmtps={"); - for (Map.Entry fmtp : fmtps.entrySet()) - { - s.append(fmtp.getKey()); - s.append('='); - s.append(fmtp.getValue()); - s.append(','); - } - - int lastIndex = s.length() - 1; - - if (s.charAt(lastIndex) == ',') - s.setCharAt(lastIndex, '}'); - else - s.append('}'); - } - return s.toString(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/format/VideoMediaFormatImpl.java b/src/net/java/sip/communicator/impl/neomedia/format/VideoMediaFormatImpl.java deleted file mode 100644 index b23186b4f..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/format/VideoMediaFormatImpl.java +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.format; - -import java.awt.*; -import java.util.*; - -import javax.media.format.*; - -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.format.*; - -/** - * Implements VideoMediaFormat for the JMF VideoFormat. - * - * @author Lyubomir Marinov - */ -public class VideoMediaFormatImpl - extends MediaFormatImpl - implements VideoMediaFormat -{ - - /** - * The default value of the clockRate property of - * VideoMediaFormatImpl. - */ - public static final double DEFAULT_CLOCK_RATE = 90000; - - /** - * The clock rate of this VideoMediaFormat. - */ - private final double clockRate; - - /** - * Initializes a new VideoMediaFormatImpl instance with a specific - * encoding. - * - * @param encoding the encoding of the new VideoMediaFormatImpl - * instance - */ - VideoMediaFormatImpl(String encoding) - { - this(encoding, DEFAULT_CLOCK_RATE); - } - - /** - * Initializes a new VideoMediaFormatImpl instance with a specific - * encoding and a specific clock rate. - * - * @param encoding the encoding of the new VideoMediaFormatImpl - * instance - * @param clockRate the clock rate of the new VideoMediaFormatImpl - * instance - */ - VideoMediaFormatImpl(String encoding, double clockRate) - { - this(new VideoFormat(encoding), clockRate); - } - - /** - * Initializes a new VideoMediaFormatImpl instance which is to - * provide an implementation of VideoMediaFormat for a specific - * JMF VideoFormat. - * - * @param format the JMF VideoFormat the new instance is to wrap - * and provide an implementation of VideoMediaFormat for - */ - VideoMediaFormatImpl(VideoFormat format) - { - this(format, DEFAULT_CLOCK_RATE); - } - - /** - * Initializes a new VideoMediaFormatImpl instance which is to - * provide an implementation of VideoMediaFormat for a specific - * JMF VideoFormat and to have a specific clock rate. - * - * @param format the JMF VideoFormat the new instance is to wrap - * and provide an implementation of VideoMediaFormat for - * @param clockRate the clock rate of the new VideoMediaFormatImpl - * instance - */ - VideoMediaFormatImpl(VideoFormat format, double clockRate) - { - this(format, clockRate, -1, null, null); - } - - /** - * Initializes a new VideoMediaFormatImpl instance which is to - * provide an implementation of VideoMediaFormat for a specific - * JMF VideoFormat and to have specific clock rate and set of - * format-specific parameters. - * - * @param format the JMF VideoFormat the new instance is to wrap - * and provide an implementation of VideoMediaFormat for - * @param clockRate the clock rate of the new VideoMediaFormatImpl - * instance - * @param frameRate the frame rate of the new VideoMediaFormatImpl - * instance - * @param formatParameters the set of format-specific parameters of the new - * instance - * @param advancedParameters set of advanced parameters of the new instance - */ - VideoMediaFormatImpl( - VideoFormat format, - double clockRate, - float frameRate, - Map formatParameters, - Map advancedParameters) - { - super( - new ParameterizedVideoFormat( - format.getEncoding(), - format.getSize(), - format.getMaxDataLength(), - format.getDataType(), - frameRate, - formatParameters), - formatParameters, - advancedParameters); - - this.clockRate = clockRate; - } - - /** - * Implements MediaFormat#equals(Object) and actually compares the - * encapsulated JMF Format instances. - * - * @param mediaFormat the object that we'd like to compare this one - * to - * @return true if the JMF Format instances encapsulated - * by this instance and their other characteristics are equal; - * false, otherwise. - * @see MediaFormatImpl#equals(Object) - */ - @Override - public boolean equals(Object mediaFormat) - { - if (this == mediaFormat) - return true; - - if (!super.equals(mediaFormat)) - return false; - - VideoMediaFormatImpl videoMediaFormatImpl - = (VideoMediaFormatImpl) mediaFormat; - - double clockRate = getClockRate(); - double videoMediaFormatImplClockRate - = videoMediaFormatImpl.getClockRate(); - - if (MediaFormatFactory.CLOCK_RATE_NOT_SPECIFIED == clockRate) - clockRate = DEFAULT_CLOCK_RATE; - if (MediaFormatFactory.CLOCK_RATE_NOT_SPECIFIED - == videoMediaFormatImplClockRate) - videoMediaFormatImplClockRate = DEFAULT_CLOCK_RATE; - - return (clockRate == videoMediaFormatImplClockRate); - } - - /** - * {@inheritDoc} - *

- * Takes into account RFC 3984 "RTP Payload Format for H.264 Video" which - * says that "[w]hen the value of packetization-mode [format parameter] - * is equal to 0 or packetization-mode is not present, the single NAL mode, - * as defined in section 6.2 of RFC 3984, MUST be used." - *

- * - * @see MediaFormatImpl#formatParametersAreEqual(Map, Map) - */ - @Override - protected boolean formatParametersAreEqual( - Map fmtps1, - Map fmtps2) - { - return formatParametersAreEqual(getEncoding(), fmtps1, fmtps2); - } - - /** - * Determines whether a specific set of format parameters is equal to - * another set of format parameters in the sense that they define an equal - * number of parameters and assign them equal values. Since the values are - * Strings, presumes that a value of null is equal to the - * empty String. - *

- * The two Map instances of format parameters to be checked for - * equality are presumed to be modifiable in the sense that if the lack of a - * format parameter in a given Map is equivalent to it having a - * specific value, an association of the format parameter to the value in - * question may be added to or removed from the respective Map - * instance for the purposes of determining equality. - *

- * - * @param encoding the encoding (name) related to the two sets of format - * parameters to be tested for equality - * @param fmtps1 the first set of format parameters to be tested for - * equality - * @param fmtps2 the second set of format parameters to be tested for - * equality - * @return true if the specified sets of format parameters are - * equal; false, otherwise - */ - public static boolean formatParametersAreEqual( - String encoding, - Map fmtps1, Map fmtps2) - { - /* - * RFC 3984 "RTP Payload Format for H.264 Video" says that "[w]hen the - * value of packetization-mode is equal to 0 or packetization-mode is - * not present, the single NAL mode, as defined in section 6.2 of RFC - * 3984, MUST be used." - */ - if ("H264".equalsIgnoreCase(encoding) - || "h264/rtp".equalsIgnoreCase(encoding)) - { - String packetizationMode = "packetization-mode"; - String pm1 = null; - String pm2 = null; - - if (fmtps1 != null) - pm1 = fmtps1.remove(packetizationMode); - if (fmtps2 != null) - pm2 = fmtps2.remove(packetizationMode); - - if (pm1 == null) - pm1 = "0"; - if (pm2 == null) - pm2 = "0"; - if (!pm1.equals(pm2)) - return false; - } - - return - MediaFormatImpl.formatParametersAreEqual(encoding, fmtps1, fmtps2); - } - - /** - * Determines whether the format parameters of this MediaFormat - * match a specific set of format parameters. - *

- * VideoMediaFormat reflects the fact that the - * packetization-mode format parameter distinguishes H.264 payload - * types. - *

- * - * @param fmtps the set of format parameters to match to the format - * parameters of this MediaFormat - * @return true if this MediaFormat considers - * fmtps matching its format parameters; otherwise, false - */ - @Override - public boolean formatParametersMatch(Map fmtps) - { - return - formatParametersMatch(getEncoding(), getFormatParameters(), fmtps) - && super.formatParametersMatch(fmtps); - } - - /** - * Determines whether two sets of format parameters match in the context of - * a specific encoding. - * - * @param encoding the encoding (name) related to the two sets of format - * parameters to be matched. - * @param fmtps1 the first set of format parameters which is to be matched - * against fmtps2 - * @param fmtps2 the second set of format parameters which is to be matched - * against fmtps1 - * @return true if the two sets of format parameters match in the - * context of the specified encoding; otherwise, false - */ - public static boolean formatParametersMatch( - String encoding, - Map fmtps1 , Map fmtps2) - { - /* - * RFC 3984 "RTP Payload Format for H.264 Video" says that "[w]hen the - * value of packetization-mode is equal to 0 or packetization-mode is - * not present, the single NAL mode, as defined in section 6.2 of RFC - * 3984, MUST be used." - */ - if ("H264".equalsIgnoreCase(encoding) - || "h264/rtp".equalsIgnoreCase(encoding)) - { - String packetizationMode = "packetization-mode"; - String pm1 - = (fmtps1 == null) ? null : fmtps1.get(packetizationMode); - String pm2 - = (fmtps2 == null) ? null : fmtps2.get(packetizationMode); - - if (pm1 == null) - pm1 = "0"; - if (pm2 == null) - pm2 = "0"; - if (!pm1.equals(pm2)) - return false; - } - - return true; - } - - /** - * Gets the clock rate associated with this MediaFormat. - * - * @return the clock rate associated with this MediaFormat - * @see MediaFormat#getClockRate() - */ - public double getClockRate() - { - return clockRate; - } - - /** - * Gets the frame rate associated with this MediaFormat. - * - * @return the frame rate associated with this MediaFormat - * @see VideoMediaFormat#getFrameRate() - */ - public float getFrameRate() - { - return format.getFrameRate(); - } - - /** - * Gets the type of this MediaFormat which is - * {@link MediaType#VIDEO} for AudioMediaFormatImpl instances. - * - * @return the MediaType that this format represents and which is - * MediaType.VIDEO for AudioMediaFormatImpl instances - * @see MediaFormat#getMediaType() - */ - public final MediaType getMediaType() - { - return MediaType.VIDEO; - } - - /** - * Gets the size of the image that this VideoMediaFormat describes. - * - * @return a {@link Dimension} instance indicating the image size (in - * pixels) of this VideoMediaFormat - * @see VideoMediaFormat#getSize() - */ - public Dimension getSize() - { - return format.getSize(); - } - - /** - * Overrides MediaFormatImpl#hashCode() because - * Object#equals(Object) is overridden. - * - * @return a hash code value for this VideoMediaFormatImpl - * @see MediaFormatImpl#hashCode() - */ - @Override - public int hashCode() - { - double clockRate = getClockRate(); - - /* - * The implementation of #equals(Object) of this instance assumes that - * MediaFormatFactory#CLOCK_RATE_NOT_SPECIFIED and #DEFAULT_CLOCK_RATE - * are equal. - */ - if (MediaFormatFactory.CLOCK_RATE_NOT_SPECIFIED == clockRate) - clockRate = DEFAULT_CLOCK_RATE; - return (super.hashCode() | Double.valueOf(clockRate).hashCode()); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteract.java b/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteract.java deleted file mode 100644 index 45d3b2226..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteract.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.imgstreaming; - -import java.awt.image.*; - -/** - * Interface to capture desktop screen. - * - * @author Sebastien Vincent - */ -public interface DesktopInteract -{ - /** - * Capture the full desktop screen using native grabber. - * - * Contrary to other captureScreen method, it only returns raw bytes - * and not BufferedImage. It is done in order to limit - * slow operation such as converting ARGB images (uint32_t) to bytes - * especially for big big screen. For example a 1920x1200 desktop consumes - * 9 MB of memory for grabbing and another 9 MB array for conversion - * operation. - * - * @param display index of display - * @param output output buffer to store bytes in. - * Be sure that output length is sufficient - * @return true if success, false if JNI error or output length too short - */ - public boolean captureScreen(int display, byte output[]); - - /** - * Capture the full desktop screen using native grabber. - * - * Contrary to other captureScreen method, it only returns raw bytes - * and not BufferedImage. It is done in order to limit - * slow operation such as converting ARGB images (uint32_t) to bytes - * especially for big big screen. For example a 1920x1200 desktop consumes - * 9 MB of memory for grabbing and another 9 MB array for conversion - * operation. - * - * @param display index of display - * @param buffer native output buffer to store bytes in. - * Be sure that output length is sufficient - * @param bufferLength length of native buffer - * @return true if success, false if JNI error or output length too short - */ - public boolean captureScreen(int display, long buffer, int bufferLength); - - /** - * Capture a part of the desktop screen using native grabber. - * - * Contrary to other captureScreen method, it only returns raw bytes - * and not BufferedImage. It is done in order to limit - * slow operation such as converting ARGB images (uint32_t) to bytes - * especially for big big screen. For example a 1920x1200 desktop consumes - * 9 MB of memory for grabbing and another 9 MB array for conversion - * operation. - * - * @param display index of display - * @param x x position to start capture - * @param y y position to start capture - * @param width capture width - * @param height capture height - * @param output output buffer to store bytes in. - * Be sure that output length is sufficient - * @return true if success, false if JNI error or output length too short - */ - public boolean captureScreen(int display, int x, int y, int width, - int height, byte output[]); - - /** - * Capture a part of the desktop screen using native grabber. - * - * Contrary to other captureScreen method, it only returns raw bytes - * and not BufferedImage. It is done in order to limit - * slow operation such as converting ARGB images (uint32_t) to bytes - * especially for big big screen. For example a 1920x1200 desktop consumes - * 9 MB of memory for grabbing and another 9 MB array for conversion - * operation. - * - * @param display index of display - * @param x x position to start capture - * @param y y position to start capture - * @param width capture width - * @param height capture height - * @param buffer native output buffer to store bytes in. - * Be sure that output length is sufficient - * @param bufferLength length of native buffer - * @return true if success, false if JNI error or output length too short - */ - public boolean captureScreen(int display, int x, int y, int width, - int height, long buffer, int bufferLength); - - /** - * Capture the full desktop screen. - * - * @return BufferedImage of the desktop screen - */ - public BufferedImage captureScreen(); - - /** - * Capture a part of the desktop screen. - * - * @param x x position to start capture - * @param y y position to start capture - * @param width capture width - * @param height capture height - * @return BufferedImage of a part of the desktop screen - * or null if Robot problem - */ - public BufferedImage captureScreen(int x, int y, int width, int height); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteractImpl.java b/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteractImpl.java deleted file mode 100644 index c5f89ae0e..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteractImpl.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.imgstreaming; - -import java.awt.*; -import java.awt.image.*; - -import net.java.sip.communicator.util.*; - -/** - * Capture desktop screen either via native code (JNI) if available or by using - * java.awt.Robot. - * - * @see java.awt.Robot - * @author Sebastien Vincent - */ -public class DesktopInteractImpl implements DesktopInteract -{ - /** - * The Logger. - */ - private static final Logger logger = - Logger.getLogger(DesktopInteractImpl.class); - - /** - * Screen capture robot. - */ - private Robot robot = null; - - /** - * Constructor. - * - * @throws AWTException if platform configuration does not allow low-level - * input control - * @throws SecurityException if Robot creation is not permitted - */ - public DesktopInteractImpl() throws AWTException, SecurityException - { - robot = new Robot(); - } - - /** - * Capture the full desktop screen using native grabber. - * - * Contrary to other captureScreen method, it only returns raw bytes - * and not BufferedImage. It is done in order to limit - * slow operation such as converting ARGB images (uint32_t) to bytes - * especially for big big screen. For example a 1920x1200 desktop consumes - * 9 MB of memory for grabbing and another 9 MB array for conversion - * operation. - * - * @param display index of display - * @param output output buffer to store bytes in. - * Be sure that output length is sufficient - * @return true if success, false if JNI error or output length too short - */ - public boolean captureScreen(int display, byte output[]) - { - Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); - - return captureScreen(display, 0, 0, dim.width, dim.height, output); - } - - /** - * Capture the full desktop screen using native grabber. - * - * Contrary to other captureScreen method, it only returns raw bytes - * and not BufferedImage. It is done in order to limit - * slow operation such as converting ARGB images (uint32_t) to bytes - * especially for big big screen. For example a 1920x1200 desktop consumes - * 9 MB of memory for grabbing and another 9 MB array for conversion - * operation. - * - * @param display index of display - * @param buffer native output buffer to store bytes in. - * Be sure that output length is sufficient - * @param bufferLength length of native buffer - * @return true if success, false if JNI error or output length too short - */ - public boolean captureScreen(int display, long buffer, int bufferLength) - { - Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); - return captureScreen(display, 0, 0, dim.width, dim.height, buffer, - bufferLength); - } - - /** - * Capture a part of the desktop screen using native grabber. - * - * Contrary to other captureScreen method, it only returns raw bytes - * and not BufferedImage. It is done in order to limit - * slow operation such as converting ARGB images (uint32_t) to bytes - * especially for big big screen. For example a 1920x1200 desktop consumes - * 9 MB of memory for grabbing and another 9 MB array for conversion - * operation. - * - * @param display index of display - * @param x x position to start capture - * @param y y position to start capture - * @param width capture width - * @param height capture height - * @param output output buffer to store bytes in. - * Be sure that output length is sufficient - * @return true if success, false if JNI error or output length too short - */ - public boolean captureScreen(int display, int x, int y, int width, - int height, byte output[]) - { - if(OSUtils.IS_LINUX || OSUtils.IS_FREEBSD || OSUtils.IS_WINDOWS - || OSUtils.IS_MAC) - { - return NativeScreenCapture.grabScreen( - display, x, y, width, height, output); - } - - return false; - } - - /** - * Capture a part of the desktop screen using native grabber. - * - * Contrary to other captureScreen method, it only returns raw bytes - * and not BufferedImage. It is done in order to limit - * slow operation such as converting ARGB images (uint32_t) to bytes - * especially for big big screen. For example a 1920x1200 desktop consumes - * 9 MB of memory for grabbing and another 9 MB array for conversion - * operation. - * - * @param display index of display - * @param x x position to start capture - * @param y y position to start capture - * @param width capture width - * @param height capture height - * @param buffer native output buffer to store bytes in. - * Be sure that output length is sufficient - * @param bufferLength length of native buffer - * @return true if success, false if JNI error or output length too short - */ - public boolean captureScreen(int display, int x, int y, int width, - int height, long buffer, int bufferLength) - { - if(OSUtils.IS_LINUX || OSUtils.IS_FREEBSD || OSUtils.IS_WINDOWS - || OSUtils.IS_MAC) - { - return NativeScreenCapture.grabScreen( - display, x, y, width, height, buffer, bufferLength); - } - - return false; - } - - /** - * Capture the full desktop screen using java.awt.Robot. - * - * @return BufferedImage of the desktop screen - */ - public BufferedImage captureScreen() - { - Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); - - return captureScreen(0, 0, dim.width, dim.height); - } - - /** - * Capture a part of the desktop screen using java.awt.Robot. - * - * @param x x position to start capture - * @param y y position to start capture - * @param width capture width - * @param height capture height - * @return BufferedImage of a part of the desktop screen - * or null if Robot problem - */ - public BufferedImage captureScreen(int x, int y, int width, int height) - { - BufferedImage img = null; - Rectangle rect = null; - - if(robot == null) - { - /* Robot has not been created so abort */ - return null; - } - - if (logger.isInfoEnabled()) - logger.info("Begin capture: " + System.nanoTime()); - rect = new Rectangle(x, y, width, height); - img = robot.createScreenCapture(rect); - if (logger.isInfoEnabled()) - logger.info("End capture: " + System.nanoTime()); - - return img; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/imgstreaming/ImageStreamingUtils.java b/src/net/java/sip/communicator/impl/neomedia/imgstreaming/ImageStreamingUtils.java deleted file mode 100644 index 00afdf6ab..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/imgstreaming/ImageStreamingUtils.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.imgstreaming; - -import java.awt.geom.*; -import java.awt.image.*; - -/** - * This class provides utility functions and fields for image streaming. - * - * @author Sebastien Vincent - */ -public class ImageStreamingUtils -{ - /** - * Get a scaled BufferedImage. - * - * Mainly inspired by: - * http://java.developpez.com/faq/gui/?page=graphique_general_images - * #GRAPHIQUE_IMAGE_redimensionner - * - * @param src source image - * @param width width of scaled image - * @param height height of scaled image - * @param type BufferedImage type - * @return scaled BufferedImage - */ - public static BufferedImage getScaledImage(BufferedImage src, - int width, - int height, - int type) - { - double scaleWidth = width / ((double)src.getWidth()); - double scaleHeight = height / ((double)src.getHeight()); - AffineTransform tx = new AffineTransform(); - - // Skip rescaling if input and output size are the same. - if ((Double.compare(scaleWidth, 1) != 0) - || (Double.compare(scaleHeight, 1) != 0)) - tx.scale(scaleWidth, scaleHeight); - - AffineTransformOp op - = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR); - BufferedImage dst = new BufferedImage(width, height, type); - - return op.filter(src, dst); - } - - /** - * Get raw bytes from ARGB BufferedImage. - * - * @param src ARGB - * @param output output buffer, if not null and if its length is at least - * image's (width * height) * 4, method will put bytes in it. - * @return raw bytes or null if src is not an ARGB - * BufferedImage - */ - public static byte[] getImageBytes(BufferedImage src, byte output[]) - { - if(src.getType() != BufferedImage.TYPE_INT_ARGB) - throw new IllegalArgumentException("src.type"); - - WritableRaster raster = src.getRaster(); - int width = src.getWidth(); - int height = src.getHeight(); - int size = width * height * 4; - int off = 0; - int pixel[] = new int[4]; - byte data[] = null; - - if(output == null || output.length < size) - { - /* allocate our bytes array */ - data = new byte[size]; - } - else - { - /* use output */ - data = output; - } - - for(int y = 0 ; y < height ; y++) - for(int x = 0 ; x < width ; x++) - { - raster.getPixel(x, y, pixel); - data[off++] = (byte)pixel[0]; - data[off++] = (byte)pixel[1]; - data[off++] = (byte)pixel[2]; - data[off++] = (byte)pixel[3]; - } - - return data; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/imgstreaming/NativeScreenCapture.java b/src/net/java/sip/communicator/impl/neomedia/imgstreaming/NativeScreenCapture.java deleted file mode 100644 index ce3d9c529..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/imgstreaming/NativeScreenCapture.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.imgstreaming; - -/** - * This class uses native code to capture desktop screen. - * - * It should work for Windows, Mac OS X and X11-based Unix such as Linux - * and FreeBSD. - * - * @author Sebastien Vincent - */ -public class NativeScreenCapture -{ - static - { - System.loadLibrary("jnscreencapture"); - } - - /** - * Grab desktop screen and get raw bytes. - * - * @param display index of display - * @param x x position to start capture - * @param y y position to start capture - * @param width capture width - * @param height capture height - * @param output output buffer to store screen bytes - * @return true if grab success, false otherwise - */ - public static native boolean grabScreen(int display, int x, int y, - int width, int height, byte output[]); - - /** - * Grab desktop screen and get raw bytes. - * - * @param display index of display - * @param x x position to start capture - * @param y y position to start capture - * @param width capture width - * @param height capture height - * @param output native output buffer to store screen bytes - * @param outputLength native output length - * @return true if grab success, false otherwise - */ - public static native boolean grabScreen(int display, int x, int y, - int width, int height, long output, int outputLength); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractBufferCaptureDevice.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractBufferCaptureDevice.java deleted file mode 100644 index 1e31b5583..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractBufferCaptureDevice.java +++ /dev/null @@ -1,873 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol; - -import java.io.*; -import java.lang.reflect.*; -import java.util.*; - -import javax.media.*; -import javax.media.Controls; // disambiguation -import javax.media.control.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.control.*; -import net.java.sip.communicator.util.*; - -import net.sf.fmj.media.util.*; - -/** - * Facilitates the implementations of the CaptureDevice and - * DataSource interfaces provided by - * AbstractPullBufferCaptureDevice and - * AbstractPushBufferCaptureDevice. - * - * @param the type of AbstractBufferStream - * through which this AbstractBufferCaptureDevice is to give access to - * its media data - * - * @author Lyubomir Marinov - */ -public abstract class AbstractBufferCaptureDevice - - implements CaptureDevice, - Controls -{ - /** - * The Logger used by the AbstractBufferCaptureDevice - * class and its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(AbstractBufferCaptureDevice.class); - - /** - * The value of the formatControls property of - * AbstractBufferCaptureDevice which represents an empty array of - * FormatControls. Explicitly defined in order to reduce - * unnecessary allocations. - */ - private static final FormatControl[] EMPTY_FORMAT_CONTROLS - = new FormatControl[0]; - - /** - * The indicator which determines whether a connection to the media source - * specified by the MediaLocator of this DataSource has - * been opened. - */ - private boolean connected = false; - - /** - * The array of FormatControl instances each one of which can be - * used before {@link #connect()} to get and set the capture Format - * of each one of the capture streams. - */ - private FormatControl[] formatControls; - - /** - * The FrameRateControls of this - * AbstractBufferCaptureDevice. - */ - private FrameRateControl[] frameRateControls; - - /** - * The RTPInfos of this AbstractBufferCaptureDevice. - */ - private RTPInfo[] rtpInfos; - - /** - * The indicator which determines whether the transfer of media data from - * this DataSource has been started. - */ - private boolean started = false; - - /** - * The PushBufferStreams through which this - * PushBufferDataSource gives access to its media data. - *

- * Warning: Caution is advised when directly using the field and access to - * it is to be synchronized with sync root this. - *

- */ - private AbstractBufferStream[] streams; - - /** - * Opens a connection to the media source of this - * AbstractBufferCaptureDevice. - * - * @throws IOException if anything goes wrong while opening the connection - * to the media source of this AbstractBufferCaptureDevice - */ - public synchronized void connect() - throws IOException - { - if (!connected) - { - doConnect(); - connected = true; - } - } - - /** - * Creates a new FormatControl instance which is to be associated - * with a PushBufferStream at a specific zero-based index in the - * list of streams of this PushBufferDataSource. As the - * FormatControls of a PushBufferDataSource can be - * requested before {@link #connect()}, its PushBufferStreams may - * not exist at the time of the request for the creation of the - * FormatControl. - * - * @param streamIndex the zero-based index of the PushBufferStream - * in the list of streams of this PushBufferDataSource which is to - * be associated with the new FormatControl instance - * @return a new FormatControl instance which is to be associated - * with a PushBufferStream at the specified streamIndex in - * the list of streams of this PushBufferDataSource - */ - protected FormatControl createFormatControl(final int streamIndex) - { - return - new AbstractFormatControl() - { - /** - * The Format of this FormatControl and, - * respectively, of the media data of its owner. - */ - private Format format; - - /** - * Gets the Format of the media data of the owner of - * this FormatControl. - * - * @return the Format of the media data of the owner of - * this FormatControl - */ - public Format getFormat() - { - format - = AbstractBufferCaptureDevice.this.internalGetFormat( - streamIndex, - format); - return format; - } - - /** - * Gets the Formats in which the owner of this - * FormatControl is capable of providing media data. - * - * @return an array of Formats in which the owner of - * this FormatControl is capable of providing media - * data - */ - public Format[] getSupportedFormats() - { - return - AbstractBufferCaptureDevice.this.getSupportedFormats( - streamIndex); - } - - /** - * Implements {@link FormatControl#setFormat(Format)}. Attempts - * to set the Format in which the owner of this - * FormatControl is to provide media data. - * - * @param format the Format to be set on this instance - * @return the currently set Format after the attempt - * to set it on this instance if format is supported by - * this instance and regardless of whether it was actually set; - * null if format is not supported by this - * instance - */ - @Override - public Format setFormat(Format format) - { - Format setFormat = super.setFormat(format); - - if (setFormat != null) - { - setFormat - = AbstractBufferCaptureDevice.this - .internalSetFormat( - streamIndex, - setFormat, - format); - if (setFormat != null) - this.format = setFormat; - } - return setFormat; - } - }; - } - - /** - * Creates the FormatControls of this CaptureDevice. - * - * @return an array of the FormatControls of this - * CaptureDevice - */ - protected FormatControl[] createFormatControls() - { - FormatControl formatControl = createFormatControl(0); - - return - (formatControl == null) - ? EMPTY_FORMAT_CONTROLS - : new FormatControl[] { formatControl }; - } - - /** - * Creates a new FrameRateControl instance which is to allow the - * getting and setting of the frame rate of this - * AbstractBufferCaptureDevice. - * - * @return a new FrameRateControl instance which is to allow the - * getting and setting of the frame rate of this - * AbstractBufferCaptureDevice - */ - protected FrameRateControl createFrameRateControl() - { - return null; - } - - /** - * Creates a new RTPInfo instance of this - * AbstractBufferCaptureDevice. - * - * @return a new RTPInfo instance of this - * AbstractBufferCaptureDevice - */ - protected RTPInfo createRTPInfo() - { - return - new RTPInfo() - { - public String getCNAME() - { - // TODO Auto-generated method stub - return null; - } - }; - } - - /** - * Create a new AbstractBufferStream which is to be at a specific - * zero-based index in the list of streams of this - * AbstractBufferCaptureDevice. The Format-related - * information of the new instance is to be abstracted by a specific - * FormatControl. - * - * @param streamIndex the zero-based index of the - * AbstractBufferStream in the list of streams of this - * AbstractBufferCaptureDevice - * @param formatControl the FormatControl which is to abstract the - * Format-related information of the new instance - * @return a new AbstractBufferStream which is to be at the - * specified streamIndex in the list of streams of this - * AbstractBufferCaptureDevice and which has its - * Format-related information abstracted by the specified - * formatControl - */ - protected abstract AbstractBufferStreamT createStream( - int streamIndex, - FormatControl formatControl); - - /** - * Provides the default implementation of - * AbstractBufferCaptureDevice for {@link #doStart()}. - * - * @throws IOException if anything goes wrong while starting the transfer of - * media data from this AbstractBufferCaptureDevice - * @see #doStart() - */ - final void defaultDoStart() - throws IOException - { - if (streams != null) - for (AbstractBufferStream stream : streams) - stream.start(); - } - - /** - * Provides the default implementation of - * AbstractBufferCaptureDevice for {@link #doStop()}. - * - * @throws IOException if anything goes wrong while stopping the transfer of - * media data from this AbstractBufferCaptureDevice - * @see #doStop() - */ - final void defaultDoStop() - throws IOException - { - if (streams != null) - for (AbstractBufferStream stream : streams) - stream.stop(); - } - - /** - * Provides the default implementation of - * AbstractBufferCaptureDevice for {@link #getControls()}. - * - * @return an array of Objects which represent the controls - * available for this instance - */ - final Object[] defaultGetControls() - { - FormatControl[] formatControls = internalGetFormatControls(); - int formatControlCount - = (formatControls == null) ? 0 : formatControls.length; - FrameRateControl[] frameRateControls = internalGetFrameRateControls(); - int frameRateControlCount - = (frameRateControls == null) ? 0 : frameRateControls.length; - RTPInfo[] rtpInfos = internalGetRTPInfos(); - int rtpInfoCount = (rtpInfos == null) ? 0 : rtpInfos.length; - - if ((formatControlCount == 0) - && (frameRateControlCount == 0) - && (rtpInfoCount == 0)) - return ControlsAdapter.EMPTY_CONTROLS; - else - { - Object[] controls - = new Object[ - formatControlCount - + frameRateControlCount - + rtpInfoCount]; - int offset = 0; - - if (formatControlCount != 0) - { - System.arraycopy( - formatControls, 0, - controls, offset, - formatControlCount); - offset += formatControlCount; - } - if (frameRateControlCount != 0) - { - System.arraycopy( - frameRateControls, 0, - controls, offset, - frameRateControlCount); - offset += frameRateControlCount; - } - if (rtpInfoCount != 0) - { - System.arraycopy(rtpInfos, 0, controls, offset, rtpInfoCount); - offset += rtpInfoCount; - } - return controls; - } - } - - /** - * Provides the default implementation of - * AbstractBufferCaptureDevice for {@link #getFormat(int, Format)}. - * - * @param streamIndex the zero-based index of the - * AbstractBufferStream the Format of which is to be - * retrieved - * @param oldValue the last-known Format for the - * AbstractBufferStream at the specified streamIndex - * @return the Format to be reported by the FormatControl - * of the AbstractBufferStream at the specified - * streamIndex in the list of streams of this - * AbstractBufferCaptureDevice - * @see #getFormat(int, Format) - */ - final Format defaultGetFormat(int streamIndex, Format oldValue) - { - if (oldValue != null) - return oldValue; - - Format[] supportedFormats = getSupportedFormats(streamIndex); - - return - ((supportedFormats == null) || (supportedFormats.length < 1)) - ? null - : supportedFormats[0]; - } - - /** - * Provides the default implementation of - * AbstractBufferCaptureDevice for - * {@link #getSupportedFormats(int)}. - * - * @param streamIndex the zero-based index of the - * AbstractBufferStream for which the specified - * FormatControl is to report the list of supported - * Formats - * @return an array of Formats to be reported by a - * FormatControl as the supported formats for the - * AbstractBufferStream at the specified streamIndex in - * the list of streams of this AbstractBufferCaptureDevice - */ - final Format[] defaultGetSupportedFormats(int streamIndex) - { - CaptureDeviceInfo captureDeviceInfo = getCaptureDeviceInfo(); - - return - (captureDeviceInfo == null) ? null : captureDeviceInfo.getFormats(); - } - - /** - * Closes the connection to the media source specified of this - * AbstractBufferCaptureDevice. If such a connection has not been - * opened, the call is ignored. - */ - public synchronized void disconnect() - { - try - { - stop(); - } - catch (IOException ioex) - { - logger.error("Failed to stop " + getClass().getSimpleName(), ioex); - } - - if (connected) - { - doDisconnect(); - connected = false; - } - } - - /** - * Opens a connection to the media source of this - * AbstractBufferCaptureDevice. Allows extenders to override and be - * sure that there will be no request to open a connection if the connection - * has already been opened. - * - * @throws IOException if anything goes wrong while opening the connection - * to the media source of this AbstractBufferCaptureDevice - */ - protected abstract void doConnect() - throws IOException; - - /** - * Closes the connection to the media source of this - * AbstractBufferCaptureDevice. Allows extenders to override and be - * sure that there will be no request to close a connection if the - * connection has not been opened yet. - */ - protected abstract void doDisconnect(); - - /** - * Starts the transfer of media data from this - * AbstractBufferCaptureDevice. Allows extenders to override and be - * sure that there will be no request to start the transfer of media data if - * it has already been started. - * - * @throws IOException if anything goes wrong while starting the transfer of - * media data from this AbstractBufferCaptureDevice - */ - protected abstract void doStart() - throws IOException; - - /** - * Stops the transfer of media data from this - * AbstractBufferCaptureDevice. Allows extenders to override and be - * sure that there will be no request to stop the transfer of media data if - * it has not been started yet. - * - * @throws IOException if anything goes wrong while stopping the transfer of - * media data from this AbstractBufferCaptureDevice - */ - protected abstract void doStop() - throws IOException; - - /** - * Gets the CaptureDeviceInfo of this CaptureDevice which - * describes it. - * - * @return the CaptureDeviceInfo of this CaptureDevice - * which describes it - */ - public abstract CaptureDeviceInfo getCaptureDeviceInfo(); - - /** - * Gets the CaptureDeviceInfo of a specific CaptureDevice - * by locating its registration in JMF using its MediaLocator. - * - * @param captureDevice the CaptureDevice to gets the - * CaptureDeviceInfo of - * @return the CaptureDeviceInfo of the specified - * CaptureDevice as registered in JMF - */ - public static CaptureDeviceInfo getCaptureDeviceInfo( - DataSource captureDevice) - { - /* - * TODO The implemented search for the CaptureDeviceInfo of this - * CaptureDevice by looking for its MediaLocator is inefficient. - */ - @SuppressWarnings("unchecked") - Vector captureDeviceInfos - = (Vector) - CaptureDeviceManager.getDeviceList(null); - MediaLocator locator = captureDevice.getLocator(); - - for (CaptureDeviceInfo captureDeviceInfo : captureDeviceInfos) - if (captureDeviceInfo.getLocator().toString().equals( - locator.toString())) - return captureDeviceInfo; - return null; - } - - /** - * Gets the control of the specified type available for this instance. - * - * @param controlType the type of the control available for this instance to - * be retrieved - * @return an Object which represents the control of the specified - * type available for this instance if such a control is indeed available; - * otherwise, null - */ - public Object getControl(String controlType) - { - return AbstractControls.getControl(this, controlType); - } - - /** - * Implements {@link javax.media.Controls#getControls()}. Gets the controls - * available for this instance. - * - * @return an array of Objects which represent the controls - * available for this instance - */ - public Object[] getControls() - { - return defaultGetControls(); - } - - /** - * Gets the Format to be reported by the FormatControl of - * an AbstractBufferStream at a specific zero-based index in the - * list of streams of this AbstractBufferCaptureDevice. The - * AbstractBufferStream may not exist at the time of requesting its - * Format. Allows extenders to override the default behavior which - * is to report any last-known format or the first Format from the - * list of supported formats as defined in the JMF registration of this - * CaptureDevice. - * - * @param streamIndex the zero-based index of the - * AbstractBufferStream the Format of which is to be - * retrieved - * @param oldValue the last-known Format for the - * PushBufferStream at the specified streamIndex - * @return the Format to be reported by the FormatControl - * of the PushBufferStream at the specified streamIndex in - * the list of streams of this PushBufferDataSource. - */ - protected abstract Format getFormat(int streamIndex, Format oldValue); - - /** - * Gets an array of FormatControl instances each one of which can - * be used before {@link #connect()} to get and set the capture - * Format of each one of the capture streams. - * - * @return an array of FormatControl instances each one of which - * can be used before {@link #connect()} to get and set the capture - * Format of each one of the capture streams - */ - public FormatControl[] getFormatControls() - { - return AbstractFormatControl.getFormatControls(this); - } - - /** - * Gets the Object which is to synchronize the access to - * {@link #streams()} and its return value. - * - * @return the Object which is to synchronize the access to - * {@link #streams()} and its return value - */ - Object getStreamSyncRoot() - { - return this; - } - - /** - * Gets the AbstractBufferStreams through which this - * AbstractBufferCaptureDevice gives access to its media data. - * - * @param the type of SourceStream which is to be - * the element type of the returned array - * @param clz the Class of SourceStream which is to be the - * element type of the returned array - * @return an array of the SourceStreams through which this - * AbstractBufferCaptureDevice gives access to its media data - */ - public synchronized - - SourceStreamT[] getStreams(Class clz) - { - if (streams == null) - { - FormatControl[] formatControls = internalGetFormatControls(); - - if (formatControls != null) - { - int formatControlCount = formatControls.length; - - streams = new AbstractBufferStream[formatControlCount]; - for (int i = 0; i < formatControlCount; i++) - streams[i] = createStream(i, formatControls[i]); - - /* - * Start the streams if this DataSource has already been - * started. - */ - if (started) - for (AbstractBufferStream stream : streams) - try - { - stream.start(); - } - catch (IOException ioex) - { - throw new UndeclaredThrowableException(ioex); - } - } - } - - int streamCount = (streams == null) ? 0 : streams.length; - @SuppressWarnings("unchecked") - SourceStreamT[] clone - = (SourceStreamT[]) Array.newInstance(clz, streamCount); - - if (streamCount != 0) - System.arraycopy(streams, 0, clone, 0, streamCount); - return clone; - } - - /** - * Gets the Formats which are to be reported by a - * FormatControl as supported formats for a - * AbstractBufferStream at a specific zero-based index in the list - * of streams of this AbstractBufferCaptureDevice. - * - * @param streamIndex the zero-based index of the - * AbstractBufferStream for which the specified - * FormatControl is to report the list of supported - * Formats - * @return an array of Formats to be reported by a - * FormatControl as the supported formats for the - * AbstractBufferStream at the specified streamIndex in - * the list of streams of this AbstractBufferCaptureDevice - */ - protected abstract Format[] getSupportedFormats(int streamIndex); - - /** - * Gets the Format to be reported by the FormatControl of - * a PushBufferStream at a specific zero-based index in the list of - * streams of this PushBufferDataSource. The - * PushBufferStream may not exist at the time of requesting its - * Format. - * - * @param streamIndex the zero-based index of the PushBufferStream - * the Format of which is to be retrieved - * @param oldValue the last-known Format for the - * PushBufferStream at the specified streamIndex - * @return the Format to be reported by the FormatControl - * of the PushBufferStream at the specified streamIndex in - * the list of streams of this PushBufferDataSource. - */ - private Format internalGetFormat(int streamIndex, Format oldValue) - { - synchronized (this) - { - if (streams != null) - { - AbstractBufferStream stream = streams[streamIndex]; - - if (stream != null) - { - Format streamFormat = stream.internalGetFormat(); - - if (streamFormat != null) - return streamFormat; - } - } - } - return getFormat(streamIndex, oldValue); - } - - /** - * Gets an array of FormatControl instances each one of which can - * be used before {@link #connect()} to get and set the capture - * Format of each one of the capture streams. - * - * @return an array of FormatControl instances each one of which - * can be used before {@link #connect()} to get and set the capture - * Format of each one of the capture streams - */ - private synchronized FormatControl[] internalGetFormatControls() - { - if (formatControls == null) - formatControls = createFormatControls(); - return formatControls; - } - - /** - * Gets an array of FrameRateControl instances which can be used to - * get and/or set the output frame rate of this - * AbstractBufferCaptureDevice. - * - * @return an array of FrameRateControl instances which can be used - * to get and/or set the output frame rate of this - * AbstractBufferCaptureDevice. - */ - private synchronized FrameRateControl[] internalGetFrameRateControls() - { - if (frameRateControls == null) - { - FrameRateControl frameRateControl = createFrameRateControl(); - - // Don't try to create the FrameRateControl more than once. - frameRateControls - = (frameRateControl == null) - ? new FrameRateControl[0] - : new FrameRateControl[] { frameRateControl }; - } - return frameRateControls; - } - - /** - * Gets an array of RTPInfo instances of this - * AbstractBufferCaptureDevice. - * - * @return an array of RTPInfo instances of this - * AbstractBufferCaptureDevice. - */ - private synchronized RTPInfo[] internalGetRTPInfos() - { - if (rtpInfos == null) - { - RTPInfo rtpInfo = createRTPInfo(); - - // Don't try to create the RTPInfo more than once. - rtpInfos - = (rtpInfo == null) - ? new RTPInfo[0] - : new RTPInfo[] { rtpInfo }; - } - return rtpInfos; - } - - /** - * Attempts to set the Format to be reported by the - * FormatControl of a PushBufferStream at a specific - * zero-based index in the list of streams of this - * PushBufferDataSource. - * - * @param streamIndex the zero-based index of the PushBufferStream - * the Format of which is to be set - * @param oldValue the last-known Format for the - * PushBufferStream at the specified streamIndex - * @param newValue the Format which is to be set - * @return the Format to be reported by the FormatControl - * of the PushBufferStream at the specified streamIndex - * in the list of streams of this PushBufferStream or null - * if the attempt to set the Format did not success and any - * last-known Format is to be left in effect - */ - private Format internalSetFormat( - int streamIndex, - Format oldValue, Format newValue) - { - synchronized (this) - { - if (streams != null) - { - AbstractBufferStream stream = streams[streamIndex]; - - if (stream != null) - return stream.internalSetFormat(newValue); - } - } - return setFormat(streamIndex, oldValue, newValue); - } - - /** - * Attempts to set the Format to be reported by the - * FormatControl of a AbstractBufferStream at a specific - * zero-based index in the list of streams of this - * AbstractBufferCaptureDevice. The AbstractBufferStream - * does not exist at the time of the attempt to set its Format. - * Allows extenders to override the default behavior which is to not attempt - * to set the specified Format so that they can enable setting the - * Format prior to creating the AbstractBufferStream. If - * setting the Format of an existing AbstractBufferStream - * is desired, AbstractBufferStream#doSetFormat(Format) should be - * overridden instead. - * - * @param streamIndex the zero-based index of the - * AbstractBufferStream the Format of which is to be set - * @param oldValue the last-known Format for the - * AbstractBufferStream at the specified streamIndex - * @param newValue the Format which is to be set - * @return the Format to be reported by the FormatControl - * of the AbstractBufferStream at the specified - * streamIndex in the list of streams of this - * AbstractBufferStream or null if the attempt to set the - * Format did not success and any last-known Format is to - * be left in effect - */ - protected abstract Format setFormat( - int streamIndex, - Format oldValue, Format newValue); - - /** - * Starts the transfer of media data from this - * AbstractBufferCaptureDevice. - * - * @throws IOException if anything goes wrong while starting the transfer of - * media data from this AbstractBufferCaptureDevice - */ - public synchronized void start() - throws IOException - { - if (!started) - { - if (!connected) - throw new IOException(getClass().getName() + " not connected"); - - doStart(); - started = true; - } - } - - /** - * Stops the transfer of media data from this - * AbstractBufferCaptureDevice. - * - * @throws IOException if anything goes wrong while stopping the transfer of - * media data from this AbstractBufferCaptureDevice - */ - public synchronized void stop() - throws IOException - { - if (started) - { - doStop(); - started = false; - } - } - - /** - * Gets the internal array of AbstractBufferStreams through which - * this AbstractBufferCaptureDevice gives access to its media data. - * - * @return the internal array of AbstractBufferStreams through - * which this AbstractBufferCaptureDevice gives access to its media - * data - */ - AbstractBufferStream[] streams() - { - return streams; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractBufferStream.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractBufferStream.java deleted file mode 100644 index d3bb205e5..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractBufferStream.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol; - -import java.io.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.control.*; -import net.java.sip.communicator.util.*; - -/** - * Provides a base implementation of SourceStream in order to - * facilitate implementers by taking care of boilerplate in the most common - * cases. - * - * @author Lyubomir Marinov - */ -abstract class AbstractBufferStream - extends AbstractControls - implements SourceStream -{ - /** - * The Logger used by the AbstractBufferStream class and - * its instances. - */ - private static final Logger logger - = Logger.getLogger(AbstractBufferStream.class); - - /** - * The (default) ContentDescriptor of the - * AbstractBufferStream instances. - */ - private static final ContentDescriptor CONTENT_DESCRIPTOR - = new ContentDescriptor(ContentDescriptor.RAW); - - /** - * The DataSource which has created this instance and which - * contains it as one of its streams. - */ - protected final DataSource dataSource; - - /** - * The FormatControl which gives access to the Format of - * the media data provided by this SourceStream and which, - * optionally, allows setting it. - */ - protected final FormatControl formatControl; - - /** - * Initializes a new AbstractBufferStream instance which is to have - * its Format-related information abstracted by a specific - * FormatControl. - * - * @param dataSource the DataSource which is creating the new - * instance so that it becomes one of its streams - * @param formatControl the FormatControl which is to abstract the - * Format-related information of the new instance - */ - protected AbstractBufferStream( - DataSource dataSource, - FormatControl formatControl) - { - this.dataSource = dataSource; - this.formatControl = formatControl; - } - - /** - * Releases the resources used by this instance throughout its existence and - * makes it available for garbage collection. This instance is considered - * unusable after closing. - */ - public void close() - { - try - { - stop(); - } - catch (IOException ioex) - { - logger.error("Failed to stop " + getClass().getSimpleName(), ioex); - } - } - - /** - * Gets the Format of this AbstractBufferStream as - * directly known by it. Allows extenders to override the Format - * known to the DataSource which created this instance and possibly - * provide more details on the currently set Format. - * - * @return the Format of this AbstractBufferStream as - * directly known by it or null if this - * AbstractBufferStream does not directly know its Format - * and it relies on the DataSource which created it to report its - * Format - */ - protected Format doGetFormat() - { - return null; - } - - /** - * Attempts to set the Format of this - * AbstractBufferStream. Allows extenders to enable setting the - * Format of an existing AbstractBufferStream (in contract - * to setting it before the AbstractBufferStream is created by the - * DataSource which will provide it). - * - * @param format the Format to be set as the format of this - * AbstractBufferStream - * @return the Format of this AbstractBufferStream or - * null if the attempt to set the Format did not succeed - * and any last-known Format is to be left in effect - */ - protected Format doSetFormat(Format format) - { - return null; - } - - /** - * Determines whether the end of this SourceStream has been - * reached. The AbstractBufferStream implementation always returns - * false. - * - * @return true if the end of this SourceStream has been - * reached; otherwise, false - */ - public boolean endOfStream() - { - return false; - } - - /** - * Gets a ContentDescriptor which describes the type of the content - * made available by this SourceStream. The - * AbstractBufferStream implementation always returns a - * ContentDescriptor with content type equal to - * ContentDescriptor#RAW. - * - * @return a ContentDescriptor which describes the type of the - * content made available by this SourceStream - */ - public ContentDescriptor getContentDescriptor() - { - return CONTENT_DESCRIPTOR; - } - - /** - * Gets the length in bytes of the content made available by this - * SourceStream. The AbstractBufferStream implementation - * always returns LENGTH_UNKNOWN. - * - * @return the length in bytes of the content made available by this - * SourceStream if it is known; otherwise, LENGTH_UKNOWN - */ - public long getContentLength() - { - return LENGTH_UNKNOWN; - } - - /** - * Implements {@link javax.media.protocol.Controls#getControls()}. Gets the - * controls available for this instance. - * - * @return an array of Objects which represent the controls - * available for this instance - */ - public Object[] getControls() - { - if (formatControl != null) - return new Object[] { formatControl }; - else - return ControlsAdapter.EMPTY_CONTROLS; - } - - /** - * Gets the Format of the media data made available by this - * AbstractBufferStream. - * - * @return the Format of the media data made available by this - * AbstractBufferStream - */ - public Format getFormat() - { - return (formatControl == null) ? null : formatControl.getFormat(); - } - - /** - * Gets the Format of this AbstractBufferStream as - * directly known by it. - * - * @return the Format of this AbstractBufferStream as - * directly known by it - */ - Format internalGetFormat() - { - return doGetFormat(); - } - - /** - * Attempts to set the Format of this - * AbstractBufferStream. - * - * @param format the Format to be set as the format of this - * AbstractBufferStream - * @return the Format of this AbstractBufferStream or - * null if the attempt to set the Format did not succeed - * and any last-known Format is to be left in effect - */ - Format internalSetFormat(Format format) - { - return doSetFormat(format); - } - - /** - * Starts the transfer of media data from this - * AbstractBufferStream. - * - * @throws IOException if anything goes wrong while starting the transfer of - * media data from this AbstractBufferStream - */ - public void start() - throws IOException - { - } - - /** - * Stops the transfer of media data from this AbstractBufferStream. - * - * @throws IOException if anything goes wrong while stopping the transfer of - * media data from this AbstractBufferStream - */ - public void stop() - throws IOException - { - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPullBufferCaptureDevice.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPullBufferCaptureDevice.java deleted file mode 100644 index 26e1d0dc0..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPullBufferCaptureDevice.java +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol; - -import java.io.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.protocol.*; - -/** - * Provides a base implementation of PullBufferDataSource and - * CaptureDevice in order to facilitate implementers by taking care of - * boilerplate in the most common cases. - * - * @author Lyubomir Marinov - */ -public abstract class AbstractPullBufferCaptureDevice - extends PullBufferDataSource - implements CaptureDevice -{ - - /** - * The CaptureDeviceInfo. - */ - private CaptureDeviceInfo deviceInfo; - - /** - * The AbstractBufferCaptureDevice which provides the - * implementation of this AbstractPullBufferCaptureDevice. - */ - private final AbstractBufferCaptureDevice impl - = new AbstractBufferCaptureDevice() - { - @Override - protected FrameRateControl createFrameRateControl() - { - return - AbstractPullBufferCaptureDevice.this - .createFrameRateControl(); - } - - protected AbstractPullBufferStream createStream( - int streamIndex, - FormatControl formatControl) - { - return - AbstractPullBufferCaptureDevice.this.createStream( - streamIndex, - formatControl); - } - - protected void doConnect() - throws IOException - { - AbstractPullBufferCaptureDevice.this.doConnect(); - } - - protected void doDisconnect() - { - AbstractPullBufferCaptureDevice.this.doDisconnect(); - } - - protected void doStart() - throws IOException - { - AbstractPullBufferCaptureDevice.this.doStart(); - } - - protected void doStop() - throws IOException - { - AbstractPullBufferCaptureDevice.this.doStop(); - } - - public CaptureDeviceInfo getCaptureDeviceInfo() - { - return - AbstractPullBufferCaptureDevice.this - .getCaptureDeviceInfo(); - } - - protected Format getFormat(int streamIndex, Format oldValue) - { - return - AbstractPullBufferCaptureDevice.this.getFormat( - streamIndex, - oldValue); - } - - protected Format[] getSupportedFormats(int streamIndex) - { - return - AbstractPullBufferCaptureDevice.this - .getSupportedFormats(streamIndex); - } - - protected Format setFormat( - int streamIndex, - Format oldValue, Format newValue) - { - return - AbstractPullBufferCaptureDevice.this.setFormat( - streamIndex, - oldValue, newValue); - } - }; - - /** - * Initializes a new AbstractPullBufferCaptureDevice instance. - */ - protected AbstractPullBufferCaptureDevice() - { - } - - /** - * Initializes a new AbstractPullBufferCaptureDevice instance from - * a specific MediaLocator. - * - * @param locator the MediaLocator to create the new instance from - */ - protected AbstractPullBufferCaptureDevice(MediaLocator locator) - { - setLocator(locator); - } - - /** - * Opens a connection to the media source specified by the - * MediaLocator of this DataSource. - * - * @throws IOException if anything goes wrong while opening the connection - * to the media source specified by the MediaLocator of this - * DataSource - */ - public void connect() - throws IOException - { - impl.connect(); - } - - /** - * Creates a new FrameRateControl instance which is to allow the - * getting and setting of the frame rate of this - * AbstractPullBufferCaptureDevice. - * - * @return a new FrameRateControl instance which is to allow the - * getting and setting of the frame rate of this - * AbstractPullBufferCaptureDevice - */ - protected FrameRateControl createFrameRateControl() - { - return null; - } - - /** - * Creates a new PullBufferStream which is to be at a specific - * zero-based index in the list of streams of this - * PullBufferDataSource. The Format-related information of - * the new instance is to be abstracted by a specific - * FormatControl. - * - * @param streamIndex the zero-based index of the PullBufferStream - * in the list of streams of this PullBufferDataSource - * @param formatControl the FormatControl which is to abstract the - * Format-related information of the new instance - * @return a new PullBufferStream which is to be at the specified - * streamIndex in the list of streams of this - * PullBufferDataSource and which has its Format-related - * information abstracted by the specified formatControl - */ - protected abstract AbstractPullBufferStream createStream( - int streamIndex, - FormatControl formatControl); - - /** - * Closes the connection to the media source specified by the - * MediaLocator of this DataSource. If such a connection - * has not been opened, the call is ignored. - */ - public void disconnect() - { - impl.disconnect(); - } - - /** - * Opens a connection to the media source specified by the - * MediaLocator of this DataSource. Allows extenders to - * override and be sure that there will be no request to open a connection - * if the connection has already been opened. - * - * @throws IOException if anything goes wrong while opening the connection - * to the media source specified by the MediaLocator of this - * DataSource - */ - protected void doConnect() - throws IOException - { - } - - /** - * Closes the connection to the media source specified by the - * MediaLocator of this DataSource. Allows extenders to - * override and be sure that there will be no request to close a connection - * if the connection has not been opened yet. - */ - protected void doDisconnect() - { - /* - * While it is not clear whether the streams can be released upon - * disconnect, com.imb.media.protocol.SuperCloneableDataSource gets the - * streams of the DataSource it adapts (i.e. this DataSource when - * SourceCloneable support is to be created for it) before #connect(). - * Unfortunately, it means that it isn't clear when the streams are to - * be disposed. - */ - } - - /** - * Starts the transfer of media data from this DataSource. Allows - * extenders to override and be sure that there will be no request to start - * the transfer of media data if it has already been started. - * - * @throws IOException if anything goes wrong while starting the transfer of - * media data from this DataSource - */ - protected void doStart() - throws IOException - { - impl.defaultDoStart(); - } - - /** - * Stops the transfer of media data from this DataSource. Allows - * extenders to override and be sure that there will be no request to stop - * the transfer of media data if it has not been started yet. - * - * @throws IOException if anything goes wrong while stopping the transfer of - * media data from this DataSource - */ - protected void doStop() - throws IOException - { - impl.defaultDoStop(); - } - - /** - * Gets the CaptureDeviceInfo of this CaptureDevice which - * describes it. - * - * @return the CaptureDeviceInfo of this CaptureDevice - * which describes it - */ - public CaptureDeviceInfo getCaptureDeviceInfo() - { - return - (deviceInfo == null) - ? AbstractBufferCaptureDevice.getCaptureDeviceInfo(this) - : deviceInfo; - } - - /** - * Gets the content type of the media represented by this instance. The - * AbstractPullBufferCaptureDevice implementation always returns - * {@link ContentDescriptor#RAW}. - * - * @return the content type of the media represented by this instance - */ - public String getContentType() - { - return ContentDescriptor.RAW; - } - - /** - * Gets the control of the specified type available for this instance. - * - * @param controlType the type of the control available for this instance to - * be retrieved - * @return an Object which represents the control of the specified - * type available for this instance if such a control is indeed available; - * otherwise, null - */ - public Object getControl(String controlType) - { - return impl.getControl(controlType); - } - - /** - * Implements {@link javax.media.Controls#getControls()}. Gets the controls - * available for this instance. - * - * @return an array of Objects which represent the controls - * available for this instance - */ - public Object[] getControls() - { - return impl.getControls(); - } - - /** - * Gets the duration of the media represented by this instance. The - * AbstractPullBufferCaptureDevice always returns - * {@link #DURATION_UNBOUNDED}. - * - * @return the duration of the media represented by this instance - */ - public Time getDuration() - { - return DURATION_UNBOUNDED; - } - - /** - * Gets the Format to be reported by the FormatControl of - * a PullBufferStream at a specific zero-based index in the list of - * streams of this PullBufferDataSource. The - * PullBufferStream may not exist at the time of requesting its - * Format. Allows extenders to override the default behavior which - * is to report any last-known format or the first Format from the - * list of supported formats as defined in the JMF registration of this - * CaptureDevice. - * - * @param streamIndex the zero-based index of the PullBufferStream - * the Format of which is to be retrieved - * @param oldValue the last-known Format for the - * PullBufferStream at the specified streamIndex - * @return the Format to be reported by the FormatControl - * of the PullBufferStream at the specified streamIndex in - * the list of streams of this PullBufferDataSource. - */ - protected Format getFormat(int streamIndex, Format oldValue) - { - return impl.defaultGetFormat(streamIndex, oldValue); - } - - /** - * Gets an array of FormatControl instances each one of which can - * be used before {@link #connect()} to get and set the capture - * Format of each one of the capture streams. - * - * @return an array of FormatControl instances each one of which - * can be used before {@link #connect()} to get and set the capture - * Format of each one of the capture streams - */ - public FormatControl[] getFormatControls() - { - return impl.getFormatControls(); - } - - /** - * Gets the Object which is to synchronize the access to - * {@link #streams()} and its return value. - * - * @return the Object which is to synchronize the access to - * {@link #streams()} and its return value - */ - protected Object getStreamSyncRoot() - { - return impl.getStreamSyncRoot(); - } - - /** - * Gets the PullBufferStreams through which this - * PullBufferDataSource gives access to its media data. - * - * @return an array of the PullBufferStreams through which this - * PullBufferDataSource gives access to its media data - */ - public PullBufferStream[] getStreams() - { - return impl.getStreams(PullBufferStream.class); - } - - /** - * Gets the Formats which are to be reported by a - * FormatControl as supported formats for a - * PullBufferStream at a specific zero-based index in the list of - * streams of this PullBufferDataSource. - * - * @param streamIndex the zero-based index of the PullBufferStream - * for which the specified FormatControl is to report the list of - * supported Formats - * @return an array of Formats to be reported by a - * FormatControl as the supported formats for the - * PullBufferStream at the specified streamIndex in the - * list of streams of this PullBufferDataSource - */ - protected Format[] getSupportedFormats(int streamIndex) - { - return impl.defaultGetSupportedFormats(streamIndex); - } - - /** - * Sets a specific CaptureDeviceInfo on this - * CaptureDevice. - * - * @param deviceInfo the CaptureDeviceInfo on this - * CaptureDevice - */ - public void setCaptureDeviceInfo(CaptureDeviceInfo deviceInfo) - { - this.deviceInfo = deviceInfo; - } - - /** - * Attempts to set the Format to be reported by the - * FormatControl of a PullBufferStream at a specific - * zero-based index in the list of streams of this - * PullBufferDataSource. The PullBufferStream does not - * exist at the time of the attempt to set its Format. Allows - * extenders to override the default behavior which is to not attempt to set - * the specified Format so that they can enable setting the - * Format prior to creating the PullBufferStream. If - * setting the Format of an existing PullBufferStream is - * desired, AbstractPullBufferStream#doSetFormat(Format) should be - * overridden instead. - * - * @param streamIndex the zero-based index of the PullBufferStream - * the Format of which is to be set - * @param oldValue the last-known Format for the - * PullBufferStream at the specified streamIndex - * @param newValue the Format which is to be set - * @return the Format to be reported by the FormatControl - * of the PullBufferStream at the specified streamIndex - * in the list of streams of this PullBufferStream or null - * if the attempt to set the Format did not success and any - * last-known Format is to be left in effect - */ - protected Format setFormat( - int streamIndex, - Format oldValue, - Format newValue) - { - return oldValue; - } - - /** - * Starts the transfer of media data from this DataSource - * - * @throws IOException if anything goes wrong while starting the transfer of - * media data from this DataSource - */ - public synchronized void start() - throws IOException - { - impl.start(); - } - - /** - * Stops the transfer of media data from this DataSource. - * - * @throws IOException if anything goes wrong while stopping the transfer of - * media data from this DataSource - */ - public synchronized void stop() - throws IOException - { - impl.stop(); - } - - /** - * Gets the internal array of AbstractPushBufferStreams through - * which this AbstractPushBufferCaptureDevice gives access to its - * media data. - * - * @return the internal array of AbstractPushBufferStreams through - * which this AbstractPushBufferCaptureDevice gives access to its - * media data - */ - protected AbstractBufferStream[] streams() - { - return impl.streams(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPullBufferStream.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPullBufferStream.java deleted file mode 100644 index 10725febe..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPullBufferStream.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol; - -import javax.media.*; -import javax.media.control.*; -import javax.media.protocol.*; - -/** - * Provides a base implementation of PullBufferStream in order to - * facilitate implementers by taking care of boilerplate in the most common - * cases. - * - * @author Lyubomir Marinov - */ -public abstract class AbstractPullBufferStream - extends AbstractBufferStream - implements PullBufferStream -{ - - /** - * Initializes a new AbstractPullBufferStream instance which is to - * have its Format-related information abstracted by a specific - * FormatControl. - * - * @param dataSource the PullBufferDataSource which is creating the - * new instance so that it becomes one of its streams - * @param formatControl the FormatControl which is to abstract the - * Format-related information of the new instance - */ - protected AbstractPullBufferStream( - PullBufferDataSource dataSource, - FormatControl formatControl) - { - super(dataSource, formatControl); - } - - /** - * Determines if {@link #read(Buffer)} will block. - * - * @return true if read block, false otherwise - */ - public boolean willReadBlock() - { - return true; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPushBufferCaptureDevice.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPushBufferCaptureDevice.java deleted file mode 100644 index 1d962022a..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPushBufferCaptureDevice.java +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol; - -import java.io.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.protocol.*; - -/** - * Provides a base implementation of PushBufferDataSource and - * CaptureDevice in order to facilitate implementers by taking care of - * boilerplate in the most common cases. - * - * @author Lyubomir Marinov - */ -public abstract class AbstractPushBufferCaptureDevice - extends PushBufferDataSource - implements CaptureDevice -{ - /** - * The AbstractBufferCaptureDevice which provides the - * implementation of this AbstractPushBufferCaptureDevice. - */ - private final AbstractBufferCaptureDevice impl - = new AbstractBufferCaptureDevice() - { - @Override - protected FrameRateControl createFrameRateControl() - { - return - AbstractPushBufferCaptureDevice.this - .createFrameRateControl(); - } - - protected AbstractPushBufferStream createStream( - int streamIndex, - FormatControl formatControl) - { - return - AbstractPushBufferCaptureDevice.this.createStream( - streamIndex, - formatControl); - } - - protected void doConnect() - throws IOException - { - AbstractPushBufferCaptureDevice.this.doConnect(); - } - - protected void doDisconnect() - { - AbstractPushBufferCaptureDevice.this.doDisconnect(); - } - - protected void doStart() - throws IOException - { - AbstractPushBufferCaptureDevice.this.doStart(); - } - - protected void doStop() - throws IOException - { - AbstractPushBufferCaptureDevice.this.doStop(); - } - - public CaptureDeviceInfo getCaptureDeviceInfo() - { - return - AbstractPushBufferCaptureDevice.this - .getCaptureDeviceInfo(); - } - - /** - * Overrides {@link AbstractBufferCaptureDevice#getControls()} to - * add controls specific to this - * AbstractPushBufferCaptureDevice. - * - * {@inheritDoc} - */ - @Override - public Object[] getControls() - { - return AbstractPushBufferCaptureDevice.this.getControls(); - } - - protected Format getFormat(int streamIndex, Format oldValue) - { - return - AbstractPushBufferCaptureDevice.this.getFormat( - streamIndex, - oldValue); - } - - protected Format[] getSupportedFormats(int streamIndex) - { - return - AbstractPushBufferCaptureDevice.this - .getSupportedFormats(streamIndex); - } - - protected Format setFormat( - int streamIndex, - Format oldValue, Format newValue) - { - return - AbstractPushBufferCaptureDevice.this.setFormat( - streamIndex, - oldValue, newValue); - } - }; - - /** - * Initializes a new AbstractPushBufferCaptureDevice instance. - */ - protected AbstractPushBufferCaptureDevice() - { - } - - /** - * Initializes a new AbstractPushBufferCaptureDevice instance from - * a specific MediaLocator. - * - * @param locator the MediaLocator to create the new instance from - */ - protected AbstractPushBufferCaptureDevice(MediaLocator locator) - { - setLocator(locator); - } - - /** - * Opens a connection to the media source specified by the - * MediaLocator of this DataSource. - * - * @throws IOException if anything goes wrong while opening the connection - * to the media source specified by the MediaLocator of this - * DataSource - */ - public void connect() - throws IOException - { - impl.connect(); - } - - /** - * Creates a new FrameRateControl instance which is to allow the - * getting and setting of the frame rate of this - * AbstractPushBufferCaptureDevice. - * - * @return a new FrameRateControl instance which is to allow the - * getting and setting of the frame rate of this - * AbstractPushBufferCaptureDevice - */ - protected FrameRateControl createFrameRateControl() - { - return null; - } - - /** - * Create a new PushBufferStream which is to be at a specific - * zero-based index in the list of streams of this - * PushBufferDataSource. The Format-related information of - * the new instance is to be abstracted by a specific - * FormatControl. - * - * @param streamIndex the zero-based index of the PushBufferStream - * in the list of streams of this PushBufferDataSource - * @param formatControl the FormatControl which is to abstract the - * Format-related information of the new instance - * @return a new PushBufferStream which is to be at the specified - * streamIndex in the list of streams of this - * PushBufferDataSource and which has its Format-related - * information abstracted by the specified formatControl - */ - protected abstract AbstractPushBufferStream createStream( - int streamIndex, - FormatControl formatControl); - - /** - * Closes the connection to the media source specified by the - * MediaLocator of this DataSource. If such a connection - * has not been opened, the call is ignored. - */ - public void disconnect() - { - impl.disconnect(); - } - - /** - * Opens a connection to the media source specified by the - * MediaLocator of this DataSource. Allows extenders to - * override and be sure that there will be no request to open a connection - * if the connection has already been opened. - * - * @throws IOException if anything goes wrong while opening the connection - * to the media source specified by the MediaLocator of this - * DataSource - */ - protected void doConnect() - throws IOException - { - } - - /** - * Closes the connection to the media source specified by the - * MediaLocator of this DataSource. Allows extenders to - * override and be sure that there will be no request to close a connection - * if the connection has not been opened yet. - */ - protected void doDisconnect() - { - /* - * While it is not clear whether the streams can be released upon - * disconnect, com.imb.media.protocol.SuperCloneableDataSource gets the - * streams of the DataSource it adapts (i.e. this DataSource when - * SourceCloneable support is to be created for it) before #connect(). - * Unfortunately, it means that it isn't clear when the streams are to - * be disposed. - */ - } - - /** - * Starts the transfer of media data from this DataSource. Allows - * extenders to override and be sure that there will be no request to start - * the transfer of media data if it has already been started. - * - * @throws IOException if anything goes wrong while starting the transfer of - * media data from this DataSource - */ - protected void doStart() - throws IOException - { - impl.defaultDoStart(); - } - - /** - * Stops the transfer of media data from this DataSource. Allows - * extenders to override and be sure that there will be no request to stop - * the transfer of media data if it has not been started yet. - * - * @throws IOException if anything goes wrong while stopping the transfer of - * media data from this DataSource - */ - protected void doStop() - throws IOException - { - impl.defaultDoStop(); - } - - /** - * Gets the CaptureDeviceInfo of this CaptureDevice which - * describes it. - * - * @return the CaptureDeviceInfo of this CaptureDevice - * which describes it - */ - public CaptureDeviceInfo getCaptureDeviceInfo() - { - return AbstractBufferCaptureDevice.getCaptureDeviceInfo(this); - } - - /** - * Gets the content type of the media represented by this instance. The - * AbstractPushBufferCaptureDevice implementation always returns - * {@link ContentDescriptor#RAW}. - * - * @return the content type of the media represented by this instance - */ - public String getContentType() - { - return ContentDescriptor.RAW; - } - - /** - * Gets the control of the specified type available for this instance. - * - * @param controlType the type of the control available for this instance to - * be retrieved - * @return an Object which represents the control of the specified - * type available for this instance if such a control is indeed available; - * otherwise, null - */ - public Object getControl(String controlType) - { - return impl.getControl(controlType); - } - - /** - * Implements {@link javax.media.protocol.DataSource#getControls()}. Gets - * the controls available for this instance. - * - * @return an array of Objects which represent the controls - * available for this instance - */ - public Object[] getControls() - { - return impl.defaultGetControls(); - } - - /** - * Gets the duration of the media represented by this instance. The - * AbstractPushBufferCaptureDevice always returns - * {@link #DURATION_UNBOUNDED}. - * - * @return the duration of the media represented by this instance - */ - public Time getDuration() - { - return DURATION_UNBOUNDED; - } - - /** - * Gets the Format to be reported by the FormatControl of - * a PushBufferStream at a specific zero-based index in the list of - * streams of this PushBufferDataSource. The - * PushBufferStream may not exist at the time of requesting its - * Format. Allows extenders to override the default behavior which - * is to report any last-known format or the first Format from the - * list of supported formats as defined in the JMF registration of this - * CaptureDevice. - * - * @param streamIndex the zero-based index of the PushBufferStream - * the Format of which is to be retrieved - * @param oldValue the last-known Format for the - * PushBufferStream at the specified streamIndex - * @return the Format to be reported by the FormatControl - * of the PushBufferStream at the specified streamIndex in - * the list of streams of this PushBufferDataSource. - */ - protected Format getFormat(int streamIndex, Format oldValue) - { - return impl.defaultGetFormat(streamIndex, oldValue); - } - - /** - * Gets an array of FormatControl instances each one of which can - * be used before {@link #connect()} to get and set the capture - * Format of each one of the capture streams. - * - * @return an array of FormatControl instances each one of which - * can be used before {@link #connect()} to get and set the capture - * Format of each one of the capture streams - */ - public FormatControl[] getFormatControls() - { - return impl.getFormatControls(); - } - - /** - * Gets the Object which is to synchronize the access to - * {@link #streams()} and its return value. - * - * @return the Object which is to synchronize the access to - * {@link #streams()} and its return value - */ - protected Object getStreamSyncRoot() - { - return impl.getStreamSyncRoot(); - } - - /** - * Gets the PushBufferStreams through which this - * PushBufferDataSource gives access to its media data. - * - * @return an array of the PushBufferStreams through which this - * PushBufferDataSource gives access to its media data - */ - public PushBufferStream[] getStreams() - { - return impl.getStreams(PushBufferStream.class); - } - - /** - * Gets the Formats which are to be reported by a - * FormatControl as supported formats for a - * PushBufferStream at a specific zero-based index in the list of - * streams of this PushBufferDataSource. - * - * @param streamIndex the zero-based index of the PushBufferStream - * for which the specified FormatControl is to report the list of - * supported Formats - * @return an array of Formats to be reported by a - * FormatControl as the supported formats for the - * PushBufferStream at the specified streamIndex in the - * list of streams of this PushBufferDataSource - */ - protected Format[] getSupportedFormats(int streamIndex) - { - return impl.defaultGetSupportedFormats(streamIndex); - } - - /** - * Attempts to set the Format to be reported by the - * FormatControl of a PushBufferStream at a specific - * zero-based index in the list of streams of this - * PushBufferDataSource. The PushBufferStream does not - * exist at the time of the attempt to set its Format. Allows - * extenders to override the default behavior which is to not attempt to set - * the specified Format so that they can enable setting the - * Format prior to creating the PushBufferStream. If - * setting the Format of an existing PushBufferStream is - * desired, AbstractPushBufferStream#doSetFormat(Format) should be - * overridden instead. - * - * @param streamIndex the zero-based index of the PushBufferStream - * the Format of which is to be set - * @param oldValue the last-known Format for the - * PushBufferStream at the specified streamIndex - * @param newValue the Format which is to be set - * @return the Format to be reported by the FormatControl - * of the PushBufferStream at the specified streamIndex - * in the list of streams of this PushBufferStream or null - * if the attempt to set the Format did not success and any - * last-known Format is to be left in effect - */ - protected Format setFormat( - int streamIndex, - Format oldValue, Format newValue) - { - return oldValue; - } - - /** - * Starts the transfer of media data from this DataSource. - * - * @throws IOException if anything goes wrong while starting the transfer of - * media data from this DataSource - */ - public void start() - throws IOException - { - impl.start(); - } - - /** - * Stops the transfer of media data from this DataSource. - * - * @throws IOException if anything goes wrong while stopping the transfer of - * media data from this DataSource - */ - public void stop() - throws IOException - { - impl.stop(); - } - - /** - * Gets the internal array of AbstractPushBufferStreams through - * which this AbstractPushBufferCaptureDevice gives access to its - * media data. - * - * @return the internal array of AbstractPushBufferStreams through - * which this AbstractPushBufferCaptureDevice gives access to its - * media data - */ - protected AbstractBufferStream[] streams() - { - return impl.streams(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPushBufferStream.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPushBufferStream.java deleted file mode 100644 index 7ab691624..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPushBufferStream.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol; - -import javax.media.control.*; -import javax.media.protocol.*; - -/** - * Provides a base implementation of PushBufferStream in order to - * facilitate implementers by taking care of boilerplate in the most common - * cases. - * - * @author Lyubomir Marinov - */ -public abstract class AbstractPushBufferStream - extends AbstractBufferStream - implements PushBufferStream -{ - - /** - * The BufferTransferHandler which is notified by this - * PushBufferStream when data is available for reading. - */ - protected BufferTransferHandler transferHandler; - - /** - * Initializes a new AbstractPushBufferStream instance which is to - * have its Format-related information abstracted by a specific - * FormatControl. - * - * @param dataSource the PushBufferDataSource which is creating the - * new instance so that it becomes one of its streams - * @param formatControl the FormatControl which is to abstract the - * Format-related information of the new instance - */ - protected AbstractPushBufferStream( - PushBufferDataSource dataSource, - FormatControl formatControl) - { - super(dataSource, formatControl); - } - - /** - * Sets the BufferTransferHandler which is to be notified by this - * PushBufferStream when data is available for reading. - * - * @param transferHandler the BufferTransferHandler which is to be - * notified by this PushBufferStream when data is available for - * reading - */ - public void setTransferHandler(BufferTransferHandler transferHandler) - { - this.transferHandler = transferHandler; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractVideoPullBufferCaptureDevice.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractVideoPullBufferCaptureDevice.java deleted file mode 100644 index 46b0a1f23..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractVideoPullBufferCaptureDevice.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol; - -import javax.media.*; -import javax.media.control.*; - -import net.java.sip.communicator.impl.neomedia.control.*; - -/** - * Provides a base implementation of PullBufferDataSource and - * CaptureDevice for the purposes of video in order to facilitate - * implementers by taking care of boilerplate in the most common cases. - * - * @author Lyubomir Marinov - */ -public abstract class AbstractVideoPullBufferCaptureDevice - extends AbstractPullBufferCaptureDevice -{ - - /** - * Initializes a new AbstractVideoPullBufferCaptureDevice instance. - */ - protected AbstractVideoPullBufferCaptureDevice() - { - } - - /** - * Initializes a new AbstractVideoPullBufferCaptureDevice instance - * from a specific MediaLocator. - * - * @param locator the MediaLocator to create the new instance from - */ - protected AbstractVideoPullBufferCaptureDevice(MediaLocator locator) - { - super(locator); - } - - /** - * Creates a new FrameRateControl instance which is to allow the - * getting and setting of the frame rate of this - * AbstractVideoPullBufferCaptureDevice. - * - * @return a new FrameRateControl instance which is to allow the - * getting and setting of the frame rate of this - * AbstractVideoPullBufferCaptureDevice - * @see AbstractPullBufferCaptureDevice#createFrameRateControl() - */ - @Override - protected FrameRateControl createFrameRateControl() - { - return - new FrameRateControlAdapter() - { - /** - * The output frame rate of this - * AbstractVideoPullBufferCaptureDevice. - */ - private float frameRate = -1; - - @Override - public float getFrameRate() - { - return frameRate; - } - - @Override - public float setFrameRate(float frameRate) - { - this.frameRate = frameRate; - return this.frameRate; - } - }; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractVideoPullBufferStream.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractVideoPullBufferStream.java deleted file mode 100644 index 62a7f8be1..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractVideoPullBufferStream.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol; - -import java.io.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.protocol.*; - -/** - * Provides a base implementation of PullBufferStream for video in - * order to facilitate implementers by taking care of boilerplate in the most - * common cases. - * - * @author Lyubomir Marinov - */ -public abstract class AbstractVideoPullBufferStream - extends AbstractPullBufferStream -{ - - /** - * The output frame rate of this AbstractVideoPullBufferStream - * which has been specified by {@link #frameRateControl} and depending on - * which {@link #minimumVideoFrameInterval} has been calculated. - */ - private float frameRate; - - /** - * The FrameRateControl which gets and sets the output frame rate - * of this AbstractVideoPullBufferStream. - */ - private FrameRateControl frameRateControl; - - /** - * The minimum interval in milliseconds between consecutive video frames - * i.e. the reverse of {@link #frameRate}. - */ - private long minimumVideoFrameInterval; - - /** - * Initializes a new AbstractVideoPullBufferStream instance which - * is to have its Format-related information abstracted by a - * specific FormatControl. - * - * @param dataSource the PullBufferDataSource which is creating the - * new instance so that it becomes one of its streams - * @param formatControl the FormatControl which is to abstract the - * Format-related information of the new instance - */ - protected AbstractVideoPullBufferStream( - PullBufferDataSource dataSource, - FormatControl formatControl) - { - super(dataSource, formatControl); - } - - /** - * Blocks and reads into a Buffer from this - * PullBufferStream. - * - * @param buffer the Buffer this PullBufferStream is to - * read into - * @throws IOException if an I/O error occurs while this - * PullBufferStream reads into the specified Buffer - */ - protected abstract void doRead(Buffer buffer) - throws IOException; - - /** - * Blocks and reads into a Buffer from this - * PullBufferStream. - * - * @param buffer the Buffer this PullBufferStream is to - * read into - * @throws IOException if an I/O error occurs while this - * PullBufferStream reads into the specified Buffer - */ - public void read(Buffer buffer) - throws IOException - { - FrameRateControl frameRateControl = this.frameRateControl; - - if (frameRateControl != null) - { - float frameRate = frameRateControl.getFrameRate(); - - if (frameRate > 0) - { - if (this.frameRate != frameRate) - { - minimumVideoFrameInterval = (long) (1000 / frameRate); - this.frameRate = frameRate; - } - if (minimumVideoFrameInterval > 0) - { - long startTime = System.currentTimeMillis(); - - doRead(buffer); - - if (!buffer.isDiscard()) - { - boolean interrupted = false; - - while (true) - { - // Sleep to respect the frame rate as much as possible. - long sleep - = minimumVideoFrameInterval - - (System.currentTimeMillis() - startTime); - - if (sleep > 0) - { - try - { - Thread.sleep(sleep); - } - catch (InterruptedException ie) - { - interrupted = true; - } - } - else - { - // Yield a little bit to not use all the whole CPU. - Thread.yield(); - break; - } - } - if (interrupted) - Thread.currentThread().interrupt(); - } - - // We've executed #doRead(Buffer). - return; - } - } - } - - // If there is no frame rate to be respected, just #doRead(Buffer). - doRead(buffer); - } - - /** - * Starts the transfer of media data from this - * AbstractBufferStream. - * - * @throws IOException if anything goes wrong while starting the transfer of - * media data from this AbstractBufferStream - * @see AbstractBufferStream#start() - */ - @Override - public void start() - throws IOException - { - super.start(); - - frameRateControl - = (FrameRateControl) - dataSource.getControl(FrameRateControl.class.getName()); - } - - /** - * Stops the transfer of media data from this AbstractBufferStream. - * - * @throws IOException if anything goes wrong while stopping the transfer of - * media data from this AbstractBufferStream - * @see AbstractBufferStream#stop() - */ - @Override - public void stop() - throws IOException - { - super.stop(); - - frameRateControl = null; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractVideoPushBufferCaptureDevice.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractVideoPushBufferCaptureDevice.java deleted file mode 100644 index f831e28db..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractVideoPushBufferCaptureDevice.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol; - -import javax.media.*; -import javax.media.control.*; - -/** - * Provides a base implementation of PushBufferDataSource and - * CaptureDevice for the purposes of video in order to facilitate - * implementers by taking care of boilerplate in the most common cases. - * - * @author Lyubomir Marinov - */ -public abstract class AbstractVideoPushBufferCaptureDevice - extends AbstractPushBufferCaptureDevice -{ - - /** - * Initializes a new AbstractVideoPushBufferCaptureDevice instance. - */ - protected AbstractVideoPushBufferCaptureDevice() - { - } - - /** - * Initializes a new AbstractVideoPushBufferCaptureDevice instance - * from a specific MediaLocator. - * - * @param locator the MediaLocator to create the new instance from - */ - protected AbstractVideoPushBufferCaptureDevice(MediaLocator locator) - { - super(locator); - } - - /** - * Creates a new FrameRateControl instance which is to allow the - * getting and setting of the frame rate of this - * AbstractVideoPushBufferCaptureDevice. - * - * @return a new FrameRateControl instance which is to allow the - * getting and setting of the frame rate of this - * AbstractVideoPushBufferCaptureDevice - * @see AbstractPushBufferCaptureDevice#createFrameRateControl() - */ - @Override - protected FrameRateControl createFrameRateControl() - { - return null; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/ByteBufferPool.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/ByteBufferPool.java deleted file mode 100644 index 4c11c0f98..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/ByteBufferPool.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol; - -import java.util.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.codec.video.*; -import net.java.sip.communicator.util.*; - -/** - * Represents a pool of ByteBuffers which reduces the allocations and - * deallocations of ByteBuffers in the Java heap and of native memory - * in the native heap. - * - * @author Lubomir Marinov - */ -public class ByteBufferPool -{ - - /** - * The Logger used by the ByteBufferPool class and its - * instances for logging output. - */ - private static final Logger logger = Logger.getLogger(ByteBufferPool.class); - - /** - * The ByteBuffers which are managed by this - * ByteBufferPool. - */ - private final List buffers = new ArrayList(); - - /** - * The indicator which determines whether this ByteBufferPool has - * been closed. Introduced to determine when ByteBuffers are to be - * disposed of and no longer be pooled. - */ - private boolean closed = false; - - /** - * Closes this ByteBufferPool i.e. releases the resource allocated - * by this ByteBufferPool during its existence and prepares it to - * be garbage collected. - */ - public void close() - { - synchronized (buffers) - { - closed = true; - - Iterator bufferIter = buffers.iterator(); - boolean loggerIsTraceEnabled = logger.isTraceEnabled(); - int leakedCount = 0; - - while (bufferIter.hasNext()) - { - ByteBuffer buffer = bufferIter.next(); - - if (buffer.isFree()) - { - bufferIter.remove(); - FFmpeg.av_free(buffer.ptr); - } - else if (loggerIsTraceEnabled) - leakedCount++; - } - if (loggerIsTraceEnabled) - { - if (logger.isTraceEnabled()) - logger.trace( - "Leaking " + leakedCount + " ByteBuffer instances."); - } - } - } - - /** - * Gets a ByteBuffer out of the pool of free ByteBuffers - * (i.e. ByteBuffers ready for writing captured media data into - * them) which is capable to receiving at least capacity number of - * bytes. - * - * @param capacity the minimal number of bytes that the returned - * ByteBuffer is to be capable of receiving - * @return a ByteBuffer which is ready for writing captured media - * data into and which is capable of receiving at least capacity - * number of bytes - */ - public ByteBuffer getFreeBuffer(int capacity) - { - synchronized (buffers) - { - if (closed) - return null; - - int bufferCount = buffers.size(); - ByteBuffer freeBuffer = null; - - /* - * XXX Pad with FF_INPUT_BUFFER_PADDING_SIZE or hell will break - * loose. - */ - capacity += FFmpeg.FF_INPUT_BUFFER_PADDING_SIZE; - - for (int bufferIndex = 0; bufferIndex < bufferCount; bufferIndex++) - { - ByteBuffer buffer = buffers.get(bufferIndex); - - if (buffer.isFree() && (buffer.capacity >= capacity)) - { - freeBuffer = buffer; - break; - } - } - if (freeBuffer == null) - { - freeBuffer = new ByteBuffer(capacity); - buffers.add(freeBuffer); - } - freeBuffer.setFree(false); - return freeBuffer; - } - } - - /** - * Returns a specific ByteBuffer into the pool of free - * ByteBuffers (i.e. ByteBuffers ready for writing - * captured media data into them). - * - * @param buffer the ByteBuffer to be returned into the pool of - * free ByteBuffers - */ - public void returnFreeBuffer(ByteBuffer buffer) - { - synchronized (buffers) - { - buffer.setFree(true); - if (closed && buffers.remove(buffer)) - FFmpeg.av_free(buffer.ptr); - } - } - - /** - * Returns a specific ByteBuffer given by the pointer to the native - * memory that it represents into the pool of free ByteBuffers - * (i.e. ByteBuffers ready for writing captured media data into - * them). - * - * @param bufferPtr the pointer to the native memory represented by the - * ByteBuffer to be returned into the pool of free - * ByteBuffers - */ - public void returnFreeBuffer(long bufferPtr) - { - synchronized (buffers) - { - for (ByteBuffer buffer : buffers) - if (buffer.ptr == bufferPtr) - { - returnFreeBuffer(buffer); - break; - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/alsa/AlsaStream.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/alsa/AlsaStream.java deleted file mode 100644 index fb50fedc2..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/alsa/AlsaStream.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.alsa; - -import java.io.*; - -import javax.media.*; -import javax.media.format.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.control.*; - -/** - * low-latency ALSA access through JNI wrapper - * - * @author Jean Lorchat - * @author Lubomir Marinov - */ -public class AlsaStream - extends ControlsAdapter - implements PushBufferStream, - Runnable -{ - protected ContentDescriptor cd = new ContentDescriptor(ContentDescriptor.RAW); - protected int maxDataLength; - protected AudioFormat audioFormat; - protected boolean started; - protected Thread thread; - protected BufferTransferHandler transferHandler; - - private native void jni_alsa_init(); - private native void jni_alsa_read(byte [] arr); - private native void jni_alsa_delete(); - - int seqNo = 0; - - /** - * Dynamically loads JNI object. Will fail if non-Linux - * or when libjmf_alsa.so is outside of the LD_LIBRARY_PATH - */ - static { - System.loadLibrary("jmf_alsa"); - } - - /** - * We only provide 8 kbps access to the device for now - * In addition, datablock size is fixed to 160 samples (320 bytes) - * This turns out to be 20ms worth of samples at 8kbps - * Very convenient for ilbc 20ms mode... - */ - public AlsaStream() { - - audioFormat = new AudioFormat(AudioFormat.LINEAR, - 8000.0, - 16, - 1, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - 16, - Format.NOT_SPECIFIED, - Format.byteArray); - - maxDataLength = 160; - - jni_alsa_init(); - thread = new Thread(this); - } - - /** - * Methods required for SourceStream interface - * - */ - - /** - * We are providing access to raw data - * - */ - public ContentDescriptor getContentDescriptor() { - return cd; - } - - /** - * Come on, we are streaming. Can't guess when the user wants to stop... - * - */ - public long getContentLength() { - return LENGTH_UNKNOWN; - } - - /** - * The stream of happiness never ends, somehow. - * - */ - public boolean endOfStream() { - return false; - } - - /** - * Tell whoever has interest how we are going to send the data - * - */ - public Format getFormat() { - return audioFormat; - } - - /** - * Reads sample data using native call - * - * @param buffer A Buffer with byte array as data, large enough to be - * filled with sample data. If this is not the case, we are going - * to allocate it ourselves anyway and replace the current data. - * - * @throws IOException Native method might throw an exception. - * Well actually that would surprise me because it is not - * implemented, but we love to be future-proof, isn't it ? - */ - public void read(Buffer buffer) throws IOException { - synchronized (this) { - Object outdata = buffer.getData(); - - if (outdata == null || - !(outdata.getClass() == Format.byteArray) || - ((byte[])outdata).length < maxDataLength) { - outdata = new byte[maxDataLength]; - buffer.setData(outdata); - } - - buffer.setFormat(audioFormat); - buffer.setTimeStamp(1000000000 / 8); - jni_alsa_read((byte[])outdata); - buffer.setSequenceNumber(seqNo); - buffer.setLength(maxDataLength); - buffer.setFlags(0); - buffer.setHeader(null); - seqNo++; - } - } - - /** - * Dunno about that piece yet... - * - */ - public void setTransferHandler(BufferTransferHandler transferHandler) { - synchronized (this) { - this.transferHandler = transferHandler; - notifyAll(); - } - } - - /** - * Starts a new thread for the stream operation - * - */ - void start(boolean started) { - synchronized (this) { - this.started = started; - if (started && !thread.isAlive()) { - thread = new Thread(this); - thread.start(); - } - notifyAll(); - } - } - - /** - * Transfer Buffer information through current thread then sleep - * until next data slice is ready. - * - */ - public void run() { - while (started) { - - synchronized (this) { - while (transferHandler == null && started) { - try { - wait(1000); - } catch (InterruptedException ie) { - } - } - } - - if (started && transferHandler != null) { - transferHandler.transferData(this); - try { - Thread.sleep(1); - } catch (InterruptedException ise) { - } - } - - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/alsa/DataSource.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/alsa/DataSource.java deleted file mode 100644 index 7ed310461..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/alsa/DataSource.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.alsa; - -import java.io.*; - -import javax.media.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.control.*; - -/** - * low-latency ALSA access through JNI wrapper - * - * @author Jean Lorchat - * @author Lubomir Marinov - */ -public class DataSource - extends PushBufferDataSource -{ - protected boolean started = false; - protected boolean connected = false; - protected Time duration = DURATION_UNKNOWN; - protected AlsaStream [] streams = null; - protected AlsaStream stream = null; - - /** - * Constructs a new ALSA DataSource. - */ - public DataSource() - { - } - - /** - * Gets the type of the content made available by this DataSource - * (i.e. raw). - * - * @return the type of the content made available by this - * DataSource (i.e. raw) - */ - public String getContentType() - { - return ContentDescriptor.RAW; - } - - /** - * Connect the datasource - */ - public void connect() throws IOException - { - if (connected) - return; - connected = true; - } - - /** - * Disconnect the datasource - */ - public void disconnect() - { - try - { - if (started) - stop(); - } - catch (IOException e) {} - connected = false; - } - - /** - * Start the datasource and the underlying stream - */ - public void start() throws IOException - { - if (!connected) - throw new java.lang.Error("DataSource must be connected"); - - if (started) - return; - - started = true; - stream.start(true); - } - - /** - * Stop the datasource and it's underlying stream - */ - public void stop() throws IOException - { - if ((!connected) || (!started)) - return; - - started = false; - stream.start(false); - } - - /** - * Gives control information to the caller. - */ - public Object [] getControls() - { - return ControlsAdapter.EMPTY_CONTROLS; - } - - /** - * Return required control from the Control[] array - * if exists, that is - */ - public Object getControl(String controlType) - { - return AbstractControls.getControl(this, controlType); - } - - /** - * Gives to the caller the duration information of our stream - * Which is, obviously unknown. Better turn on that premonition - * switch again, Mrs Cake. - * - * @return DURATION_UNKNOWN - */ - public Time getDuration() - { - return duration; - } - - /** - * Returns an array of PushBufferStream containing all the streams - * i.e. only one in our case : only sound - * - * If no stream actually exists, instanciate one on the fly - * - * @return Array of one stream - */ - public PushBufferStream [] getStreams() - { - if (streams == null) - { - streams = new AlsaStream[1]; - stream = streams[0] = new AlsaStream(); - } - return streams; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/directshow/DataSource.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/directshow/DataSource.java deleted file mode 100644 index 989c98f0a..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/directshow/DataSource.java +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.directshow; - -import java.io.*; -import java.util.*; -import java.awt.Dimension; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.codec.video.*; -import net.java.sip.communicator.impl.neomedia.control.*; -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.impl.neomedia.directshow.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.*; -import net.java.sip.communicator.util.*; - -/** - * Implements a CaptureDevice and a DataSource using - * DirectShow. - * - * @author Lyubomir Marinov - * @author Sebastien Vincent - */ -public class DataSource - extends AbstractVideoPushBufferCaptureDevice -{ - /** - * The Logger used by the DataSource class and its - * instances for logging output. - */ - private static final Logger logger = Logger.getLogger(DataSource.class); - - /** - * DirectShow capture device. - */ - private DSCaptureDevice device = null; - - /** - * Delegate grabber. Each frame captured by device will be pass through this - * grabber. - */ - private DSCaptureDevice.GrabberDelegate grabber = null; - - - /** - * DirectShow manager. - */ - private DSManager manager = null; - - /** - * The map of DirectShow pixel formats to FFmpeg - * pixel formats which allows converting between the two. - */ - private static final long[] DS_TO_FFMPEG_PIX_FMT - = new long[] - { - DSFormat.RGB24, - FFmpeg.PIX_FMT_RGB24, - DSFormat.RGB32, - FFmpeg.PIX_FMT_RGB32, - DSFormat.ARGB32, - FFmpeg.PIX_FMT_ARGB, - DSFormat.YUY2, - FFmpeg.PIX_FMT_YUYV422, - DSFormat.UYVY, - FFmpeg.PIX_FMT_UYVY422, - DSFormat.Y411, - FFmpeg.PIX_FMT_UYYVYY411, - DSFormat.Y41P, - FFmpeg.PIX_FMT_UYYVYY411, - DSFormat.NV12, - FFmpeg.PIX_FMT_NV12, - DSFormat.I420, - FFmpeg.PIX_FMT_YUV420P, - }; - - /** - * Last known native DirectShow format. - */ - private DSFormat nativeFormat = null; - - /** - * Constructor. - */ - public DataSource() - { - manager = DSManager.getInstance(); - } - - /** - * Initializes a new DataSource instance from a specific - * MediaLocator. - * - * @param locator the MediaLocator to create the new instance from - */ - public DataSource(MediaLocator locator) - { - super(locator); - manager = DSManager.getInstance(); - } - - /** - * Sets the MediaLocator which specifies the media source of this - * DataSource. - * - * @param locator the MediaLocator which specifies the media source - * of this DataSource - * @see DataSource#setLocator(MediaLocator) - */ - @Override - public void setLocator(MediaLocator locator) - { - DSCaptureDevice device = null; - logger.info("set locator to " + locator); - - if(getLocator() == null) - super.setLocator(locator); - locator = getLocator(); - logger.info("getLocator() returns " + locator); - - if((locator != null) && - DeviceSystem.LOCATOR_PROTOCOL_DIRECTSHOW.equalsIgnoreCase( - locator.getProtocol())) - { - DSCaptureDevice[] devices = manager.getCaptureDevices(); - - logger.info("Search directshow device..."); - - /* find device */ - for(int i = 0 ; i < devices.length ; i++) - { - if(devices[i].getName().equals(locator.getRemainder())) - { - device = devices[i]; - logger.info("Set directshow device: " + device); - break; - } - } - - if(device == null) - { - logger.info("No devices matches locator's remainder: " + - locator.getRemainder()); - } - } - else - { - logger.info( - "MediaLocator either null or does not have right protocol"); - device = null; - } - setDevice(device); - } - - /** - * Sets the DSCaptureDevice which represents the media source of - * this DataSource. - * - * @param device the DSCaptureDevice which represents the media - * source of this DataSource - */ - private void setDevice(DSCaptureDevice device) - { - if(this.device != device) - { - this.device = device; - } - } - - /** - * Creates a new FrameRateControl instance which is to allow the - * getting and setting of the frame rate of this - * AbstractVideoPushBufferCaptureDevice. - * - * @return a new FrameRateControl instance which is to allow the - * getting and setting of the frame rate of this - * AbstractVideoPushBufferCaptureDevice - * @see AbstractPushBufferCaptureDevice#createFrameRateControl() - */ - @Override - protected FrameRateControl createFrameRateControl() - { - return - new FrameRateControlAdapter() - { - /** - * The output frame rate of this - * AbstractVideoPullBufferCaptureDevice. - */ - private float frameRate = -1; - - @Override - public float getFrameRate() - { - return frameRate; - } - - @Override - public float setFrameRate(float frameRate) - { - this.frameRate = frameRate; - return this.frameRate; - } - }; - } - - /** - * Create a new PushBufferStream which is to be at a specific - * zero-based index in the list of streams of this - * PushBufferDataSource. The Format-related information of - * the new instance is to be abstracted by a specific - * FormatControl. - * - * @param streamIndex the zero-based index of the PushBufferStream - * in the list of streams of this PushBufferDataSource - * @param formatControl the FormatControl which is to abstract the - * Format-related information of the new instance - * @return a new PushBufferStream which is to be at the specified - * streamIndex in the list of streams of this - * PushBufferDataSource and which has its Format-related - * information abstracted by the specified formatControl - * @see AbstractPushBufferCaptureDevice#createStream(int, FormatControl) - */ - protected AbstractPushBufferStream createStream( - int streamIndex, - FormatControl formatControl) - { - DirectShowStream stream = new DirectShowStream(this, formatControl); - - if (logger.isTraceEnabled()) - { - DSFormat deviceFmts[] = device.getSupportedFormats(); - - for (DSFormat deviceFmt : deviceFmts) - { - logger.trace( - "width= " + deviceFmt.getWidth() - + ", height= " + deviceFmt.getHeight() - + ", pixelFormat= " + deviceFmt.getPixelFormat()); - } - } - - grabber = stream.grabber; - - return stream; - } - - /** - * Gets the Formats which are to be reported by a - * FormatControl as supported formats for a - * PushBufferStream at a specific zero-based index in the list of - * streams of this PushBufferDataSource. - * - * @param streamIndex the zero-based index of the PushBufferStream - * for which the specified FormatControl is to report the list of - * supported Formats - * @return an array of Formats to be reported by a - * FormatControl as the supported formats for the - * PushBufferStream at the specified streamIndex in the - * list of streams of this PushBufferDataSource - * @see AbstractPushBufferCaptureDevice#getSupportedFormats(int) - */ - @Override - protected Format[] getSupportedFormats(int streamIndex) - { - if(device == null) - return new Format[0]; - - DSFormat[] deviceFmts = device.getSupportedFormats(); - List fmts = new ArrayList(deviceFmts.length); - - for (DSFormat deviceFmt : deviceFmts) - { - Dimension size - = new Dimension(deviceFmt.getWidth(), deviceFmt.getHeight()); - long devicePixFmt = deviceFmt.getPixelFormat(); - int pixFmt = (int) getFFmpegPixFmt(devicePixFmt); - - fmts.add( - new AVFrameFormat( - size, - Format.NOT_SPECIFIED, - pixFmt, (int) devicePixFmt)); - } - return fmts.toArray(new Format[fmts.size()]); - } - - /** - * Attempts to set the Format to be reported by the - * FormatControl of a PushBufferStream at a specific - * zero-based index in the list of streams of this - * PushBufferDataSource. The PushBufferStream does not - * exist at the time of the attempt to set its Format. - * - * @param streamIndex the zero-based index of the PushBufferStream - * the Format of which is to be set - * @param oldValue the last-known Format for the - * PushBufferStream at the specified streamIndex - * @param newValue the Format which is to be set - * @return the Format to be reported by the FormatControl - * of the PushBufferStream at the specified streamIndex - * in the list of streams of this PushBufferStream or null - * if the attempt to set the Format did not success and any - * last-known Format is to be left in effect - * @see AbstractPushBufferCaptureDevice#setFormat(int, Format, Format) - */ - @Override - protected Format setFormat( - int streamIndex, - Format oldValue, Format newValue) - { - if(newValue instanceof VideoFormat) - { - if(newValue instanceof AVFrameFormat) - { - AVFrameFormat newAVFrameFormatValue - = (AVFrameFormat) newValue; - long pixelFormat = newAVFrameFormatValue.getDevicePixFmt(); - - if(pixelFormat != -1) - { - Dimension size = newAVFrameFormatValue.getSize(); - - /* - * We will set the native format in doStart() because a - * connect-disconnect-connect sequence of the native - * capture device may reorder its formats in a different - * way. Consequently, in the absence of further calls to - * setFormat() by JMF, a crash may occur later (typically, - * during scaling) because of a wrong format. - */ - nativeFormat - = new DSFormat( - size.width, size.height, - pixelFormat); - } - } - - // This DataSource supports setFormat. - return newValue; - } - else - return super.setFormat(streamIndex, oldValue, newValue); - } - - /** - * Opens a connection to the media source specified by the - * MediaLocator of this DataSource. - * - * @throws IOException if anything goes wrong while opening the connection - * to the media source specified by the MediaLocator of this - * DataSource - * @see AbstractPushBufferCaptureDevice#doConnect() - */ - @Override - protected void doConnect() throws IOException - { - if (logger.isInfoEnabled()) - logger.info("doConnect"); - - if(manager == null) - manager = DSManager.getInstance(); - - setLocator(getLocator()); - - super.doConnect(); - } - - /** - * Closes the connection to the media source specified by the - * MediaLocator of this DataSource. - * - * @see AbstractPushBufferCaptureDevice#doDisconnect() - */ - @Override - protected void doDisconnect() - { - if (logger.isInfoEnabled()) - logger.info("doDisconnect"); - - super.doDisconnect(); - - if(manager != null) - { - device.setDelegate(null); - device = null; - - DSManager.dispose(); - manager = null; - } - } - - /** - * Starts the transfer of media data from this DataSource. - * - * @throws IOException if anything goes wrong while starting the transfer of - * media data from this DataSource - * @see AbstractPushBufferCaptureDevice#doStart() - */ - @Override - protected void doStart() throws IOException - { - if (logger.isInfoEnabled()) - logger.info("start"); - - /* open and start capture */ - device.open(); - if(nativeFormat != null) - device.setFormat(nativeFormat); - - device.setDelegate(grabber); - - super.doStart(); - } - - /** - * Stops the transfer of media data from this DataSource. - * - * @throws IOException if anything goes wrong while stopping the transfer of - * media data from this DataSource - * @see AbstractPushBufferCaptureDevice#doStop() - */ - @Override - protected void doStop() throws IOException - { - if (logger.isInfoEnabled()) - logger.info("stop"); - - /* close capture */ - super.doStop(); - device.close(); - } - - /** - * Gets the DirectShow pixel format matching a specific FFmpeg pixel - * format. - * - * @param dsPixFmt the DirectShow pixel format to get the matching - * FFmpeg pixel format of - * @return the FFmpeg pixel format matching the specified DirectShow pixel - */ - public static long getFFmpegPixFmt(long dsPixFmt) - { - for (int i = 0; i < DS_TO_FFMPEG_PIX_FMT.length; i += 2) - if (DS_TO_FFMPEG_PIX_FMT[i] == dsPixFmt) - return DS_TO_FFMPEG_PIX_FMT[i + 1]; - return FFmpeg.PIX_FMT_NONE; - } - - /** - * Gets the FFmpeg pixel format matching a specific DirectShow - * Specification pixel format. - * - * @param ffmpegPixFmt FFmpeg format - * @return the DirectShow pixel format matching the specified FFmpeg format - */ - public static long getDSPixFmt(int ffmpegPixFmt) - { - for (int i = 0; i < DS_TO_FFMPEG_PIX_FMT.length; i += 2) - if (DS_TO_FFMPEG_PIX_FMT[i + 1] == ffmpegPixFmt) - return DS_TO_FFMPEG_PIX_FMT[i]; - return -1; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/directshow/DirectShowStream.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/directshow/DirectShowStream.java deleted file mode 100644 index 02d83f68b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/directshow/DirectShowStream.java +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.directshow; - -import java.io.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.codec.video.*; -import net.java.sip.communicator.impl.neomedia.directshow.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.*; - -/** - * Implements a PushBufferStream using DirectShow. - * - * @author Lyubomir Marinov - * @author Sebastien Vincent - */ -public class DirectShowStream extends AbstractPushBufferStream -{ - /** - * The pool of ByteBuffers this instances is using to transfer the - * media data captured by {@link #grabber} out of this instance - * through the Buffers specified in its {@link #read(Buffer)}. - */ - private final ByteBufferPool bufferPool = new ByteBufferPool(); - - /** - * The captured media data to be returned in {@link #read(Buffer)}. - */ - private ByteBuffer data; - - /** - * The Object which synchronizes the access to the - * {@link #data}-related fields of this instance. - */ - private final Object dataSyncRoot = new Object(); - - /** - * The time stamp in nanoseconds of {@link #data}. - */ - private long dataTimeStamp; - - /** - * The last-known Format of the media data made available by this - * PushBufferStream. - */ - private final Format format; - - /** - * The captured media data to become the value of {@link #data} as soon as - * the latter becomes is consumed. Thus prepares this - * DirectShowStream to provide the latest available frame and not - * wait for DirectShow to capture a new one. - */ - private ByteBuffer nextData = null; - - /** - * The time stamp in nanoseconds of {@link #nextData}. - */ - private long nextDataTimeStamp; - - /** - * The Thread which is to call - * {@link BufferTransferHandler#transferData(PushBufferStream)} for this - * DirectShowStream so that the call is not made in DirectShow - * and we can drop late frames when - * {@link #automaticallyDropsLateVideoFrames} is false. - */ - private Thread transferDataThread; - - /** - * The indicator which determines whether {@link #grabber} - * automatically drops late frames. If false, we have to drop them - * ourselves because DirectShow will buffer them all and the video will - * be late. - */ - private boolean automaticallyDropsLateVideoFrames = false; - - /** - * Delegate class to handle video data. - */ - final DSCaptureDevice.GrabberDelegate grabber - = new DSCaptureDevice.GrabberDelegate() - { - @Override - public void frameReceived(long ptr, int length) - { - processFrame(ptr, length); - } - }; - - /** - * Initializes a new DirectShowStream instance which is to have its - * Format-related information abstracted by a specific - * FormatControl. - * - * @param dataSource the DataSource which is creating the new - * instance so that it becomes one of its streams - * @param formatControl the FormatControl which is to abstract the - * Format-related information of the new instance - */ - DirectShowStream(DataSource dataSource, FormatControl formatControl) - { - super(dataSource, formatControl); - - format = (VideoFormat) formatControl.getFormat(); - } - - /** - * Process received frames from DirectShow capture device - * - * @param ptr native pointer to data - * @param length length of data - */ - private void processFrame(long ptr, int length) - { - boolean transferData = false; - - synchronized (dataSyncRoot) - { - if(!automaticallyDropsLateVideoFrames && (data != null)) - { - if(nextData != null) - { - bufferPool.returnFreeBuffer(nextData); - nextData = null; - } - - nextData - = bufferPool.getFreeBuffer(length); - if(nextData != null) - { - nextData.setLength( - DSCaptureDevice.getBytes(ptr, - nextData.ptr, - nextData.capacity)); - nextDataTimeStamp = System.nanoTime(); - } - - return; - } - - if(data != null) - { - bufferPool.returnFreeBuffer(data); - data = null; - } - - data = bufferPool.getFreeBuffer(length); - if(data != null) - { - data.setLength(DSCaptureDevice.getBytes(ptr, - data.ptr, data.capacity)); - dataTimeStamp = System.nanoTime(); - } - - if(nextData != null) - { - bufferPool.returnFreeBuffer(nextData); - nextData = null; - } - - if(automaticallyDropsLateVideoFrames) - transferData = (data != null); - else - { - transferData = false; - dataSyncRoot.notifyAll(); - } - } - - if(transferData) - { - BufferTransferHandler transferHandler = this.transferHandler; - - if(transferHandler != null) - transferHandler.transferData(this); - } - } - - /** - * Gets the Format of this PushBufferStream as directly - * known by it. - * - * @return the Format of this PushBufferStream as directly - * known by it or null if this PushBufferStream does not - * directly know its Format and it relies on the - * PushBufferDataSource which created it to report its - * Format - */ - @Override - protected Format doGetFormat() - { - return (this.format == null) ? super.doGetFormat() : this.format; - } - - /** - * Releases the resources used by this instance throughout its existence and - * makes it available for garbage collection. This instance is considered - * unusable after closing. - * - * @see AbstractPushBufferStream#close() - */ - @Override - public void close() - { - bufferPool.close(); - } - - /** - * Calls {@link BufferTransferHandler#transferData(PushBufferStream)} from - * inside {@link #transferDataThread} so that the call is not made in - * DirectShow and we can drop late frames in the meantime. - */ - private void runInTransferDataThread() - { - boolean transferData = false; - FrameRateControl frameRateControl - = (FrameRateControl) - dataSource.getControl(FrameRateControl.class.getName()); - long transferDataTimeStamp = -1; - - while (Thread.currentThread().equals(transferDataThread)) - { - if (transferData) - { - BufferTransferHandler transferHandler = this.transferHandler; - - if (transferHandler != null) - { - /* - * Respect the frame rate specified through the - * FrameRateControl of the associated DataSource. - */ - if (frameRateControl != null) - { - float frameRate; - long newTransferDataTimeStamp - = System.currentTimeMillis(); - - if ((transferDataTimeStamp != -1) - && ((frameRate - = frameRateControl.getFrameRate()) - > 0)) - { - long minimumVideoFrameInterval - = (long) (1000 / frameRate); - - if (minimumVideoFrameInterval > 0) - { - long t - = newTransferDataTimeStamp - - transferDataTimeStamp; - - if ((t > 0) && (t < minimumVideoFrameInterval)) - { - boolean interrupted = false; - - try - { - Thread.sleep( - minimumVideoFrameInterval - t); - } - catch (InterruptedException ie) - { - interrupted = true; - } - if (interrupted) - Thread.currentThread().interrupt(); - continue; - } - } - } - - transferDataTimeStamp = newTransferDataTimeStamp; - } - - transferHandler.transferData(this); - } - - synchronized (dataSyncRoot) - { - if(data != null) - { - bufferPool.returnFreeBuffer(data); - data = null; - } - - data = nextData; - dataTimeStamp = nextDataTimeStamp; - nextData = null; - } - } - - synchronized (dataSyncRoot) - { - if (data == null) - { - data = nextData; - dataTimeStamp = nextDataTimeStamp; - nextData = null; - } - if (data == null) - { - boolean interrupted = false; - - try - { - dataSyncRoot.wait(); - } - catch (InterruptedException iex) - { - interrupted = true; - } - if(interrupted) - Thread.currentThread().interrupt(); - - transferData = (data != null); - } - else - transferData = true; - } - } - } - - /** - * Starts the transfer of media data from this PushBufferStream. - * - * @throws IOException if anything goes wrong while starting the transfer of - * media data from this PushBufferStream - */ - @Override - public void start() throws IOException - { - if(!automaticallyDropsLateVideoFrames) - { - transferDataThread - = new Thread(getClass().getSimpleName()) - { - @Override - public void run() - { - runInTransferDataThread(); - } - }; - transferDataThread.start(); - } - } - - /** - * Stops the transfer of media data from this PushBufferStream. - * - * @throws IOException if anything goes wrong while stopping the transfer of - * media data from this PushBufferStream - */ - @Override - public void stop() throws IOException - { - transferDataThread = null; - - synchronized (dataSyncRoot) - { - if(data != null) - { - bufferPool.returnFreeBuffer(data); - data = null; - } - - if(nextData != null) - { - bufferPool.returnFreeBuffer(nextData); - nextData = null; - } - - if(!automaticallyDropsLateVideoFrames) - dataSyncRoot.notifyAll(); - } - } - - /** - * Reads media data from this PushBufferStream into a specific - * Buffer without blocking. - * - * @param buffer the Buffer in which media data is to be read from - * this PushBufferStream - * @throws IOException if anything goes wrong while reading media data from - * this PushBufferStream into the specified buffer - */ - public void read(Buffer buffer) throws IOException - { - synchronized (dataSyncRoot) - { - if(data == null) - { - buffer.setLength(0); - return; - } - - Format bufferFormat = buffer.getFormat(); - - if(bufferFormat == null) - { - bufferFormat = getFormat(); - if(bufferFormat != null) - buffer.setFormat(bufferFormat); - } - if(bufferFormat instanceof AVFrameFormat) - { - FinalizableAVFrame.read( - buffer, - bufferFormat, - data, - bufferPool); - } - else - { - Object bufferData = buffer.getData(); - byte[] bufferByteData; - int dataLength = data.getLength(); - - if(bufferData instanceof byte[]) - { - bufferByteData = (byte[]) bufferData; - if(bufferByteData.length < dataLength) - bufferByteData = null; - } - else - bufferByteData = null; - if(bufferByteData == null) - { - bufferByteData = new byte[dataLength]; - buffer.setData(bufferByteData); - } - - /* XXX */ - //DSCaptureDevice.getBytes(bufferByteData, 0, dataLength, - // data.ptr); - //CVPixelBuffer.memcpy(bufferByteData, 0, dataLength, data.ptr); - - buffer.setLength(dataLength); - buffer.setOffset(0); - - bufferPool.returnFreeBuffer(data); - } - - buffer.setFlags(Buffer.FLAG_LIVE_DATA | Buffer.FLAG_SYSTEM_TIME); - buffer.setTimeStamp(dataTimeStamp); - - data = null; - if(!automaticallyDropsLateVideoFrames) - dataSyncRoot.notifyAll(); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/DataSource.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/DataSource.java deleted file mode 100644 index 4e5e5898d..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/DataSource.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.imgstreaming; - -import javax.media.*; -import javax.media.control.*; - -import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.*; -import net.java.sip.communicator.impl.neomedia.protocol.*; - -/** - * Implements CaptureDevice and DataSource for the purposes of - * image and desktop streaming. - * - * @author Sebastien Vincent - * @author Lyubomir Marinov - * @author Damian Minkov - */ -public class DataSource - extends AbstractVideoPullBufferCaptureDevice - implements Controls -{ - /** - * Stream created. - */ - private ImageStream stream = null; - - /** - * Initializes a new DataSource instance. - */ - public DataSource() - { - } - - /** - * Initializes a new DataSource instance. - * - * @param locator associated MediaLocator - */ - public DataSource(MediaLocator locator) - { - super(locator); - } - - /** - * Set origin of ImageStream. - * - * @param streamIndex stream index - * @param monitorIndex monitor index - * @param x x coordinate - * @param y y coordinate - */ - public void setOrigin(int streamIndex, int monitorIndex, int x, int y) - { - if(stream != null) - { - stream.setOrigin(x, y); - stream.setDisplayIndex(monitorIndex); - } - } - - /** - * Creates a new PullBufferStream which is to be at a specific - * zero-based index in the list of streams of this - * PullBufferDataSource. The Format-related information of - * the new instance is to be abstracted by a specific - * FormatControl. - * - * @param streamIndex the zero-based index of the PullBufferStream - * in the list of streams of this PullBufferDataSource - * @param formatControl the FormatControl which is to abstract the - * Format-related information of the new instance - * @return a new PullBufferStream which is to be at the specified - * streamIndex in the list of streams of this - * PullBufferDataSource and which has its Format-related - * information abstracted by the specified formatControl - * @see AbstractPullBufferCaptureDevice#createStream(int, FormatControl) - */ - protected AbstractPullBufferStream createStream( - int streamIndex, - FormatControl formatControl) - { - /* - * full desktop: remainder => index - * part of desktop: remainder => index,x,y - */ - String remainder = getLocator().getRemainder(); - String split[] = remainder.split(","); - int index = -1; - int x = 0; - int y = 0; - - if ((split != null) && (split.length > 1)) - { - index = Integer.parseInt(split[0]); - x = Integer.parseInt(split[1]); - y = Integer.parseInt(split[2]); - } - else - { - index = Integer.parseInt(remainder); - } - - ImageStream stream = new ImageStream(this, formatControl); - - stream.setDisplayIndex(index); - stream.setOrigin(x, y); - - this.stream = stream; - return stream; - } - - /** - * Implements {@link Controls#getControl(String)}. Invokes - * {@link #getControls()} and then looks for a control of the specified type - * in the returned array of controls. - * - * @param controlType a String value naming the type of the control - * of this instance to be retrieved - * @return an Object which represents the control of this instance - * with the specified type - */ - public Object getControl(String controlType) - { - if(controlType == this.getClass().getName()) - { - return this; - } - else - { - return super.getControl(controlType); - } - } - - /** - * Implements {@link Controls#getControl(String)}. Invokes - * {@link #getControls()} and then looks for a control of the specified type - * in the returned array of controls. - * - * @param controlType a String value naming the type of the control - * of this instance to be retrieved - * @return an Object which represents the control of this instance - * with the specified type - */ - public Object[] getControls() - { - Object[] thisControls; - Object[] superControls = super.getControls(); - if(superControls != null) - { - thisControls = new Object[superControls.length + 1]; - System.arraycopy( - superControls, 0, - thisControls, 0, - superControls.length); - thisControls[superControls.length] = this; - } - else - { - thisControls = new Object[]{this}; - } - return thisControls; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java deleted file mode 100644 index 588dd9ef4..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.imgstreaming; - -import java.awt.*; -import java.awt.image.*; -import java.io.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.codec.video.*; -import net.java.sip.communicator.impl.neomedia.imgstreaming.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.*; -import net.java.sip.communicator.util.*; - -/** - * The stream used by JMF for our image streaming. - * - * @author Sebastien Vincent - * @author Lyubomir Marinov - * @author Damian Minkov - */ -public class ImageStream - extends AbstractVideoPullBufferStream -{ - /** - * The Logger - */ - private static final Logger logger = Logger.getLogger(ImageStream.class); - - /** - * Sequence number. - */ - private long seqNo = 0; - - /** - * Desktop interaction (screen capture, key press, ...). - */ - private DesktopInteract desktopInteract = null; - - /** - * Native buffer pointer. - */ - private ByteBuffer data = null; - - /** - * If stream has been reinitialized. - */ - private boolean reinit = false; - - /** - * Index of display that we will capture from. - */ - private int displayIndex = -1; - - /** - * X origin. - */ - private int x = 0; - - /** - * Y origin. - */ - private int y = 0; - - /** - * Initializes a new ImageStream instance which is to have a - * specific FormatControl - * - * @param dataSource the DataSource which is creating the new - * instance so that it becomes one of its streams - * @param formatControl the FormatControl of the new instance which - * is to specify the format in which it is to provide its media data - */ - ImageStream(DataSource dataSource, FormatControl formatControl) - { - super(dataSource, formatControl); - } - - /** - * Blocks and reads into a Buffer from this - * PullBufferStream. - * - * @param buffer the Buffer this PullBufferStream is to - * read into - * @throws IOException if an I/O error occurs while this - * PullBufferStream reads into the specified Buffer - * @see AbstractVideoPullBufferStream#doRead(Buffer) - */ - protected void doRead(Buffer buffer) - throws IOException - { - /* - * Determine the Format in which we're expected to output. We cannot - * rely on the Format always being specified in the Buffer because it is - * not its responsibility, the DataSource of this ImageStream knows the - * output Format. - */ - Format bufferFormat = buffer.getFormat(); - - if (bufferFormat == null) - { - bufferFormat = getFormat(); - if (bufferFormat != null) - buffer.setFormat(bufferFormat); - } - - if(bufferFormat instanceof AVFrameFormat) - { - /* - * Native transfer: we keep data in native memory rather than the - * Java heap until we reach SwScaler. - */ - Object dataAv = buffer.getData(); - AVFrame bufferFrame = null; - long bufferFramePtr = 0; - - if (dataAv instanceof AVFrame) - { - bufferFrame = (AVFrame)dataAv; - bufferFramePtr = bufferFrame.getPtr(); - } - else - { - bufferFrame = new FinalizableAVFrame(); - bufferFramePtr = bufferFrame.getPtr(); - } - - AVFrameFormat bufferFrameFormat = (AVFrameFormat) bufferFormat; - Dimension bufferFrameSize = bufferFrameFormat.getSize(); - - if(readScreenNative(bufferFrameSize)) - { - FFmpeg.avpicture_fill( - bufferFramePtr, - data.ptr, - bufferFrameFormat.getPixFmt(), - bufferFrameSize.width, bufferFrameSize.height); - buffer.setData(bufferFrame); - } - else - { - /* this can happen when we disconnect a monitor from computer - * before or during grabbing - */ - throw new IOException("Failed to grab screen"); - } - } - else - { - byte dataByte[] = (byte[])buffer.getData(); - int dataLength = (dataByte != null) ? dataByte.length : 0; - - if((dataByte != null) || (dataLength != 0)) - { - Dimension bufferFrameSize = - ((VideoFormat)bufferFormat).getSize(); - byte buf[] = readScreen(dataByte, bufferFrameSize); - - if(buf != dataByte) - { - /* readScreen returns us a different buffer than JMF ones, - * it means that JMF's initial buffer was too short. - */ - //System.out.println("use our own buffer"); - buffer.setData(buf); - } - - buffer.setOffset(0); - buffer.setLength(buf.length); - } - } - - buffer.setHeader(null); - buffer.setTimeStamp(System.nanoTime()); - buffer.setSequenceNumber(seqNo); - buffer.setFlags(Buffer.FLAG_SYSTEM_TIME | Buffer.FLAG_LIVE_DATA); - seqNo++; - } - - /** - * Set display index. - * - * @param index display index - */ - public void setDisplayIndex(int index) - { - displayIndex = index; - } - - /** - * Set Origin of capture. - * - * @param x x coordinate - * @param y y coordinate - */ - public void setOrigin(int x, int y) - { - this.x = x; - this.y = y; - } - - /** - * Start desktop capture stream. - * - * @see AbstractPullBufferStream#start() - */ - @Override - public void start() - { - if(desktopInteract == null) - { - try - { - desktopInteract = new DesktopInteractImpl(); - } - catch(Exception e) - { - logger.warn("Cannot create DesktopInteract object!"); - } - } - - reinit = true; - } - - /** - * Stop desktop capture stream. - * - * @see AbstractPullBufferStream#stop() - */ - @Override - public void stop() - { - if (logger.isInfoEnabled()) - logger.info("Stop stream"); - } - - /** - * Read screen and store result in native buffer. - * - * @param dim dimension of the video - * @return true if success, false otherwise - */ - private boolean readScreenNative(Dimension dim) - { - int size = dim.width * dim.height * 4; - - /* pad the buffer */ - size += FFmpeg.FF_INPUT_BUFFER_PADDING_SIZE; - - /* allocate native array */ - if(data == null || reinit) - { - data = new ByteBuffer(size); - data.setLength(size); - reinit = false; - } - else if(data.capacity < size) - { - /* reallocate native array if capacity is not enough */ - data.setFree(true); - FFmpeg.av_free(data.ptr); - data = new ByteBuffer(size); - data.setLength(size); - } - - /* get desktop screen via native grabber */ - return desktopInteract.captureScreen(displayIndex, x, y, dim.width, - dim.height, data.ptr, data.getLength()); - } - - /** - * Read screen. - * - * @param output output buffer for screen bytes - * @param dim dimension of the screen - * @return raw bytes, it could be equal to output or not. Take care in the - * caller to check if output is the returned value. - */ - public byte[] readScreen(byte output[], Dimension dim) - { - VideoFormat format = (VideoFormat) getFormat(); - Dimension formatSize = format.getSize(); - int width = (int) formatSize.getWidth(); - int height = (int) formatSize.getHeight(); - BufferedImage scaledScreen = null; - BufferedImage screen = null; - byte data[] = null; - int size = width * height * 4; - - /* check if output buffer can hold all the screen - * if not allocate our own buffer - */ - if(output.length < size) - { - output = null; - output = new byte[size]; - } - - /* get desktop screen via native grabber if available */ - if(desktopInteract.captureScreen(displayIndex, x, y, dim.width, - dim.height, output)) - { - return output; - } - - System.out.println("failed to grab with native! " + output.length); - - /* OK native grabber failed or is not available, - * try with AWT Robot and convert it to the right format - * - * Note that it is very memory consuming since memory are allocated - * to capture screen (via Robot) and then for converting to raw bytes - * Moreover support for multiple display has not yet been investigated - * - * Normally not of our supported platform (Windows (x86, x64), - * Linux (x86, x86-64), Mac OS X (i386, x86-64, ppc) and - * FreeBSD (x86, x86-64) should go here. - */ - screen = desktopInteract.captureScreen(); - - if(screen != null) - { - /* convert to ARGB BufferedImage */ - scaledScreen - = ImageStreamingUtils - .getScaledImage( - screen, - width, - height, - BufferedImage.TYPE_INT_ARGB); - - /* get raw bytes */ - data = ImageStreamingUtils.getImageBytes(scaledScreen, output); - } - - screen = null; - scaledScreen = null; - return data; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/portaudio/DataSource.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/portaudio/DataSource.java deleted file mode 100644 index 0130ec28e..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/portaudio/DataSource.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.portaudio; - -import java.io.*; - -import javax.media.*; -import javax.media.control.*; - -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.*; -import net.java.sip.communicator.impl.neomedia.portaudio.*; -import net.java.sip.communicator.util.*; - -/** - * Implements DataSource and CaptureDevice for PortAudio. - * - * @author Damian Minkov - * @author Lyubomir Marinov - */ -public class DataSource - extends AbstractPullBufferCaptureDevice -{ - /** - * The Logger used by the DataSource class and its - * instances for logging output. - */ - private static final Logger logger = Logger.getLogger(DataSource.class); - - /** - * The indicator which determines whether this DataSource will - * use audio quality improvement in accord with the preferences of the user. - */ - private final boolean audioQualityImprovement; - - /** - * The list of Formats in which this DataSource is - * capable of capturing audio data. - */ - private final Format[] supportedFormats; - - /** - * Initializes a new DataSource instance. - */ - public DataSource() - { - this.supportedFormats = null; - this.audioQualityImprovement = true; - } - - /** - * Initializes a new DataSource instance from a specific - * MediaLocator. - * - * @param locator the MediaLocator to create the new instance from - */ - public DataSource(MediaLocator locator) - { - this(locator, null, true); - } - - /** - * Initializes a new DataSource instance from a specific - * MediaLocator and which has a specific list of Format - * in which it is capable of capturing audio data overriding its - * registration with JMF and optionally uses audio quality improvement in - * accord with the preferences of the user. - * - * @param locator the MediaLocator to create the new instance from - * @param supportedFormats the list of Formats in which the new - * instance is to be capable of capturing audio data - * @param audioQualityImprovement true if audio quality improvement - * is to be enabled in accord with the preferences of the user or - * false to completely disable audio quality improvement - */ - public DataSource( - MediaLocator locator, - Format[] supportedFormats, - boolean audioQualityImprovement) - { - super(locator); - - this.supportedFormats - = (supportedFormats == null) - ? null - : supportedFormats.clone(); - this.audioQualityImprovement = audioQualityImprovement; - } - - /** - * Creates a new PullBufferStream which is to be at a specific - * zero-based index in the list of streams of this - * PullBufferDataSource. The Format-related information of - * the new instance is to be abstracted by a specific - * FormatControl. - * - * @param streamIndex the zero-based index of the PullBufferStream - * in the list of streams of this PullBufferDataSource - * @param formatControl the FormatControl which is to abstract the - * Format-related information of the new instance - * @return a new PullBufferStream which is to be at the specified - * streamIndex in the list of streams of this - * PullBufferDataSource and which has its Format-related - * information abstracted by the specified formatControl - * @see AbstractPullBufferCaptureDevice#createStream(int, FormatControl) - */ - protected AbstractPullBufferStream createStream( - int streamIndex, - FormatControl formatControl) - { - return - new PortAudioStream(this, formatControl, audioQualityImprovement); - } - - /** - * Opens a connection to the media source specified by the - * MediaLocator of this DataSource. - * - * @throws IOException if anything goes wrong while opening the connection - * to the media source specified by the MediaLocator of this - * DataSource - * @see AbstractPullBufferCaptureDevice#doConnect() - */ - @Override - protected void doConnect() - throws IOException - { - super.doConnect(); - - int deviceIndex = getDeviceIndex(); - - synchronized (getStreamSyncRoot()) - { - for (Object stream : getStreams()) - ((PortAudioStream) stream).setDeviceIndex(deviceIndex); - } - } - - /** - * Closes the connection to the media source specified by the - * MediaLocator of this DataSource. Allows extenders to - * override and be sure that there will be no request to close a connection - * if the connection has not been opened yet. - */ - @Override - protected void doDisconnect() - { - try - { - synchronized (getStreamSyncRoot()) - { - Object[] streams = streams(); - - if (streams != null) - { - for (Object stream : streams) - { - try - { - ((PortAudioStream) stream).setDeviceIndex( - PortAudio.paNoDevice); - } - catch (IOException ioex) - { - logger.error( - "Failed to close " - + stream.getClass().getSimpleName(), - ioex); - } - } - } - } - } - finally - { - super.doDisconnect(); - } - } - - /** - * Gets the device index of the PortAudio device identified by the - * MediaLocator of this DataSource. - * - * @return the device index of a PortAudio device identified by the - * MediaLocator of this DataSource - */ - private int getDeviceIndex() - { - MediaLocator locator = getLocator(); - - if (locator == null) - throw new NullPointerException("locator"); - return getDeviceIndex(locator); - } - - /** - * Gets the device index of a PortAudio device from a specific - * MediaLocator identifying it. - * - * @param locator the MediaLocator identifying the device index of - * a PortAudio device to get - * @return the device index of a PortAudio device identified by - * locator - */ - public static int getDeviceIndex(MediaLocator locator) - { - if (AudioSystem.LOCATOR_PROTOCOL_PORTAUDIO.equalsIgnoreCase( - locator.getProtocol())) - { - return Integer.parseInt(locator.getRemainder().replace("#", "")); - } - else - { - throw new IllegalArgumentException("locator.protocol"); - } - } - - /** - * Gets the Formats which are to be reported by a - * FormatControl as supported formats for a - * PullBufferStream at a specific zero-based index in the list of - * streams of this PullBufferDataSource. - * - * @param streamIndex the zero-based index of the PullBufferStream - * for which the specified FormatControl is to report the list of - * supported Formats - * @return an array of Formats to be reported by a - * FormatControl as the supported formats for the - * PullBufferStream at the specified streamIndex in the - * list of streams of this PullBufferDataSource - * @see AbstractPullBufferCaptureDevice#getSupportedFormats(int) - */ - @Override - protected Format[] getSupportedFormats(int streamIndex) - { - return - (supportedFormats == null) - ? super.getSupportedFormats(streamIndex) - : supportedFormats; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/portaudio/PortAudioStream.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/portaudio/PortAudioStream.java deleted file mode 100644 index ea6195ecc..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/portaudio/PortAudioStream.java +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.portaudio; - -import java.io.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.*; -import net.java.sip.communicator.impl.neomedia.portaudio.*; -import net.java.sip.communicator.util.*; - -/** - * Implements PullBufferStream for PortAudio. - * - * @author Damian Minkov - * @author Lyubomir Marinov - */ -public class PortAudioStream - extends AbstractPullBufferStream -{ - /** - * The Logger used by the PortAudioStream class and its - * instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(PortAudioStream.class); - - /** - * The indicator which determines whether audio quality improvement is - * enabled for this PortAudioStream in accord with the preferences - * of the user. - */ - private final boolean audioQualityImprovement; - - /** - * The number of bytes to read from a native PortAudio stream in a single - * invocation. Based on {@link #framesPerBuffer}. - */ - private int bytesPerBuffer; - - /** - * The device index of the PortAudio device read through this - * PullBufferStream. - */ - private int deviceIndex = PortAudio.paNoDevice; - - /** - * The last-known Format of the media data made available by this - * PullBufferStream. - */ - private AudioFormat format; - - /** - * The number of frames to read from a native PortAudio stream in a single - * invocation. - */ - private int framesPerBuffer; - - /** - * The GainControl through which the volume/gain of captured media - * is controlled. - */ - private final GainControl gainControl; - - /** - * Native pointer to a PaStreamParameters object. - */ - private long inputParameters = 0; - - /** - * Current sequence number. - */ - private int sequenceNumber = 0; - - /** - * The input PortAudio stream represented by this instance. - */ - private long stream = 0; - - /** - * The indicator which determines whether {@link #stream} is busy and should - * not, for example, be closed. - */ - private boolean streamIsBusy = false; - - /** - * Initializes a new PortAudioStream instance which is to have its - * Format-related information abstracted by a specific - * FormatControl. - * - * @param dataSource the DataSource which is creating the new - * instance so that it becomes one of its streams - * @param formatControl the FormatControl which is to abstract the - * Format-related information of the new instance - * @param audioQualityImprovement true to enable audio quality - * improvement for the new instance in accord with the preferences of the - * user or false to completely disable audio quality improvement - */ - public PortAudioStream( - DataSource dataSource, - FormatControl formatControl, - boolean audioQualityImprovement) - { - super(dataSource, formatControl); - - this.audioQualityImprovement = audioQualityImprovement; - - MediaServiceImpl mediaServiceImpl - = NeomediaActivator.getMediaServiceImpl(); - - gainControl - = (mediaServiceImpl == null) - ? null - : (GainControl) mediaServiceImpl.getInputVolumeControl(); - } - - /** - * Gets the Format of this PullBufferStream as directly - * known by it. - * - * @return the Format of this PullBufferStream as directly - * known by it or null if this PullBufferStream does not - * directly know its Format and it relies on the - * PullBufferDataSource which created it to report its - * Format - * @see AbstractPullBufferStream#doGetFormat() - */ - @Override - protected Format doGetFormat() - { - return (format == null) ? super.doGetFormat() : format; - } - - /** - * Reads media data from this PullBufferStream into a specific - * Buffer with blocking. - * - * @param buffer the Buffer in which media data is to be read from - * this PullBufferStream - * @throws IOException if anything goes wrong while reading media data from - * this PullBufferStream into the specified buffer - */ - public void read(Buffer buffer) - throws IOException - { - synchronized (this) - { - if (stream == 0) - { - buffer.setLength(0); - return; - } - else - streamIsBusy = true; - } - try - { - /* - * Reuse the data of buffer in order to not perform unnecessary - * allocations. - */ - Object data = buffer.getData(); - byte[] bufferData = null; - - if (data instanceof byte[]) - { - bufferData = (byte[]) data; - if (bufferData.length < bytesPerBuffer) - bufferData = null; - } - if (bufferData == null) - { - bufferData = new byte[bytesPerBuffer]; - buffer.setData(bufferData); - } - - try - { - PortAudio.Pa_ReadStream(stream, bufferData, framesPerBuffer); - } - catch (PortAudioException paex) - { - IOException ioex = new IOException(paex.getLocalizedMessage()); - - ioex.initCause(paex); - throw ioex; - } - - // if we have some volume setting apply them - if (gainControl != null) - { - AbstractVolumeControl.applyGain( - gainControl, - bufferData, 0, bytesPerBuffer); - } - - long bufferTimeStamp = System.nanoTime(); - - buffer.setFlags(Buffer.FLAG_SYSTEM_TIME); - if (format != null) - buffer.setFormat(format); - buffer.setHeader(null); - buffer.setLength(bytesPerBuffer); - buffer.setOffset(0); - buffer.setSequenceNumber(sequenceNumber++); - buffer.setTimeStamp(bufferTimeStamp); - } - finally - { - synchronized (this) - { - streamIsBusy = false; - notifyAll(); - } - } - } - - /** - * Sets the device index of the PortAudio device to be read through this - * PullBufferStream. - * - * @param deviceIndex the device index of the PortAudio device to be read - * through this PullBufferStream - * @throws IOException if input/output error occurred - */ - synchronized void setDeviceIndex(int deviceIndex) - throws IOException - { - if (this.deviceIndex == deviceIndex) - return; - - // DataSource#disconnect - if (this.deviceIndex != PortAudio.paNoDevice) - { - if (stream != 0) - { - try - { - PortAudio.Pa_CloseStream(stream); - } - catch (PortAudioException paex) - { - logger.error( - "Failed to close " + getClass().getSimpleName(), - paex); - - IOException ioex - = new IOException(paex.getLocalizedMessage()); - - ioex.initCause(paex); - throw ioex; - } - stream = 0; - if (inputParameters != 0) - { - PortAudio.PaStreamParameters_free(inputParameters); - inputParameters = 0; - } - - /* - * Make sure this AbstractPullBufferStream asks its DataSource - * for the Format in which it is supposed to output audio data - * next time it's opened instead of using its Format from a - * previous open. - */ - this.format = null; - } - } - this.deviceIndex = deviceIndex; - // DataSource#connect - if (this.deviceIndex != PortAudio.paNoDevice) - { - AudioFormat format = (AudioFormat) getFormat(); - int channels = format.getChannels(); - int sampleSizeInBits = format.getSampleSizeInBits(); - long sampleFormat = PortAudio.getPaSampleFormat(sampleSizeInBits); - double sampleRate = format.getSampleRate(); - int framesPerBuffer - = (int) - ((sampleRate * PortAudio.DEFAULT_MILLIS_PER_BUFFER) - / (channels * 1000)); - - try - { - inputParameters - = PortAudio.PaStreamParameters_new( - this.deviceIndex, - channels, - sampleFormat, - PortAudio.getSuggestedLatency()); - - stream - = PortAudio.Pa_OpenStream( - inputParameters, - 0 /* outputParameters */, - sampleRate, - framesPerBuffer, - PortAudio.STREAM_FLAGS_CLIP_OFF - | PortAudio.STREAM_FLAGS_DITHER_OFF, - null /* streamCallback */); - } - catch (PortAudioException paex) - { - logger.error( - "Failed to open " + getClass().getSimpleName(), - paex); - - IOException ioex = new IOException(paex.getLocalizedMessage()); - - ioex.initCause(paex); - throw ioex; - } - finally - { - if ((stream == 0) && (inputParameters != 0)) - { - PortAudio.PaStreamParameters_free(inputParameters); - inputParameters = 0; - } - } - if (stream == 0) - throw new IOException("Pa_OpenStream"); - - this.framesPerBuffer = framesPerBuffer; - bytesPerBuffer - = PortAudio.Pa_GetSampleSize(sampleFormat) - * channels - * framesPerBuffer; - - /* - * Know the Format in which this PortAudioStream will output audio - * data so that it can report it without going through its - * DataSource. - */ - this.format - = new AudioFormat( - AudioFormat.LINEAR, - sampleRate, - sampleSizeInBits, - channels, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED /* frameSizeInBits */, - Format.NOT_SPECIFIED /* frameRate */, - Format.byteArray); - - MediaServiceImpl mediaServiceImpl - = NeomediaActivator.getMediaServiceImpl(); - boolean denoise = DeviceConfiguration.DEFAULT_AUDIO_DENOISE; - boolean echoCancel = DeviceConfiguration.DEFAULT_AUDIO_ECHOCANCEL; - long echoCancelFilterLengthInMillis - = DeviceConfiguration - .DEFAULT_AUDIO_ECHOCANCEL_FILTER_LENGTH_IN_MILLIS; - - if (mediaServiceImpl != null) - { - DeviceConfiguration devCfg - = mediaServiceImpl.getDeviceConfiguration(); - - if (devCfg != null) - { - denoise = devCfg.isDenoise(); - echoCancel = devCfg.isEchoCancel(); - echoCancelFilterLengthInMillis - = devCfg.getEchoCancelFilterLengthInMillis(); - } - } - - PortAudio.setDenoise(stream, audioQualityImprovement && denoise); - PortAudio.setEchoFilterLengthInMillis( - stream, - (audioQualityImprovement && echoCancel) - ? echoCancelFilterLengthInMillis - : 0); - } - } - - /** - * Starts the transfer of media data from this PullBufferStream. - * - * @throws IOException if anything goes wrong while starting the transfer of - * media data from this PullBufferStream - */ - @Override - public synchronized void start() - throws IOException - { - try - { - PortAudio.Pa_StartStream(stream); - } - catch (PortAudioException paex) - { - logger.error("Failed to start " + getClass().getSimpleName(), paex); - - IOException ioex = new IOException(paex.getLocalizedMessage()); - - ioex.initCause(paex); - throw ioex; - } - } - - /** - * Stops the transfer of media data from this PullBufferStream. - * - * @throws IOException if anything goes wrong while stopping the transfer of - * media data from this PullBufferStream - */ - @Override - public synchronized void stop() - throws IOException - { - boolean interrupted = false; - - while (streamIsBusy) - { - try - { - wait(); - } - catch (InterruptedException iex) - { - interrupted = true; - } - } - if (interrupted) - Thread.currentThread().interrupt(); - - try - { - PortAudio.Pa_StopStream(stream); - } - catch (PortAudioException paex) - { - logger.error("Failed to stop " + getClass().getSimpleName(), paex); - - IOException ioex = new IOException(paex.getLocalizedMessage()); - - ioex.initCause(paex); - throw ioex; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/pulseaudio/DataSource.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/pulseaudio/DataSource.java deleted file mode 100644 index 8967fd098..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/pulseaudio/DataSource.java +++ /dev/null @@ -1,649 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.pulseaudio; - -import java.io.*; -import java.util.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.*; -import net.java.sip.communicator.impl.neomedia.pulseaudio.*; -import net.java.sip.communicator.util.*; - -public class DataSource - extends AbstractPullBufferCaptureDevice -{ - /** - * The Logger used by the DataSource class and its - * instances for logging output. - */ - private static final Logger logger = Logger.getLogger(DataSource.class); - - private static final int BUFFER_IN_TENS_OF_MILLIS = 10; - - private static final boolean DEBUG = logger.isDebugEnabled(); - - private static final int FRAGSIZE_IN_TENS_OF_MILLIS = 2; - - private static final boolean SOFTWARE_GAIN; - - static { - boolean softwareGain = true; - - try - { - String libraryVersion = PA.get_library_version(); - - if (libraryVersion != null) - { - StringTokenizer st = new StringTokenizer(libraryVersion, "."); - int major = Integer.parseInt(st.nextToken()); - int minor = Integer.parseInt(st.nextToken()); - - if ((major >= 1) && (minor >= 0)) - { - softwareGain = false; - if (logger.isDebugEnabled()) - { - logger.debug( - "Will control the volume" - + " through the native PulseAudio API."); - } - } - } - } - catch (Throwable t) - { - if (t instanceof ThreadDeath) - throw (ThreadDeath) t; - } - SOFTWARE_GAIN = softwareGain; - } - - private class PulseAudioStream - extends AbstractPullBufferStream - { - private byte[] buffer; - - private int channels; - - private boolean corked = true; - - private long cvolume; - - private int fragsize; - - private final GainControl gainControl; - - private float gainControlLevel; - - private int length; - - private int offset; - - private final PulseAudioSystem pulseAudioSystem; - - private final PA.stream_request_cb_t readCallback - = new PA.stream_request_cb_t() - { - public void callback(long s, int nbytes) - { - readCallback(s, nbytes); - } - }; - - private long stream; - - public PulseAudioStream(FormatControl formatControl) - { - super(DataSource.this, formatControl); - - pulseAudioSystem = PulseAudioSystem.getPulseAudioSystem(); - if (pulseAudioSystem == null) - throw new IllegalStateException("pulseAudioSystem"); - - MediaServiceImpl mediaServiceImpl - = NeomediaActivator.getMediaServiceImpl(); - - gainControl - = (mediaServiceImpl == null) - ? null - : (GainControl) mediaServiceImpl.getInputVolumeControl(); - } - - public void read(Buffer buffer) - throws IOException - { - pulseAudioSystem.lockMainloop(); - try - { - if (stream == 0) - throw new IOException("stream"); - - Object data = buffer.getData(); - byte[] bytes; - - if (data instanceof byte[]) - { - bytes = (byte[]) data; - if (bytes.length < fragsize) - { - bytes = new byte[fragsize]; - buffer.setData(bytes); - } - } - else - { - bytes = new byte[fragsize]; - buffer.setData(bytes); - } - - int toRead = fragsize; - int offset = 0; - int length = 0; - - while (toRead > 0) - { - if (corked) - break; - - if (this.length <= 0) - { - pulseAudioSystem.waitMainloop(); - continue; - } - - int toCopy = (toRead < this.length) ? toRead : this.length; - - System.arraycopy( - this.buffer, this.offset, - bytes, offset, - toCopy); - - this.offset += toCopy; - this.length -= toCopy; - if (this.length <= 0) - { - this.offset = 0; - this.length = 0; - } - - toRead -= toCopy; - offset += toCopy; - length += toCopy; - } - - buffer.setFlags(Buffer.FLAG_SYSTEM_TIME); - buffer.setLength(length); - buffer.setOffset(0); - buffer.setTimeStamp(System.nanoTime()); - - if (gainControl != null) - { - if (SOFTWARE_GAIN || (cvolume == 0)) - { - if (length > 0) - { - AbstractVolumeControl.applyGain( - gainControl, - bytes, 0, length); - } - } - else - { - float gainControlLevel = gainControl.getLevel(); - - if (this.gainControlLevel != gainControlLevel) - { - this.gainControlLevel = gainControlLevel; - setStreamVolume(stream, gainControlLevel); - } - } - } - } - finally - { - pulseAudioSystem.unlockMainloop(); - } - } - - private void readCallback(long stream, int length) - { - try - { - int peeked; - - if (corked) - peeked = 0; - else - { - int offset; - - if ((buffer == null) || (buffer.length < length)) - { - buffer = new byte[length]; - this.offset = 0; - this.length = 0; - offset = 0; - } - else - { - offset = this.offset + this.length; - if (offset + length > buffer.length) - { - int overflow = this.length + length - buffer.length; - - if (overflow > 0) - { - if (overflow >= this.length) - { - if (DEBUG && logger.isDebugEnabled()) - { - logger.debug( - "Dropping " - + this.length - + " bytes!"); - } - this.offset = 0; - this.length = 0; - offset = 0; - } - else - { - if (DEBUG && logger.isDebugEnabled()) - { - logger.debug( - "Dropping " - + overflow - + " bytes!"); - } - this.offset += overflow; - this.length -= overflow; - } - } - if (this.length > 0) - { - for (int i = 0; - i < this.length; - i++, this.offset++) - { - buffer[i] = buffer[this.offset]; - } - this.offset = 0; - offset = this.length; - } - } - } - - peeked = PA.stream_peek(stream, buffer, offset); - } - - PA.stream_drop(stream); - this.length += peeked; - } - finally - { - pulseAudioSystem.signalMainloop(false); - } - } - - @SuppressWarnings("unused") - public void connect() - throws IOException - { - pulseAudioSystem.lockMainloop(); - try - { - connectWithMainloopLock(); - } - finally - { - pulseAudioSystem.unlockMainloop(); - } - } - - private void connectWithMainloopLock() - throws IOException - { - if (stream != 0) - return; - - AudioFormat format = (AudioFormat) getFormat(); - int sampleRate = (int) format.getSampleRate(); - int channels = format.getChannels(); - int sampleSizeInBits = format.getSampleSizeInBits(); - - if ((sampleRate == Format.NOT_SPECIFIED) - && (MediaUtils.MAX_AUDIO_SAMPLE_RATE - != Format.NOT_SPECIFIED)) - sampleRate = (int) MediaUtils.MAX_AUDIO_SAMPLE_RATE; - if (channels == Format.NOT_SPECIFIED) - channels = 1; - if (sampleSizeInBits == Format.NOT_SPECIFIED) - sampleSizeInBits = 16; - - long stream = 0; - Throwable exception = null; - - try - { - stream - = pulseAudioSystem.createStream( - sampleRate, - channels, - getClass().getName(), - PulseAudioSystem.MEDIA_ROLE_PHONE); - this.channels = channels; - } - catch (IllegalStateException ise) - { - exception = ise; - } - catch (RuntimeException re) - { - exception = re; - } - if (exception != null) - { - IOException ioe = new IOException(); - - ioe.initCause(exception); - throw ioe; - } - if (stream == 0) - throw new IOException("stream"); - - try - { - int bytesPerTenMillis - = (sampleRate / 100) * channels * (sampleSizeInBits / 8); - - fragsize = FRAGSIZE_IN_TENS_OF_MILLIS * bytesPerTenMillis; - buffer = new byte[BUFFER_IN_TENS_OF_MILLIS * bytesPerTenMillis]; - - long attr - = PA.buffer_attr_new( - -1, - -1, - -1, - -1, - fragsize); - - if (attr == 0) - throw new IOException("pa_buffer_attr_new"); - - try - { - Runnable stateCallback - = new Runnable() - { - public void run() - { - pulseAudioSystem.signalMainloop(false); - } - }; - - PA.stream_set_state_callback( - stream, - stateCallback); - PA.stream_connect_record( - stream, - getLocatorDev(), - attr, - PA.STREAM_ADJUST_LATENCY - | PA.STREAM_START_CORKED); - - try - { - if (attr != 0) - { - PA.buffer_attr_free(attr); - attr = 0; - } - - int state - = pulseAudioSystem.waitForStreamState( - stream, - PA.STREAM_READY); - - if (state != PA.STREAM_READY) - throw new IOException("stream.state"); - - PA.stream_set_read_callback( - stream, - readCallback); - - if (!SOFTWARE_GAIN && (gainControl != null)) - { - cvolume = PA.cvolume_new(); - - boolean freeCvolume = true; - - try - { - float gainControlLevel = gainControl.getLevel(); - - setStreamVolume(stream, gainControlLevel); - this.gainControlLevel = gainControlLevel; - freeCvolume = false; - } - finally - { - if (freeCvolume) - { - PA.cvolume_free(cvolume); - cvolume = 0; - } - } - } - - this.stream = stream; - } - finally - { - if (this.stream == 0) - PA.stream_disconnect(stream); - } - } - finally - { - if (attr != 0) - PA.buffer_attr_free(attr); - } - } - finally - { - if (this.stream == 0) - PA.stream_unref(stream); - } - } - - private void cork(boolean b) - throws IOException - { - try - { - PulseAudioSystem.corkStream(stream, b); - corked = b; - } - finally - { - pulseAudioSystem.signalMainloop(false); - } - } - - public void disconnect() - throws IOException - { - pulseAudioSystem.lockMainloop(); - try - { - long stream = this.stream; - - if (stream != 0) - { - try - { - stopWithMainloopLock(); - } - finally - { - long cvolume = this.cvolume; - - this.cvolume = 0; - this.stream = 0; - - buffer = null; - corked = true; - fragsize = 0; - length = 0; - offset = 0; - - pulseAudioSystem.signalMainloop(false); - - if (cvolume != 0) - PA.cvolume_free(cvolume); - PA.stream_disconnect(stream); - PA.stream_unref(stream); - } - } - } - finally - { - pulseAudioSystem.unlockMainloop(); - } - } - - private void setStreamVolume(long stream, float level) - { - int volume - = PA.sw_volume_from_linear( - level - * (AbstractVolumeControl.MAX_VOLUME_PERCENT / 100)); - - PA.cvolume_set(cvolume, channels, volume); - - long o - = PA.context_set_source_output_volume( - pulseAudioSystem.getContext(), - PA.stream_get_index(stream), - cvolume, - null); - - if (o != 0) - PA.operation_unref(o); - } - - @Override - public void start() - throws IOException - { - pulseAudioSystem.lockMainloop(); - try - { - if (stream == 0) - connectWithMainloopLock(); - - cork(false); - } - finally - { - pulseAudioSystem.unlockMainloop(); - } - - super.start(); - } - - @Override - public void stop() - throws IOException - { - pulseAudioSystem.lockMainloop(); - try - { - stopWithMainloopLock(); - } - finally - { - pulseAudioSystem.unlockMainloop(); - } - } - - private void stopWithMainloopLock() - throws IOException - { - if (stream != 0) - cork(true); - - super.stop(); - } - } - - /** - * Initializes a new DataSource instance. - */ - public DataSource() - { - } - - @Override - protected AbstractPullBufferStream createStream( - int streamIndex, - FormatControl formatControl) - { - return new PulseAudioStream(formatControl); - } - - protected void doDisconnect() - { - synchronized (getStreamSyncRoot()) - { - Object[] streams = streams(); - - if ((streams != null) && (streams.length != 0)) - { - for (Object stream : streams) - { - if (stream instanceof PulseAudioStream) - { - try - { - ((PulseAudioStream) stream).disconnect(); - } - catch (IOException ioe) - { - // Well, what can we do? - } - } - } - } - } - - super.doDisconnect(); - } - - private String getLocatorDev() - { - MediaLocator locator = getLocator(); - String locatorDev; - - if (locator == null) - locatorDev = null; - else - { - locatorDev = locator.getRemainder(); - if ((locatorDev != null) && (locatorDev.length() <= 0)) - locatorDev = null; - } - return locatorDev; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/DataSource.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/DataSource.java deleted file mode 100644 index 3497bc5fc..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/DataSource.java +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.quicktime; - -import java.awt.*; -import java.io.*; -import java.lang.reflect.*; -import java.util.*; -import java.util.List; // disambiguation - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.control.*; -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.*; -import net.java.sip.communicator.impl.neomedia.quicktime.*; -import net.java.sip.communicator.util.*; - -/** - * Implements a PushBufferDataSource and CaptureDevice using - * QuickTime/QTKit. - * - * @author Lyubomir Marinov - */ -public class DataSource - extends AbstractVideoPushBufferCaptureDevice -{ - - /** - * The Logger used by the DataSource class and its - * instances for logging output. - */ - private static final Logger logger = Logger.getLogger(DataSource.class); - - /** - * The QTCaptureSession which captures from {@link #device} and - * pushes media data to the PushBufferStreams of this - * PushBufferDataSource. - */ - private QTCaptureSession captureSession; - - /** - * The QTCaptureDevice which represents the media source of this - * DataSource. - */ - private QTCaptureDevice device; - - /** - * The list of Formats to be reported by DataSource - * instances as supported formats. - */ - private static Format[] supportedFormats; - - /** - * Initializes a new DataSource instance. - */ - public DataSource() - { - } - - /** - * Initializes a new DataSource instance from a specific - * MediaLocator. - * - * @param locator the MediaLocator to create the new instance from - */ - public DataSource(MediaLocator locator) - { - super(locator); - } - - /** - * Overrides - * {@link AbstractVideoPushBufferCaptureDevice#createFrameRateControl()} to - * provide a FrameRateControl which gets and sets the frame rate of - * the QTCaptureDecompressedVideoOutput represented by the - * QuickTimeStream made available by this DataSource. - * - * {@inheritDoc} - * @see AbstractVideoPushBufferCaptureDevice#createFrameRateControl() - */ - @Override - protected FrameRateControl createFrameRateControl() - { - return - new FrameRateControlAdapter() - { - /** - * The output frame rate to be managed by this - * FrameRateControl when there is no - * QuickTimeStream to delegate to. - */ - private float frameRate = -1; - - @Override - public float getFrameRate() - { - float frameRate = -1; - boolean frameRateFromQuickTimeStream = false; - - synchronized (getStreamSyncRoot()) - { - Object[] streams = streams(); - - if ((streams != null) && (streams.length != 0)) - { - for (Object stream : streams) - { - QuickTimeStream quickTimeStream - = (QuickTimeStream) stream; - - if (quickTimeStream != null) - { - frameRate = quickTimeStream.getFrameRate(); - frameRateFromQuickTimeStream = true; - if (frameRate != -1) - break; - } - } - } - } - return - frameRateFromQuickTimeStream - ? frameRate - : this.frameRate; - } - - @Override - public float setFrameRate(float frameRate) - { - float setFrameRate = -1; - boolean frameRateFromQuickTimeStream = false; - - synchronized (getStreamSyncRoot()) - { - Object[] streams = streams(); - - if ((streams != null) && (streams.length != 0)) - { - for (Object stream : streams) - { - QuickTimeStream quickTimeStream - = (QuickTimeStream) stream; - - if (quickTimeStream != null) - { - float quickTimeStreamFrameRate - = quickTimeStream.setFrameRate( - frameRate); - - if (quickTimeStreamFrameRate != -1) - { - setFrameRate - = quickTimeStreamFrameRate; - } - frameRateFromQuickTimeStream = true; - } - } - } - } - if (frameRateFromQuickTimeStream) - return setFrameRate; - else - { - this.frameRate = frameRate; - return this.frameRate; - } - } - }; - } - - /** - * Creates a new PushBufferStream which is to be at a specific - * zero-based index in the list of streams of this - * PushBufferDataSource. The Format-related information of - * the new instance is to be abstracted by a specific - * FormatControl. - * - * @param streamIndex the zero-based index of the PushBufferStream - * in the list of streams of this PushBufferDataSource - * @param formatControl the FormatControl which is to abstract the - * Format-related information of the new instance - * @return a new PushBufferStream which is to be at the specified - * streamIndex in the list of streams of this - * PushBufferDataSource and which has its Format-related - * information abstracted by the specified formatControl - * @see AbstractPushBufferCaptureDevice#createStream(int, FormatControl) - */ - protected AbstractPushBufferStream createStream( - int streamIndex, - FormatControl formatControl) - { - QuickTimeStream stream = new QuickTimeStream(this, formatControl); - - if (captureSession != null) - try - { - captureSession.addOutput(stream.captureOutput); - } - catch (NSErrorException nseex) - { - logger.error("Failed to addOutput to QTCaptureSession", nseex); - throw new UndeclaredThrowableException(nseex); - } - return stream; - } - - /** - * Opens a connection to the media source specified by the - * MediaLocator of this DataSource. - * - * @throws IOException if anything goes wrong while opening the connection - * to the media source specified by the MediaLocator of this - * DataSource - * @see AbstractPushBufferCaptureDevice#doConnect() - */ - @Override - protected void doConnect() - throws IOException - { - super.doConnect(); - - boolean deviceIsOpened; - - try - { - deviceIsOpened = device.open(); - } - catch (NSErrorException nseex) - { - IOException ioex = new IOException(); - - ioex.initCause(nseex); - throw ioex; - } - if (!deviceIsOpened) - throw new IOException("Failed to open QTCaptureDevice"); - - QTCaptureDeviceInput deviceInput - = QTCaptureDeviceInput.deviceInputWithDevice(device); - - captureSession = new QTCaptureSession(); - try - { - captureSession.addInput(deviceInput); - } - catch (NSErrorException nseex) - { - IOException ioex = new IOException(); - - ioex.initCause(nseex); - throw ioex; - } - - /* - * Add the QTCaptureOutputs represented by the QuickTimeStreams (if any) - * to the QTCaptureSession. - */ - synchronized (getStreamSyncRoot()) - { - Object[] streams = streams(); - - if (streams != null) - for (Object stream : streams) - if (stream != null) - try - { - captureSession - .addOutput( - ((QuickTimeStream) stream).captureOutput); - } - catch (NSErrorException nseex) - { - logger - .error( - "Failed to addOutput to QTCaptureSession", - nseex); - - IOException ioex = new IOException(); - - ioex.initCause(nseex); - throw ioex; - } - } - } - - /** - * Closes the connection to the media source specified by the - * MediaLocator of this DataSource. - * - * @see AbstractPushBufferCaptureDevice#doDisconnect() - */ - @Override - protected void doDisconnect() - { - super.doDisconnect(); - - if (captureSession != null) - { - captureSession.close(); - captureSession = null; - } - device.close(); - } - - /** - * Starts the transfer of media data from this DataSource. - * - * @throws IOException if anything goes wrong while starting the transfer of - * media data from this DataSource - * @see AbstractPushBufferCaptureDevice#doStart() - */ - @Override - protected void doStart() - throws IOException - { - captureSession.startRunning(); - - super.doStart(); - } - - /** - * Stops the transfer of media data from this DataSource. - * - * @throws IOException if anything goes wrong while stopping the transfer of - * media data from this DataSource - * @see AbstractPushBufferCaptureDevice#doStop() - */ - @Override - protected void doStop() - throws IOException - { - super.doStop(); - - captureSession.stopRunning(); - } - - /** - * Gets the Formats which are to be reported by a - * FormatControl as supported formats for a - * PushBufferStream at a specific zero-based index in the list of - * streams of this PushBufferDataSource. - * - * @param streamIndex the zero-based index of the PushBufferStream - * for which the specified FormatControl is to report the list of - * supported Formats - * @return an array of Formats to be reported by a - * FormatControl as the supported formats for the - * PushBufferStream at the specified streamIndex in the - * list of streams of this PushBufferDataSource - * @see AbstractPushBufferCaptureDevice#getSupportedFormats(int) - */ - @Override - protected Format[] getSupportedFormats(int streamIndex) - { - return getSupportedFormats(super.getSupportedFormats(streamIndex)); - } - - /** - * Gets a list of Formats which are more specific than given - * Formats with respect to video size. The implementation tries to - * come up with sane video sizes (for example, by looking for codecs which - * accept the encodings of the specified generic Formats and using - * their sizes if any). - * - * @param genericFormats the Formats from which more specific are - * to be derived - * @return a list of Formats which are more specific than the given - * Formats with respect to video size - */ - private static synchronized Format[] getSupportedFormats( - Format[] genericFormats) - { - if ((supportedFormats != null) && (supportedFormats.length > 0)) - return supportedFormats.clone(); - - List specificFormats = new LinkedList(); - - for (Format genericFormat : genericFormats) - { - VideoFormat genericVideoFormat = (VideoFormat) genericFormat; - - if (genericVideoFormat.getSize() == null) - { - @SuppressWarnings("unchecked") - Vector codecs - = PlugInManager - .getPlugInList( - new VideoFormat(genericVideoFormat.getEncoding()), - null, - PlugInManager.CODEC); - - for (String codec : codecs) - { - Format[] supportedInputFormats - = PlugInManager - .getSupportedInputFormats( - codec, - PlugInManager.CODEC); - - for (Format supportedInputFormat : supportedInputFormats) - if (supportedInputFormat instanceof VideoFormat) - { - Dimension size - = ((VideoFormat) supportedInputFormat) - .getSize(); - - if (size != null) - specificFormats - .add( - genericFormat - .intersects( - new VideoFormat( - null, - size, - Format.NOT_SPECIFIED, - null, - Format.NOT_SPECIFIED))); - } - } - } - - specificFormats.add(genericFormat); - } - supportedFormats - = specificFormats.toArray(new Format[specificFormats.size()]); - return supportedFormats.clone(); - } - - /** - * Sets the QTCaptureDevice which represents the media source of - * this DataSource. - * - * @param device the QTCaptureDevice which represents the media - * source of this DataSource - */ - private void setDevice(QTCaptureDevice device) - { - if (this.device != device) - this.device = device; - } - - /** - * Attempts to set the Format to be reported by the - * FormatControl of a PushBufferStream at a specific - * zero-based index in the list of streams of this - * PushBufferDataSource. The PushBufferStream does not - * exist at the time of the attempt to set its Format. - * - * @param streamIndex the zero-based index of the PushBufferStream - * the Format of which is to be set - * @param oldValue the last-known Format for the - * PushBufferStream at the specified streamIndex - * @param newValue the Format which is to be set - * @return the Format to be reported by the FormatControl - * of the PushBufferStream at the specified streamIndex - * in the list of streams of this PushBufferStream or null - * if the attempt to set the Format did not success and any - * last-known Format is to be left in effect - * @see AbstractPushBufferCaptureDevice#setFormat(int, Format, Format) - */ - @Override - protected Format setFormat( - int streamIndex, - Format oldValue, Format newValue) - { - if (newValue instanceof VideoFormat) - { - // This DataSource supports setFormat. - return newValue; - } - else - return super.setFormat(streamIndex, oldValue, newValue); - } - - /** - * Sets the MediaLocator which specifies the media source of this - * DataSource. - * - * @param locator the MediaLocator which specifies the media source - * of this DataSource - * @see javax.media.protocol.DataSource#setLocator(MediaLocator) - */ - @Override - public void setLocator(MediaLocator locator) - { - super.setLocator(locator); - - locator = getLocator(); - - QTCaptureDevice device; - - if ((locator != null) - && DeviceSystem.LOCATOR_PROTOCOL_QUICKTIME.equalsIgnoreCase( - locator.getProtocol())) - { - String deviceUID = locator.getRemainder(); - - device = QTCaptureDevice.deviceWithUniqueID(deviceUID); - } - else - device = null; - setDevice(device); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/QuickTimeStream.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/QuickTimeStream.java deleted file mode 100644 index cb1f7eac0..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/QuickTimeStream.java +++ /dev/null @@ -1,786 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.quicktime; - -import java.awt.Dimension; // disambiguation -import java.io.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.codec.video.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.*; -import net.java.sip.communicator.impl.neomedia.quicktime.*; - -/** - * Implements a PushBufferStream using QuickTime/QTKit. - * - * @author Lyubomir Marinov - */ -public class QuickTimeStream - extends AbstractPushBufferStream -{ - - /** - * The indicator which determines whether {@link #captureOutput} - * automatically drops late frames. If false, we have to drop them - * ourselves because QuickTime/QTKit will buffer them all and the video will - * be late. - */ - private final boolean automaticallyDropsLateVideoFrames; - - /** - * The pool of ByteBuffers this instances is using to transfer the - * media data captured by {@link #captureOutput} out of this instance - * through the Buffers specified in its {@link #read(Buffer)}. - */ - private final ByteBufferPool byteBufferPool = new ByteBufferPool(); - - /** - * The QTCaptureOutput represented by this SourceStream. - */ - final QTCaptureDecompressedVideoOutput captureOutput - = new QTCaptureDecompressedVideoOutput(); - - /** - * The VideoFormat which has been successfully set on - * {@link #captureOutput}. - */ - private VideoFormat captureOutputFormat; - - /** - * The captured media data to be returned in {@link #read(Buffer)}. - */ - private ByteBuffer data; - - /** - * The Format of {@link #data} if known. If possible, determined by - * the CVPixelBuffer video frame from which data is - * acquired. - */ - private Format dataFormat; - - /** - * The Object which synchronizes the access to the - * {@link #data}-related fields of this instance. - */ - private final Object dataSyncRoot = new Object(); - - /** - * The time stamp in nanoseconds of {@link #data}. - */ - private long dataTimeStamp; - - /** - * The last-known Format of the media data made available by this - * PushBufferStream. - */ - private Format format; - - /** - * The captured media data to become the value of {@link #data} as soon as - * the latter becomes is consumed. Thus prepares this - * QuickTimeStream to provide the latest available frame and not - * wait for QuickTime/QTKit to capture a new one. - */ - private ByteBuffer nextData; - - /** - * The Format of {@link #nextData} if known. - */ - private Format nextDataFormat; - - /** - * The time stamp in nanoseconds of {@link #nextData}. - */ - private long nextDataTimeStamp; - - /** - * The Thread which is to call - * {@link BufferTransferHandler#transferData(PushBufferStream)} for this - * QuickTimeStream so that the call is not made in QuickTime/QTKit - * and we can drop late frames when - * {@link #automaticallyDropsLateVideoFrames} is false. - */ - private Thread transferDataThread; - - /** - * Initializes a new QuickTimeStream instance which is to have its - * Format-related information abstracted by a specific - * FormatControl. - * - * @param dataSource the DataSource which is creating the new - * instance so that it becomes one of its streams - * @param formatControl the FormatControl which is to abstract the - * Format-related information of the new instance - */ - QuickTimeStream(DataSource dataSource, FormatControl formatControl) - { - super(dataSource, formatControl); - - if (formatControl != null) - { - Format format = formatControl.getFormat(); - - if (format != null) - setCaptureOutputFormat(format); - } - - automaticallyDropsLateVideoFrames - = captureOutput.setAutomaticallyDropsLateVideoFrames(true); - captureOutput.setDelegate( - new QTCaptureDecompressedVideoOutput.Delegate() - { - - /** - * Notifies this Delegate that the - * QTCaptureOutput to which it is set has output a - * specific CVImageBuffer representing a video - * frame with a specific QTSampleBuffer. - * - * @param videoFrame the CVImageBuffer which - * represents the output video frame - * @param sampleBuffer the QTSampleBuffer which - * represents additional details about the output video - * samples - */ - public void outputVideoFrameWithSampleBuffer( - CVImageBuffer videoFrame, - QTSampleBuffer sampleBuffer) - { - captureOutputDidOutputVideoFrameWithSampleBuffer( - captureOutput, - videoFrame, - sampleBuffer); - } - }); - - FrameRateControl frameRateControl - = (FrameRateControl) - dataSource.getControl(FrameRateControl.class.getName()); - - if (frameRateControl != null) - { - float frameRate = frameRateControl.getFrameRate(); - - if (frameRate > 0) - setFrameRate(frameRate); - } - } - - /** - * Notifies this instance that its QTCaptureOutput has output a - * specific CVImageBuffer representing a video frame with a - * specific QTSampleBuffer. - * - * @param captureOutput the QTCaptureOutput which has output a - * video frame - * @param videoFrame the CVImageBuffer which represents the output - * video frame - * @param sampleBuffer the QTSampleBuffer which represents - * additional details about the output video samples - */ - private void captureOutputDidOutputVideoFrameWithSampleBuffer( - QTCaptureOutput captureOutput, - CVImageBuffer videoFrame, - QTSampleBuffer sampleBuffer) - { - CVPixelBuffer pixelBuffer = (CVPixelBuffer) videoFrame; - boolean transferData; - Format videoFrameFormat = getVideoFrameFormat(pixelBuffer); - - synchronized (dataSyncRoot) - { - if (!automaticallyDropsLateVideoFrames && (data != null)) - { - if (nextData != null) - { - byteBufferPool.returnFreeBuffer(nextData); - nextData = null; - } - - nextData - = byteBufferPool.getFreeBuffer(pixelBuffer.getByteCount()); - if (nextData != null) - { - nextData.setLength( - pixelBuffer.getBytes( - nextData.ptr, - nextData.capacity)); - nextDataTimeStamp = System.nanoTime(); - if (nextDataFormat == null) - nextDataFormat = videoFrameFormat; - } - return; - } - - if (data != null) - { - byteBufferPool.returnFreeBuffer(data); - data = null; - } - - data = byteBufferPool.getFreeBuffer(pixelBuffer.getByteCount()); - if (data != null) - { - data.setLength(pixelBuffer.getBytes(data.ptr, data.capacity)); - dataTimeStamp = System.nanoTime(); - if (dataFormat == null) - dataFormat = videoFrameFormat; - } - if (nextData != null) - { - byteBufferPool.returnFreeBuffer(nextData); - nextData = null; - } - - if (automaticallyDropsLateVideoFrames) - transferData = (data != null); - else - { - transferData = false; - dataSyncRoot.notifyAll(); - } - } - - if (transferData) - { - BufferTransferHandler transferHandler = this.transferHandler; - - if (transferHandler != null) - transferHandler.transferData(this); - } - } - - /** - * Releases the resources used by this instance throughout its existence and - * makes it available for garbage collection. This instance is considered - * unusable after closing. - * - * @see AbstractPushBufferStream#close() - */ - @Override - public void close() - { - super.close(); - - captureOutput.setDelegate(null); - - byteBufferPool.close(); - } - - /** - * Gets the Format of this PushBufferStream as directly - * known by it. - * - * @return the Format of this PushBufferStream as directly - * known by it or null if this PushBufferStream does not - * directly know its Format and it relies on the - * PushBufferDataSource which created it to report its - * Format - */ - @Override - protected Format doGetFormat() - { - Format format; - - if (this.format == null) - { - format = getCaptureOutputFormat(); - if (format == null) - format = super.doGetFormat(); - else - { - VideoFormat videoFormat = (VideoFormat) format; - - if (videoFormat.getSize() != null) - this.format = format; - else - { - Dimension defaultSize - = NeomediaActivator - .getMediaServiceImpl() - .getDeviceConfiguration() - .getVideoSize(); - - format - = videoFormat.intersects( - new VideoFormat( - null, - new Dimension( - defaultSize.width, - defaultSize.height), - Format.NOT_SPECIFIED, - Format.byteArray, - Format.NOT_SPECIFIED)); - } - } - } - else - format = this.format; - return format; - } - - /** - * Gets the Format of the media data made available by this - * PushBufferStream as indicated by {@link #captureOutput}. - * - * @return the Format of the media data made available by this - * PushBufferStream as indicated by {@link #captureOutput} - */ - private Format getCaptureOutputFormat() - { - NSDictionary pixelBufferAttributes - = captureOutput.pixelBufferAttributes(); - - if (pixelBufferAttributes != null) - { - int pixelFormatType - = pixelBufferAttributes - .intForKey( - CVPixelBufferAttributeKey - .kCVPixelBufferPixelFormatTypeKey); - int width - = pixelBufferAttributes - .intForKey( - CVPixelBufferAttributeKey.kCVPixelBufferWidthKey); - int height - = pixelBufferAttributes - .intForKey( - CVPixelBufferAttributeKey.kCVPixelBufferHeightKey); - - switch (pixelFormatType) - { - case CVPixelFormatType.kCVPixelFormatType_32ARGB: - if (captureOutputFormat instanceof AVFrameFormat) - return - new AVFrameFormat( - ((width == 0) && (height == 0) - ? null - : new Dimension(width, height)), - Format.NOT_SPECIFIED, - FFmpeg.PIX_FMT_ARGB, - CVPixelFormatType.kCVPixelFormatType_32ARGB); - else - return - new RGBFormat( - ((width == 0) && (height == 0) - ? null - : new Dimension(width, height)), - Format.NOT_SPECIFIED, - Format.byteArray, - Format.NOT_SPECIFIED, - 32, - 2, 3, 4); - case CVPixelFormatType.kCVPixelFormatType_420YpCbCr8Planar: - if ((width == 0) && (height == 0)) - { - if (captureOutputFormat instanceof AVFrameFormat) - return - new AVFrameFormat( - FFmpeg.PIX_FMT_YUV420P, - CVPixelFormatType - .kCVPixelFormatType_420YpCbCr8Planar); - else - return new YUVFormat(YUVFormat.YUV_420); - } - else if (captureOutputFormat instanceof AVFrameFormat) - { - return - new AVFrameFormat( - new Dimension(width, height), - Format.NOT_SPECIFIED, - FFmpeg.PIX_FMT_YUV420P, - CVPixelFormatType. - kCVPixelFormatType_420YpCbCr8Planar); - } - else - { - int strideY = width; - int strideUV = strideY / 2; - int offsetY = 0; - int offsetU = strideY * height; - int offsetV = offsetU + strideUV * height / 2; - - return - new YUVFormat( - new Dimension(width, height), - Format.NOT_SPECIFIED, - Format.byteArray, - Format.NOT_SPECIFIED, - YUVFormat.YUV_420, - strideY, strideUV, - offsetY, offsetU, offsetV); - } - } - } - return null; - } - - /** - * Gets the output frame rate of the - * QTCaptureDecompressedVideoOutput represented by this - * QuickTimeStream. - * - * @return the output frame rate of the - * QTCaptureDecompressedVideoOutput represented by this - * QuickTimeStream - */ - public float getFrameRate() - { - return (float) (1.0d / captureOutput.minimumVideoFrameInterval()); - } - - /** - * Gets the Format of the media data made available by this - * PushBufferStream as indicated by a specific - * CVPixelBuffer. - * - * @param videoFrame the CVPixelBuffer which provides details about - * the Format of the media data made available by this - * PushBufferStream - * @return the Format of the media data made available by this - * PushBufferStream as indicated by the specified - * CVPixelBuffer - */ - private Format getVideoFrameFormat(CVPixelBuffer videoFrame) - { - Format format = getFormat(); - Dimension size = ((VideoFormat) format).getSize(); - - if ((size == null) || ((size.width == 0) && (size.height == 0))) - format - = format - .intersects( - new VideoFormat( - null, - new Dimension( - videoFrame.getWidth(), - videoFrame.getHeight()), - Format.NOT_SPECIFIED, - Format.byteArray, - Format.NOT_SPECIFIED)); - return format; - } - - /** - * Reads media data from this PushBufferStream into a specific - * Buffer without blocking. - * - * @param buffer the Buffer in which media data is to be read from - * this PushBufferStream - * @throws IOException if anything goes wrong while reading media data from - * this PushBufferStream into the specified buffer - */ - public void read(Buffer buffer) - throws IOException - { - synchronized (dataSyncRoot) - { - if (data == null) - { - buffer.setLength(0); - return; - } - - if (dataFormat != null) - buffer.setFormat(dataFormat); - - Format bufferFormat = buffer.getFormat(); - - if (bufferFormat == null) - { - bufferFormat = getFormat(); - if (bufferFormat != null) - buffer.setFormat(bufferFormat); - } - if (bufferFormat instanceof AVFrameFormat) - { - FinalizableAVFrame.read( - buffer, - bufferFormat, - data, - byteBufferPool); - } - else - { - Object bufferData = buffer.getData(); - byte[] bufferByteData; - int dataLength = data.getLength(); - - if (bufferData instanceof byte[]) - { - bufferByteData = (byte[]) bufferData; - if (bufferByteData.length < dataLength) - bufferByteData = null; - } - else - bufferByteData = null; - if (bufferByteData == null) - { - bufferByteData = new byte[dataLength]; - buffer.setData(bufferByteData); - } - CVPixelBuffer.memcpy(bufferByteData, 0, dataLength, data.ptr); - - buffer.setLength(dataLength); - buffer.setOffset(0); - - byteBufferPool.returnFreeBuffer(data); - } - - buffer.setFlags(Buffer.FLAG_LIVE_DATA | Buffer.FLAG_SYSTEM_TIME); - buffer.setTimeStamp(dataTimeStamp); - - data = null; - if (!automaticallyDropsLateVideoFrames) - dataSyncRoot.notifyAll(); - } - } - - /** - * Calls {@link BufferTransferHandler#transferData(PushBufferStream)} from - * inside {@link #transferDataThread} so that the call is not made in - * QuickTime/QTKit and we can drop late frames in the meantime. - */ - private void runInTransferDataThread() - { - boolean transferData = false; - - while (Thread.currentThread().equals(transferDataThread)) - { - if (transferData) - { - BufferTransferHandler transferHandler = this.transferHandler; - - if (transferHandler != null) - transferHandler.transferData(this); - - synchronized (dataSyncRoot) - { - if (data != null) - { - byteBufferPool.returnFreeBuffer(data); - data = null; - } - - data = nextData; - dataTimeStamp = nextDataTimeStamp; - if (dataFormat == null) - dataFormat = nextDataFormat; - nextData = null; - } - } - - synchronized (dataSyncRoot) - { - if (data == null) - { - data = nextData; - dataTimeStamp = nextDataTimeStamp; - if (dataFormat == null) - dataFormat = nextDataFormat; - nextData = null; - } - if (data == null) - { - boolean interrupted = false; - - try - { - dataSyncRoot.wait(); - } - catch (InterruptedException iex) - { - interrupted = true; - } - if (interrupted) - Thread.currentThread().interrupt(); - - transferData = (data != null); - } - else - transferData = true; - } - } - } - - /** - * Sets the Format of the media data made available by this - * PushBufferStream to {@link #captureOutput}. - * - * @param format the Format of the media data made available by - * this PushBufferStream to be set to {@link #captureOutput} - */ - private void setCaptureOutputFormat(Format format) - { - VideoFormat videoFormat = (VideoFormat) format; - Dimension size = videoFormat.getSize(); - int width; - int height; - - /* - * FIXME Mac OS X Leopard does not seem to report the size of the - * QTCaptureDevice in its formatDescriptions early in its creation. - * The workaround presented here is to just force a specific size. - */ - if (size == null) - { - Dimension defaultSize - = NeomediaActivator - .getMediaServiceImpl() - .getDeviceConfiguration() - .getVideoSize(); - - width = defaultSize.width; - height = defaultSize.height; - } - else - { - width = size.width; - height = size.height; - } - - NSMutableDictionary pixelBufferAttributes = null; - - if ((width > 0) && (height > 0)) - { - if (pixelBufferAttributes == null) - pixelBufferAttributes = new NSMutableDictionary(); - pixelBufferAttributes.setIntForKey( - width, - CVPixelBufferAttributeKey.kCVPixelBufferWidthKey); - pixelBufferAttributes.setIntForKey( - height, - CVPixelBufferAttributeKey.kCVPixelBufferHeightKey); - } - - String encoding; - - if (format instanceof AVFrameFormat) - { - int pixFmt = ((AVFrameFormat) format).getPixFmt(); - - if (pixFmt == FFmpeg.PIX_FMT_YUV420P) - encoding = VideoFormat.YUV; - else if (pixFmt == FFmpeg.PIX_FMT_ARGB) - encoding = VideoFormat.RGB; - else - encoding = null; - } - else if (format.isSameEncoding(VideoFormat.RGB)) - encoding = VideoFormat.RGB; - else if (format.isSameEncoding(VideoFormat.YUV)) - encoding = VideoFormat.YUV; - else - encoding = null; - - if (VideoFormat.RGB.equalsIgnoreCase(encoding)) - { - if (pixelBufferAttributes == null) - pixelBufferAttributes = new NSMutableDictionary(); - pixelBufferAttributes.setIntForKey( - CVPixelFormatType.kCVPixelFormatType_32ARGB, - CVPixelBufferAttributeKey.kCVPixelBufferPixelFormatTypeKey); - } - else if (VideoFormat.YUV.equalsIgnoreCase(encoding)) - { - if (pixelBufferAttributes == null) - pixelBufferAttributes = new NSMutableDictionary(); - pixelBufferAttributes.setIntForKey( - CVPixelFormatType.kCVPixelFormatType_420YpCbCr8Planar, - CVPixelBufferAttributeKey.kCVPixelBufferPixelFormatTypeKey); - } - else - throw new IllegalArgumentException("format"); - - if (pixelBufferAttributes != null) - { - captureOutput.setPixelBufferAttributes(pixelBufferAttributes); - captureOutputFormat = videoFormat; - } - } - - /** - * Sets the output frame rate of the - * QTCaptureDecompressedVideoOutput represented by this - * QuickTimeStream. - * - * @param frameRate the output frame rate to be set on the - * QTCaptureDecompressedVideoOutput represented by this - * QuickTimeStream - * @return the output frame rate of the - * QTCaptureDecompressedVideoOutput represented by this - * QuickTimeStream - */ - public float setFrameRate(float frameRate) - { - captureOutput.setMinimumVideoFrameInterval(1.0d / frameRate); - return getFrameRate(); - } - - /** - * Starts the transfer of media data from this PushBufferStream. - * - * @throws IOException if anything goes wrong while starting the transfer of - * media data from this PushBufferStream - */ - @Override - public void start() - throws IOException - { - if (!automaticallyDropsLateVideoFrames) - { - transferDataThread - = new Thread(getClass().getSimpleName()) - { - @Override - public void run() - { - runInTransferDataThread(); - } - }; - transferDataThread.start(); - } - } - - /** - * Stops the transfer of media data from this PushBufferStream. - * - * @throws IOException if anything goes wrong while stopping the transfer of - * media data from this PushBufferStream - */ - @Override - public void stop() - throws IOException - { - transferDataThread = null; - - synchronized (dataSyncRoot) - { - if (data != null) - { - byteBufferPool.returnFreeBuffer(data); - data = null; - } - dataFormat = null; - if (nextData != null) - { - byteBufferPool.returnFreeBuffer(nextData); - nextData = null; - } - nextDataFormat = null; - - if (!automaticallyDropsLateVideoFrames) - dataSyncRoot.notifyAll(); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/video4linux2/DataSource.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/video4linux2/DataSource.java deleted file mode 100644 index 64e861426..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/video4linux2/DataSource.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.video4linux2; - -import java.io.*; - -import javax.media.*; -import javax.media.control.*; - -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.*; - -/** - * Implements a PullBufferDataSource and CaptureDevice using - * the Video for Linux Two API Specification. - * - * @author Lyubomir Marinov - */ -public class DataSource - extends AbstractVideoPullBufferCaptureDevice -{ - /** - * The map of Video for Linux Two API Specification pixel formats to FFmpeg - * pixel formats which allows converting between the two. - */ - private static final int[] V4L2_TO_FFMPEG_PIX_FMT - = new int[] - { - Video4Linux2.V4L2_PIX_FMT_UYVY, - FFmpeg.PIX_FMT_UYVY422, - Video4Linux2.V4L2_PIX_FMT_YUV420, - FFmpeg.PIX_FMT_YUV420P, - Video4Linux2.V4L2_PIX_FMT_YUYV, - FFmpeg.PIX_FMT_YUYV422, - Video4Linux2.V4L2_PIX_FMT_MJPEG, - FFmpeg.PIX_FMT_YUVJ422P, - Video4Linux2.V4L2_PIX_FMT_JPEG, - FFmpeg.PIX_FMT_YUVJ422P, - Video4Linux2.V4L2_PIX_FMT_RGB24, - FFmpeg.PIX_FMT_RGB24_1, - Video4Linux2.V4L2_PIX_FMT_BGR24, - FFmpeg.PIX_FMT_BGR24_1, - }; - - /** - * The file descriptor of the opened Video for Linux Two API Specification - * device represented by this DataSource. - */ - private int fd = -1; - - /** - * Initializes a new DataSource instance. - */ - public DataSource() - { - } - - /** - * Initializes a new DataSource instance from a specific - * MediaLocator. - * - * @param locator the MediaLocator to create the new instance from - */ - public DataSource(MediaLocator locator) - { - super(locator); - } - - /** - * Creates a new PullBufferStream which is to be at a specific - * zero-based index in the list of streams of this - * PullBufferDataSource. The Format-related information of - * the new instance is to be abstracted by a specific - * FormatControl. - * - * @param streamIndex the zero-based index of the PullBufferStream - * in the list of streams of this PullBufferDataSource - * @param formatControl the FormatControl which is to abstract the - * Format-related information of the new instance - * @return a new PullBufferStream which is to be at the specified - * streamIndex in the list of streams of this - * PullBufferDataSource and which has its Format-related - * information abstracted by the specified formatControl - */ - protected Video4Linux2Stream createStream( - int streamIndex, - FormatControl formatControl) - { - return new Video4Linux2Stream(this, formatControl); - } - - /** - * Opens a connection to the media source specified by the - * MediaLocator of this DataSource. - * - * @throws IOException if anything goes wrong while opening the connection - * to the media source specified by the MediaLocator of this - * DataSource - * @see AbstractPullBufferCaptureDevice#doConnect() - */ - @Override - protected void doConnect() - throws IOException - { - super.doConnect(); - - String deviceName = getDeviceName(); - int fd = Video4Linux2.open(deviceName, Video4Linux2.O_RDWR); - - if (-1 == fd) - throw new IOException("Failed to open " + deviceName); - else - { - boolean close = true; - - try - { - synchronized (getStreamSyncRoot()) - { - for (Object stream : getStreams()) - ((Video4Linux2Stream) stream).setFd(fd); - } - close = false; - } - finally - { - if (close) - { - Video4Linux2.close(fd); - fd = -1; - } - } - this.fd = fd; - } - } - - /** - * Closes the connection to the media source specified by the - * MediaLocator of this DataSource. - */ - protected void doDisconnect() - { - try - { - /* - * Letting the Video4Linux2Stream know that the fd is going to be - * closed is necessary at least because - * AbstractPullBufferStream#close() is not guaranteed. - */ - synchronized (getStreamSyncRoot()) - { - Object[] streams = streams(); - - if (streams != null) - { - for (Object stream : streams) - { - try - { - ((Video4Linux2Stream) stream).setFd(-1); - } - catch (IOException ioex) - { - } - } - } - } - } - finally - { - try - { - super.doDisconnect(); - } - finally - { - Video4Linux2.close(fd); - } - } - } - - /** - * Gets the name of the Video for Linux Two API Specification device which - * represents the media source of this DataSource. - * - * @return the name of the Video for Linux Two API Specification device - * which represents the media source of this DataSource - */ - private String getDeviceName() - { - MediaLocator locator = getLocator(); - - return - ((locator != null) - && DeviceSystem.LOCATOR_PROTOCOL_VIDEO4LINUX2 - .equalsIgnoreCase(locator.getProtocol())) - ? locator.getRemainder() - : null; - } - - /** - * Gets the Video for Linux Two API Specification pixel format matching a - * specific FFmpeg pixel format. - * - * @param v4l2PixFmt the FFmpeg pixel format to get the matching Video for - * Linux Two API Specification pixel format of - * @return the Video for Linux Two API Specification pixel format matching - * the specified FFmpeg format - */ - public static int getFFmpegPixFmt(int v4l2PixFmt) - { - for (int i = 0; i < V4L2_TO_FFMPEG_PIX_FMT.length; i += 2) - if (V4L2_TO_FFMPEG_PIX_FMT[i] == v4l2PixFmt) - return V4L2_TO_FFMPEG_PIX_FMT[i + 1]; - return FFmpeg.PIX_FMT_NONE; - } - - /** - * Gets the FFmpeg pixel format matching a specific Video for Linux Two API - * Specification pixel format. - * - * @param ffmpegPixFmt the Video for Linux Two API Specification pixel format - * to get the matching FFmpeg pixel format of - * @return the FFmpeg pixel format matching the specified Video for Linux - * Two API Specification pixel format - */ - public static int getV4L2PixFmt(int ffmpegPixFmt) - { - for (int i = 0; i < V4L2_TO_FFMPEG_PIX_FMT.length; i += 2) - if (V4L2_TO_FFMPEG_PIX_FMT[i + 1] == ffmpegPixFmt) - return V4L2_TO_FFMPEG_PIX_FMT[i]; - return Video4Linux2.V4L2_PIX_FMT_NONE; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/video4linux2/Video4Linux2.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/video4linux2/Video4Linux2.java deleted file mode 100644 index 068b484f3..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/video4linux2/Video4Linux2.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.video4linux2; - -/** - * Provides the interface to the native Video for Linux Two API Specification - * (http://v4l2spec.bytesex.org/spec/) implementation. - * - * @author Lubomir Marinov - */ -public class Video4Linux2 -{ - public static final int MAP_SHARED = 0x01; - - public static final int O_NONBLOCK = 00004000; - - public static final int O_RDWR = 00000002; - - public static final int PROT_READ = 0x1; - - public static final int PROT_WRITE = 0x2; - - public static final int V4L2_BUF_TYPE_VIDEO_CAPTURE = 1; - - public static final int V4L2_CAP_STREAMING = 0x04000000; - - public static final int V4L2_CAP_VIDEO_CAPTURE = 0x00000001; - - public static final int V4L2_FIELD_NONE = 1; - - public static final int V4L2_MEMORY_MMAP = 1; - - public static final int V4L2_MEMORY_USERPTR = 2; - - public static final int V4L2_PIX_FMT_NONE = 0; - - public static final int V4L2_PIX_FMT_RGB24 - = v4l2_fourcc('R', 'G', 'B', '3'); - - public static final int V4L2_PIX_FMT_BGR24 - = v4l2_fourcc('B', 'G', 'R', '3'); - - public static final int V4L2_PIX_FMT_UYVY - = v4l2_fourcc('U', 'Y', 'V', 'Y'); - - public static final int V4L2_PIX_FMT_VYUY - = v4l2_fourcc('V', 'Y', 'U', 'Y'); - - public static final int V4L2_PIX_FMT_YUV420 - = v4l2_fourcc('Y', 'U', '1', '2'); - - public static final int V4L2_PIX_FMT_YUYV - = v4l2_fourcc('Y', 'U', 'Y', 'V'); - - public static final int V4L2_PIX_FMT_MJPEG - = v4l2_fourcc('M', 'J', 'P', 'G'); - - public static final int V4L2_PIX_FMT_JPEG - = v4l2_fourcc('J', 'P', 'E', 'G'); - - public static final int VIDIOC_DQBUF; - - public static final int VIDIOC_G_FMT; - - public static final int VIDIOC_QBUF; - - public static final int VIDIOC_QUERYBUF; - - public static final int VIDIOC_QUERYCAP; - - public static final int VIDIOC_REQBUFS; - - public static final int VIDIOC_S_FMT; - - public static final int VIDIOC_S_PARM; - - public static final int VIDIOC_STREAMOFF; - - public static final int VIDIOC_STREAMON; - - static - { - System.loadLibrary("jnvideo4linux2"); - - VIDIOC_DQBUF = VIDIOC_DQBUF(); - VIDIOC_G_FMT = VIDIOC_G_FMT(); - VIDIOC_QBUF = VIDIOC_QBUF(); - VIDIOC_QUERYBUF = VIDIOC_QUERYBUF(); - VIDIOC_QUERYCAP = VIDIOC_QUERYCAP(); - VIDIOC_REQBUFS = VIDIOC_REQBUFS(); - VIDIOC_S_FMT = VIDIOC_S_FMT(); - VIDIOC_S_PARM = VIDIOC_S_PARM(); - VIDIOC_STREAMOFF = VIDIOC_STREAMOFF(); - VIDIOC_STREAMON = VIDIOC_STREAMON(); - } - - public static native int close(int fd); - - public static native void free(long ptr); - - public static native int ioctl(int fd, int request, long argp); - - public static native long memcpy(long dest, long src, int n); - - public static native long mmap( - long start, - int length, - int prot, - int flags, - int fd, - long offset); - - public static native int munmap(long start, int length); - - public static native int open(String deviceName, int flags); - - public static native long v4l2_buffer_alloc(int type); - - public static native int v4l2_buffer_getBytesused(long v4l2_buffer); - - public static native int v4l2_buffer_getIndex(long v4l2_buffer); - - public static native int v4l2_buffer_getLength(long v4l2_buffer); - - public static native long v4l2_buffer_getMOffset(long v4l2_buffer); - - public static native void v4l2_buffer_setIndex( - long v4l2_buffer, - int index); - - public static native void v4l2_buffer_setMemory( - long v4l2_buffer, - int memory); - - public static native long v4l2_buf_type_alloc(int type); - - public static native long v4l2_capability_alloc(); - - public static native int v4l2_capability_getCapabilities( - long v4l2_capability); - - public static native String v4l2_capability_getCard( - long v4l2_capability); - - private static int v4l2_fourcc(char a, char b, char c, char d) - { - return - (a & 0xFF) - | ((b & 0xFF) << 8) - | ((c & 0xFF) << 16) - | ((d & 0xFF) << 24); - } - - public static native long v4l2_format_alloc(int type); - - public static native long v4l2_format_getFmtPix(long v4l2_format); - - public static native int v4l2_pix_format_getHeight( - long v4l2_pix_format); - - public static native int v4l2_pix_format_getPixelformat( - long v4l2_pix_format); - - public static native int v4l2_pix_format_getWidth(long v4l2_pix_format); - - public static native void v4l2_pix_format_setBytesperline( - long v4l2_pix_format, - int bytesperline); - - public static native void v4l2_pix_format_setField( - long v4l2_pix_format, - int field); - - public static native void v4l2_pix_format_setPixelformat( - long v4l2_pix_format, - int pixelformat); - - public static native void v4l2_pix_format_setWidthAndHeight( - long v4l2_pix_format, - int width, int height); - - public static native long v4l2_requestbuffers_alloc(int type); - - public static native int v4l2_requestbuffers_getCount( - long v4l2_requestbuffers); - - public static native void v4l2_requestbuffers_setCount( - long v4l2_requestbuffers, - int count); - - public static native void v4l2_requestbuffers_setMemory( - long v4l2_requestbuffers, - int memory); - - public static native long v4l2_streamparm_alloc(int type); - - public static native void v4l2_streamparm_setFps(long v4l2_streamparm, int fps); - - private static native int VIDIOC_DQBUF(); - - private static native int VIDIOC_G_FMT(); - - private static native int VIDIOC_QBUF(); - - private static native int VIDIOC_QUERYBUF(); - - private static native int VIDIOC_QUERYCAP(); - - private static native int VIDIOC_REQBUFS(); - - private static native int VIDIOC_S_FMT(); - - private static native int VIDIOC_S_PARM(); - - private static native int VIDIOC_STREAMOFF(); - - private static native int VIDIOC_STREAMON(); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/video4linux2/Video4Linux2Stream.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/video4linux2/Video4Linux2Stream.java deleted file mode 100644 index f4324bab7..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/video4linux2/Video4Linux2Stream.java +++ /dev/null @@ -1,851 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.video4linux2; - -import java.awt.*; -import java.io.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.codec.video.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.*; - -/** - * Implements a PullBufferStream using the Video for Linux Two API - * Specification. - * - * @author Lyubomir Marinov - */ -public class Video4Linux2Stream - extends AbstractVideoPullBufferStream -{ - /** - * The pool of ByteBuffers this instances is using to transfer the - * media data captured by the Video for Linux Two API Specification device - * out of this instance through the Buffers specified in its - * {@link #read(Buffer)}. - */ - private final ByteBufferPool byteBufferPool = new ByteBufferPool(); - - /** - * The capabilities of the Video for Linux Two API Specification device - * represented by {@link #fd}. - */ - private int capabilities = 0; - - /** - * The file descriptor of the Video for Linux Two API Specification device - * read through this PullBufferStream. - */ - private int fd = -1; - - /** - * The last-known Format of the media data made available by this - * PullBufferStream - */ - private Format format; - - /** - * The lengths in bytes of the buffers in the application's address space - * through which the Video for Linux Two API Specification device provides - * the captured media data to this instance when - * {@link #requestbuffersMemory} is equal to V4L2_MEMORY_MAP. - */ - private int[] mmapLengths; - - /** - * The buffers through which the Video for Linux Two API Specification - * device provides the captured media data to this instance when - * {@link #requestbuffersMemory} is equal to V4L2_MEMORY_MAP. These - * are mapped in the application's address space. - */ - private long[] mmaps; - - /** - * The number of buffers through which the Video for Linux Two API - * Specification device provides the captured media data to this instance - * when {@link #requestbuffersMemory} is equal to V4L2_MEMORY_MMAP. - */ - private int requestbuffersCount = 0; - - /** - * The input method negotiated by this instance with the Video for Linux Two - * API Specification device. - */ - private int requestbuffersMemory = 0; - - /** - * The v4l2_buffer instance via which captured media data is - * fetched from the Video for Linux Two API Specification device to this - * instance in {@link #read(Buffer)}. - */ - private long v4l2_buffer; - - /** - * Native Video for Linux Two pixel format. - */ - private int nativePixelFormat = 0; - - /** - * Tell device to start capture in read() method. - */ - private boolean startInRead = false; - - /** - * AVCodecContext for MJPEG conversion. - */ - private long mjpeg_context = 0; - - /** - * AVFrame that is used in case of JPEG/MJPEG conversion. - */ - private long avframe = 0; - - /** - * Initializes a new Video4Linux2Stream instance which is to have - * its Format-related information abstracted by a specific - * FormatControl. - * - * @param dataSource the DataSource which is creating the new - * instance so that it becomes one of its streams - * @param formatControl the FormatControl which is to abstract the - * Format-related information of the new instance - */ - public Video4Linux2Stream( - DataSource dataSource, - FormatControl formatControl) - { - super(dataSource, formatControl); - - v4l2_buffer - = Video4Linux2.v4l2_buffer_alloc( - Video4Linux2.V4L2_BUF_TYPE_VIDEO_CAPTURE); - if (0 == v4l2_buffer) - throw new OutOfMemoryError("v4l2_buffer_alloc"); - Video4Linux2.v4l2_buffer_setMemory( - v4l2_buffer, - Video4Linux2.V4L2_MEMORY_MMAP); - } - - /** - * Releases the resources used by this instance throughout its existence and - * makes it available for garbage collection. This instance is considered - * unusable after closing. - * - * @see AbstractPullBufferStream#close() - */ - @Override - public void close() - { - super.close(); - - if (v4l2_buffer != 0) - { - Video4Linux2.free(v4l2_buffer); - v4l2_buffer = 0; - } - } - - /** - * Gets the Format of this PullBufferStream as directly - * known by it. - * - * @return the Format of this PullBufferStream as directly - * known by it or null if this PullBufferStream does not - * directly know its Format and it relies on the - * PullBufferDataSource which created it to report its - * Format - * @see AbstractPullBufferStream#doGetFormat() - */ - @Override - protected Format doGetFormat() - { - Format format; - - if (this.format == null) - { - format = getFdFormat(); - if (format == null) - format = super.doGetFormat(); - else - { - VideoFormat videoFormat = (VideoFormat) format; - - if (videoFormat.getSize() != null) - this.format = format; - } - } - else - format = this.format; - return format; - } - - /** - * Reads media data from this PullBufferStream into a specific - * Buffer with blocking. - * - * @param buffer the Buffer in which media data is to be read from - * this PullBufferStream - * @throws IOException if anything goes wrong while reading media data from - * this PullBufferStream into the specified buffer - * @see AbstractVideoPullBufferStream#doRead(Buffer) - */ - protected void doRead(Buffer buffer) - throws IOException - { - Format format = buffer.getFormat(); - - if (!(format instanceof AVFrameFormat)) - format = null; - if (format == null) - { - format = getFormat(); - if (format != null) - buffer.setFormat(format); - } - - if(startInRead) - { - startInRead = false; - - long v4l2_buf_type - = Video4Linux2.v4l2_buf_type_alloc( - Video4Linux2.V4L2_BUF_TYPE_VIDEO_CAPTURE); - - if (0 == v4l2_buf_type) - throw new OutOfMemoryError("v4l2_buf_type_alloc"); - try - { - if (Video4Linux2.ioctl(fd, Video4Linux2.VIDIOC_STREAMON, - v4l2_buf_type) == -1) - { - throw new IOException("ioctl: request= VIDIOC_STREAMON"); - } - } - finally - { - Video4Linux2.free(v4l2_buf_type); - } - } - - if (Video4Linux2.ioctl(fd, Video4Linux2.VIDIOC_DQBUF, v4l2_buffer) - == -1) - throw new IOException("ioctl: request= VIDIOC_DQBUF"); - - long timeStamp = System.nanoTime(); - - try - { - ByteBuffer data = null; - int index = Video4Linux2.v4l2_buffer_getIndex(v4l2_buffer); - long mmap = mmaps[index]; - int bytesused = Video4Linux2.v4l2_buffer_getBytesused(v4l2_buffer); - - if(nativePixelFormat == Video4Linux2.V4L2_PIX_FMT_MJPEG || - nativePixelFormat == Video4Linux2.V4L2_PIX_FMT_JPEG) - { - /* initialize FFmpeg's MJPEG decoder if not already done */ - if(mjpeg_context == 0) - { - long avcodec = FFmpeg.avcodec_find_decoder( - FFmpeg.CODEC_ID_MJPEG); - - mjpeg_context = FFmpeg.avcodec_alloc_context(); - FFmpeg.avcodeccontext_set_workaround_bugs(mjpeg_context, - FFmpeg.FF_BUG_AUTODETECT); - - if (FFmpeg.avcodec_open(mjpeg_context, avcodec) < 0) - { - throw new RuntimeException("" + - "Could not open codec CODEC_ID_MJPEG"); - } - - avframe = FFmpeg.avcodec_alloc_frame(); - } - - if(FFmpeg.avcodec_decode_video(mjpeg_context, avframe, mmap, - bytesused) != -1) - { - Object out = buffer.getData(); - - if (!(out instanceof AVFrame) || - (((AVFrame) out).getPtr() != avframe)) - { - buffer.setData(new AVFrame(avframe)); - } - } - } - else - { - data = byteBufferPool.getFreeBuffer(bytesused); - - if (data != null) - { - Video4Linux2.memcpy(data.ptr, mmap, bytesused); - } - data.setLength(bytesused); - FinalizableAVFrame.read(buffer, format, data, byteBufferPool); - } - } - finally - { - if (Video4Linux2.ioctl(fd, Video4Linux2.VIDIOC_QBUF, v4l2_buffer) - == -1) - throw new IOException("ioctl: request= VIDIOC_QBUF"); - } - - buffer.setFlags(Buffer.FLAG_LIVE_DATA | Buffer.FLAG_SYSTEM_TIME); - buffer.setTimeStamp(timeStamp); - } - - /** - * Gets the Format of the media data captured by the Video for - * Linux Two API Specification device represented by the fd of this - * instance. - * - * @return the Format of the media data captured by the Video for - * Linux Two API Specification device represented by the fd of this - * instance - */ - private Format getFdFormat() - { - Format format = null; - - if (-1 != fd) - { - long v4l2_format - = Video4Linux2.v4l2_format_alloc( - Video4Linux2.V4L2_BUF_TYPE_VIDEO_CAPTURE); - - if (v4l2_format == 0) - throw new OutOfMemoryError("v4l2_format_alloc"); - else - { - try - { - if (Video4Linux2.ioctl( - fd, - Video4Linux2.VIDIOC_G_FMT, - v4l2_format) - != -1) - { - long fmtPix - = Video4Linux2.v4l2_format_getFmtPix(v4l2_format); - int pixelformat - = Video4Linux2.v4l2_pix_format_getPixelformat( - fmtPix); - int ffmpegPixFmt - = DataSource.getFFmpegPixFmt(pixelformat); - - if (FFmpeg.PIX_FMT_NONE != ffmpegPixFmt) - { - int width - = Video4Linux2.v4l2_pix_format_getWidth(fmtPix); - int height - = Video4Linux2.v4l2_pix_format_getHeight( - fmtPix); - - format - = new AVFrameFormat( - new Dimension(width, height), - Format.NOT_SPECIFIED, - ffmpegPixFmt, - pixelformat); - } - } - } - finally - { - Video4Linux2.free(v4l2_format); - } - } - } - return format; - } - - /** - * Unmaps the buffers through which the Video for Linux Two API - * Specification device provides the captured media data to this instance - * when {@link #requestbuffersMemory} is equal to V4L2_MEMORY_MMAP - * i.e. breaks the buffers' mappings between the driver's and the - * application's address spaces. - */ - private void munmap() - { - try - { - if (mmaps != null) - { - for (int i = 0; i < mmaps.length; i++) - { - long mmap = mmaps[i]; - - if (mmap != 0) - { - Video4Linux2.munmap(mmap, mmapLengths[i]); - mmaps[i] = 0; - mmapLengths[i] = 0; - } - } - } - } - finally - { - mmaps = null; - mmapLengths = null; - } - } - - /** - * Negotiates the input method with the Video for Linux Two API - * Specification device represented by the fd of this instance. - * - * @throws IOException if anything goes wrong while negotiating the input - * method with the Video for Linux Two API Specification device represented - * by the fd of this instance - */ - private void negotiateFdInputMethod() - throws IOException - { - long v4l2_capability = Video4Linux2.v4l2_capability_alloc(); - - if (0 == v4l2_capability) - throw new OutOfMemoryError("v4l2_capability_alloc"); - try - { - if (Video4Linux2.ioctl( - fd, - Video4Linux2.VIDIOC_QUERYCAP, - v4l2_capability) - == -1) - throw new IOException("ioctl: request= VIDIOC_QUERYCAP"); - capabilities - = Video4Linux2.v4l2_capability_getCapabilities(v4l2_capability); - } - finally - { - Video4Linux2.free(v4l2_capability); - } - if ((capabilities & Video4Linux2.V4L2_CAP_STREAMING) - != Video4Linux2.V4L2_CAP_STREAMING) - throw new IOException("Non-streaming V4L2 device not supported."); - - long v4l2_requestbuffers - = Video4Linux2.v4l2_requestbuffers_alloc( - Video4Linux2.V4L2_BUF_TYPE_VIDEO_CAPTURE); - - if (0 == v4l2_requestbuffers) - throw new OutOfMemoryError("v4l2_requestbuffers_alloc"); - try - { - requestbuffersMemory = Video4Linux2.V4L2_MEMORY_MMAP; - Video4Linux2.v4l2_requestbuffers_setMemory( - v4l2_requestbuffers, - requestbuffersMemory); - Video4Linux2.v4l2_requestbuffers_setCount(v4l2_requestbuffers, 2); - if (Video4Linux2.ioctl( - fd, - Video4Linux2.VIDIOC_REQBUFS, - v4l2_requestbuffers) - == -1) - { - throw - new IOException( - "ioctl: request= VIDIOC_REQBUFS, memory= " - + requestbuffersMemory); - } - requestbuffersCount - = Video4Linux2.v4l2_requestbuffers_getCount( - v4l2_requestbuffers); - } - finally - { - Video4Linux2.free(v4l2_requestbuffers); - } - if (requestbuffersCount < 1) - throw new IOException("Insufficient V4L2 device memory."); - - - long v4l2_buffer - = Video4Linux2.v4l2_buffer_alloc( - Video4Linux2.V4L2_BUF_TYPE_VIDEO_CAPTURE); - - if (0 == v4l2_buffer) - throw new OutOfMemoryError("v4l2_buffer_alloc"); - - try - { - Video4Linux2.v4l2_buffer_setMemory( - v4l2_buffer, - Video4Linux2.V4L2_MEMORY_MMAP); - - mmaps = new long[requestbuffersCount]; - mmapLengths = new int[requestbuffersCount]; - - boolean munmap = true; - - try - { - for (int i = 0; i < requestbuffersCount; i++) - { - Video4Linux2.v4l2_buffer_setIndex(v4l2_buffer, i); - if (Video4Linux2.ioctl( - fd, - Video4Linux2.VIDIOC_QUERYBUF, - v4l2_buffer) - == -1) - { - throw - new IOException("ioctl: request= VIDIOC_QUERYBUF"); - } - - int length - = Video4Linux2.v4l2_buffer_getLength(v4l2_buffer); - long offset - = Video4Linux2.v4l2_buffer_getMOffset(v4l2_buffer); - long mmap - = Video4Linux2.mmap( - 0, - length, - Video4Linux2.PROT_READ - | Video4Linux2.PROT_WRITE, - Video4Linux2.MAP_SHARED, - fd, - offset); - - if (-1 == mmap) - throw new IOException("mmap"); - mmaps[i] = mmap; - mmapLengths[i] = length; - } - munmap = false; - } - finally - { - if (munmap) - munmap(); - } - } - finally - { - Video4Linux2.free(v4l2_buffer); - } - } - - /** - * Sets the file descriptor of the Video for Linux Two API Specification - * device which is to be read through this PullBufferStream. - * - * @param fd the file descriptor of the Video for Linux Two API - * Specification device which is to be read through this - * PullBufferStream - * @throws IOException if anything goes wrong while setting the file - * descriptor of the Video for Linux Two API Specification device which is - * to be read through this PullBufferStream - */ - void setFd(int fd) - throws IOException - { - if (this.fd != fd) - { - if (this.fd != -1) - { - try - { - stop(); - } - catch (IOException ioex) - { - } - munmap(); - } - - /* - * Before a Video for Linux Two API Specification device can be - * read, an attempt to set its format must be made and its cropping - * must be reset. We can only learn about the format to be set from - * formatControl. But since this AbstractPullBufferStream exists - * already, formatControl will ask it about its format. So pretend - * that there is no device prior to asking formatControl about the - * format in order to get the format that has been set by the user. - */ - this.fd = -1; - this.capabilities = 0; - this.requestbuffersMemory = 0; - this.requestbuffersCount = 0; - - if (fd != -1) - { - Format format = getFormat(); - - this.fd = fd; - if (format != null) - setFdFormat(format); - setFdCropToDefault(); - negotiateFdInputMethod(); - } - } - } - - /** - * Sets the crop of the Video for Linux Two API Specification device - * represented by the fd of this instance to its default value so - * that this PullBufferStream reads media data without cropping. - */ - private void setFdCropToDefault() - { - // TODO Auto-generated method stub - } - - /** - * Sets the Format in which the Video for Linux Two API - * Specification device represented by the fd of this instance is - * to capture media data. - * - * @param format the Format of the media data to be captured by the - * Video for Linux Two API Specification device represented by the - * fd of this instance - * @throws IOException if anything goes wrong while setting the - * Format of the media data to be captured by the Video for Linux - * Two API Specification device represented by the fd of this - * instance - */ - private void setFdFormat(Format format) - throws IOException - { - int pixelformat = 0; - - if (format instanceof AVFrameFormat) - { - pixelformat = ((AVFrameFormat) format).getDevicePixFmt(); - nativePixelFormat = pixelformat; - } - if (Video4Linux2.V4L2_PIX_FMT_NONE == pixelformat) - throw new IOException("Unsupported format " + format); - - long v4l2_format - = Video4Linux2.v4l2_format_alloc( - Video4Linux2.V4L2_BUF_TYPE_VIDEO_CAPTURE); - - if (v4l2_format == 0) - throw new OutOfMemoryError("v4l2_format_alloc"); - try - { - if (Video4Linux2.ioctl(fd, Video4Linux2.VIDIOC_G_FMT, v4l2_format) - == -1) - throw new IOException("ioctl: request= VIDIO_G_FMT"); - - VideoFormat videoFormat = (VideoFormat) format; - Dimension size = videoFormat.getSize(); - long fmtPix = Video4Linux2.v4l2_format_getFmtPix(v4l2_format); - int width = Video4Linux2.v4l2_pix_format_getWidth(fmtPix); - int height = Video4Linux2.v4l2_pix_format_getHeight(fmtPix); - boolean setFdFormat = false; - - if (size == null) - { - // if there is no size in the format, respect settings - size = NeomediaActivator - .getMediaServiceImpl() - .getDeviceConfiguration() - .getVideoSize(); - } - - if ((size != null) - && ((size.width != width) || (size.height != height))) - { - Video4Linux2.v4l2_pix_format_setWidthAndHeight( - fmtPix, - size.width, size.height); - setFdFormat = true; - } - if (Video4Linux2.v4l2_pix_format_getPixelformat(v4l2_format) - != pixelformat) - { - Video4Linux2.v4l2_pix_format_setPixelformat( - fmtPix, - pixelformat); - - setFdFormat = true; - } - - if (setFdFormat) - setFdFormat(v4l2_format, fmtPix, size, pixelformat); - } - finally - { - Video4Linux2.free(v4l2_format); - } - } - - /** - * Sets the Format in which the Video for Linux Two API - * Specification device represented by the fd of this instance is - * to capture media data. - * - * @param v4l2_format native format to set on the Video for Linux Two API - * Specification device - * @param fmtPix native pixel format of the device - * @param size size to set on the device - * @param pixelformat requested pixel format - * @throws IOException if anything goes wrong while setting the - * native format of the media data to be captured by the Video for Linux - * Two API Specification device represented by the fd of this - * instance - */ - private void setFdFormat( - long v4l2_format, - long fmtPix, - Dimension size, - int pixelformat) - throws IOException - { - Video4Linux2.v4l2_pix_format_setField( - fmtPix, - Video4Linux2.V4L2_FIELD_NONE); - Video4Linux2.v4l2_pix_format_setBytesperline(fmtPix, 0); - - if (Video4Linux2.ioctl( - fd, - Video4Linux2.VIDIOC_S_FMT, - v4l2_format) - == -1) - { - throw - new IOException( - "ioctl: request= VIDIOC_S_FMT" - + ((size == null) - ? "" - : (", width= " - + size.width - + ", height= " - + size.height)) - + ", pixelformat= " - + pixelformat); - } - else if (Video4Linux2.v4l2_pix_format_getPixelformat(fmtPix) - != pixelformat) - { - throw - new IOException( - "Failed to change the format of the V4L2 device to " - + pixelformat); - } - } - - /** - * Starts the transfer of media data from this PullBufferStream. - * - * @throws IOException if anything goes wrong while starting the transfer of - * media data from this PullBufferStream - * @see AbstractPullBufferStream#start() - */ - @Override - public void start() - throws IOException - { - super.start(); - - long v4l2_buffer - = Video4Linux2.v4l2_buffer_alloc( - Video4Linux2.V4L2_BUF_TYPE_VIDEO_CAPTURE); - - if (0 == v4l2_buffer) - throw new OutOfMemoryError("v4l2_buffer_alloc"); - try - { - Video4Linux2.v4l2_buffer_setMemory( - v4l2_buffer, - Video4Linux2.V4L2_MEMORY_MMAP); - for (int i = 0; i < requestbuffersCount; i++) - { - Video4Linux2.v4l2_buffer_setIndex(v4l2_buffer, i); - if (Video4Linux2.ioctl( - fd, - Video4Linux2.VIDIOC_QBUF, - v4l2_buffer) - == -1) - { - throw - new IOException( - "ioctl: request= VIDIOC_QBUF, index= " + i); - } - } - } - finally - { - Video4Linux2.free(v4l2_buffer); - } - - /* we will start capture in read() method (i.e do the VIDIOC_STREAMON - * ioctl) because for some couple of fps/resolution the captured image - * will be weird (shift, not a JPEG for JPEG/MJPEG format, ...) - * if it is done here. Maybe it is due because sometime JMF do the - * sequence start/stop/start too quickly... - */ - startInRead = true; - } - - /** - * Stops the transfer of media data from this PullBufferStream. - * - * @throws IOException if anything goes wrong while stopping the transfer of - * media data from this PullBufferStream - * @see AbstractPullBufferStream#stop() - */ - @Override - public void stop() - throws IOException - { - try - { - long v4l2_buf_type - = Video4Linux2.v4l2_buf_type_alloc( - Video4Linux2.V4L2_BUF_TYPE_VIDEO_CAPTURE); - - if (0 == v4l2_buf_type) - throw new OutOfMemoryError("v4l2_buf_type_alloc"); - try - { - if (Video4Linux2.ioctl( - fd, - Video4Linux2.VIDIOC_STREAMOFF, - v4l2_buf_type) - == -1) - { - throw new IOException("ioctl: request= VIDIOC_STREAMOFF"); - } - } - finally - { - Video4Linux2.free(v4l2_buf_type); - } - } - finally - { - super.stop(); - - if(mjpeg_context > 0) - { - FFmpeg.avcodec_close(mjpeg_context); - FFmpeg.av_free(mjpeg_context); - } - mjpeg_context = 0; - - if(avframe > 0) - { - FFmpeg.av_free(avframe); - } - avframe = 0; - - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/AbstractRenderer.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/AbstractRenderer.java deleted file mode 100644 index 6223945e7..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/AbstractRenderer.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.renderer; - -import javax.media.*; - -import net.java.sip.communicator.impl.neomedia.control.*; - -/** - * Provides an abstract base implementation of Renderer in order to - * facilitate extenders - * - * @author Lyubomir Marinov - * - * @param the type of Format of the media data processed - * as input by AbstractRenderer - */ -public abstract class AbstractRenderer - extends ControlsAdapter - implements Renderer -{ - /** - * The Format of the media data processed as input by this - * Renderer. - */ - protected InputFormatT inputFormat; - - /** - * Resets the state of this PlugIn. - */ - public void reset() - { - // TODO Auto-generated method stub - } - - /** - * Sets the Format of the media data to be rendered by this - * Renderer. - * - * @param format the Format of the media data to be rendered by - * this Renderer - * @return null if the specified format is not compatible - * with this Renderer; otherwise, the Format which has - * been successfully set - */ - @SuppressWarnings("unchecked") - public Format setInputFormat(Format format) - { - Format matchingFormat = null; - - for (Format supportedInputFormat : getSupportedInputFormats()) - { - if (supportedInputFormat.matches(format)) - { - matchingFormat = supportedInputFormat.intersects(format); - break; - } - } - if (matchingFormat == null) - return null; - - inputFormat = (InputFormatT) matchingFormat; - return inputFormat; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/audio/PortAudioRenderer.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/audio/PortAudioRenderer.java deleted file mode 100644 index a2236cb12..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/audio/PortAudioRenderer.java +++ /dev/null @@ -1,686 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.audio; - -import java.util.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.portaudio.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.*; -import net.java.sip.communicator.impl.neomedia.portaudio.*; -import net.java.sip.communicator.util.*; - -/** - * Implements an audio Renderer which uses PortAudio. - * - * @author Damian Minkov - * @author Lyubomir Marinov - */ -public class PortAudioRenderer - extends AbstractRenderer -{ - /** - * The Logger used by the PortAudioRenderer class and its - * instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(PortAudioRenderer.class); - - /** - * The constant which represents an empty array with - * Format element type. Explicitly defined in order to - * reduce unnecessary allocations. - */ - private static final Format[] EMPTY_SUPPORTED_INPUT_FORMATS - = new Format[0]; - - /** - * The human-readable name of the PortAudioRenderer JMF plug-in. - */ - private static final String PLUGIN_NAME = "PortAudio Renderer"; - - /** - * The list of JMF Formats of audio data which - * PortAudioRenderer instances are capable of rendering. - */ - private static final Format[] SUPPORTED_INPUT_FORMATS; - - /** - * The list of the sample rates supported by PortAudioRenderer as - * input. - */ - private static final double[] SUPPORTED_INPUT_SAMPLE_RATES - = new double[] { 8000, 11025, 16000, 22050, 32000, 44100, 48000 }; - - static - { - int count = SUPPORTED_INPUT_SAMPLE_RATES.length; - - SUPPORTED_INPUT_FORMATS = new Format[count]; - for (int i = 0; i < count; i++) - { - SUPPORTED_INPUT_FORMATS[i] - = new AudioFormat( - AudioFormat.LINEAR, - SUPPORTED_INPUT_SAMPLE_RATES[i], - 16 /* sampleSizeInBits */, - Format.NOT_SPECIFIED /* channels */, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED /* frameSizeInBits */, - Format.NOT_SPECIFIED /* frameRate */, - Format.byteArray); - } - } - - /** - * The audio samples left unwritten by a previous call to - * {@link #process(Buffer)}. As {@link #bytesPerBuffer} number of - * bytes are always written, the number of the unwritten audio samples is - * always less than that. - */ - private byte[] bufferLeft; - - /** - * The number of bytes in {@link #bufferLeft} representing unwritten audio - * samples. - */ - private int bufferLeftLength = 0; - - /** - * The number of bytes to write to the native PortAudio stream represented - * by this instance with a single invocation. Based on - * {@link #framesPerBuffer}. - */ - private int bytesPerBuffer; - - /** - * The number of frames to write to the native PortAudio stream represented - * by this instance with a single invocation. - */ - private int framesPerBuffer; - - /** - * The MediaLocator which specifies the device index of the - * PortAudio device used by this instance for rendering. - */ - private MediaLocator locator; - - private long outputParameters = 0; - - /** - * The indicator which determines whether this Renderer is started. - */ - private boolean started = false; - - /** - * The output PortAudio stream represented by this instance. - */ - private long stream = 0; - - /** - * The indicator which determines whether {@link #stream} is busy and should - * not, for example, be closed. - */ - private boolean streamIsBusy = false; - - /** - * Array of supported input formats. - */ - private Format[] supportedInputFormats; - - /** - * The GainControl through which volume/gain of rendered media is - * controlled. - */ - private final GainControl gainControl; - - /** - * Initializes a new PortAudioRenderer instance. - */ - public PortAudioRenderer() - { - this(true); - } - - /** - * Initializes a new PortAudioRenderer instance. - * - * @param enableVolumeControl true to enable volume control; - * false, otherwise - */ - public PortAudioRenderer(boolean enableVolumeControl) - { - if (enableVolumeControl) - { - /* - * XXX The Renderer implementations are probed for their - * supportedInputFormats during the initialization of - * MediaServiceImpl so the latter may not be available at this time. - * Which is not much of a problem given than the GainControl is of - * no interest during the probing of the supportedInputFormats. - */ - MediaServiceImpl mediaServiceImpl - = NeomediaActivator.getMediaServiceImpl(); - - gainControl - = (mediaServiceImpl == null) - ? null - : (GainControl) mediaServiceImpl.getOutputVolumeControl(); - } - else - gainControl = null; - } - - /** - * Closes this PlugIn. - */ - public synchronized void close() - { - try - { - stop(); - } - finally - { - if (stream != 0) - { - try - { - PortAudio.Pa_CloseStream(stream); - stream = 0; - } - catch (PortAudioException paex) - { - logger.error("Failed to close PortAudio stream.", paex); - } - } - if ((stream == 0) && (outputParameters != 0)) - { - PortAudio.PaStreamParameters_free(outputParameters); - outputParameters = 0; - } - } - } - - /** - * Implements {@link javax.media.Controls#getControls()}. Gets the controls - * available for the owner of this instance. The current implementation - * returns an empty array because it has no available controls. - * - * @return an array of Objects which represent the controls - * available for the owner of this instance - */ - public Object[] getControls() - { - return new Object[] { gainControl }; - } - - /** - * Gets the MediaLocator which specifies the device index of the - * PortAudio device used by this instance for rendering. - * - * @return the MediaLocator which specifies the device index of the - * PortAudio device used by this instance for rendering - */ - public MediaLocator getLocator() - { - MediaLocator locator = this.locator; - - if (locator == null) - { - AudioSystem portAudioSystem - = AudioSystem.getAudioSystem( - AudioSystem.LOCATOR_PROTOCOL_PORTAUDIO); - - if (portAudioSystem != null) - { - CaptureDeviceInfo playbackDevice - = portAudioSystem.getPlaybackDevice(); - - if (playbackDevice != null) - locator = playbackDevice.getLocator(); - } - } - return locator; - } - - /** - * Gets the descriptive/human-readable name of this JMF plug-in. - * - * @return the descriptive/human-readable name of this JMF plug-in - */ - public String getName() - { - return PLUGIN_NAME; - } - - /** - * Gets the list of JMF Formats of audio data which this - * Renderer is capable of rendering. - * - * @return an array of JMF Formats of audio data which this - * Renderer is capable of rendering - */ - public Format[] getSupportedInputFormats() - { - if (supportedInputFormats == null) - { - MediaLocator locator = getLocator(); - int deviceIndex; - - if ((locator == null) - || ((deviceIndex = DataSource.getDeviceIndex(locator)) - == PortAudio.paNoDevice)) - supportedInputFormats = SUPPORTED_INPUT_FORMATS; - else - { - long deviceInfo = PortAudio.Pa_GetDeviceInfo(deviceIndex); - - if (deviceInfo == 0) - supportedInputFormats = SUPPORTED_INPUT_FORMATS; - else - { - int minOutputChannels = 1; - /* - * The maximum output channels may be a lot and checking all - * of them will take a lot of time. Besides, we currently - * support at most 2. - */ - int maxOutputChannels - = Math.min( - PortAudio.PaDeviceInfo_getMaxOutputChannels( - deviceInfo), - 2); - List supportedInputFormats - = new ArrayList(SUPPORTED_INPUT_FORMATS.length); - - for (Format supportedInputFormat : SUPPORTED_INPUT_FORMATS) - { - getSupportedInputFormats( - supportedInputFormat, - deviceIndex, - minOutputChannels, - maxOutputChannels, - supportedInputFormats); - } - this.supportedInputFormats - = supportedInputFormats.isEmpty() - ? EMPTY_SUPPORTED_INPUT_FORMATS - : supportedInputFormats.toArray( - EMPTY_SUPPORTED_INPUT_FORMATS); - } - } - } - return - (supportedInputFormats.length == 0) - ? EMPTY_SUPPORTED_INPUT_FORMATS - : supportedInputFormats.clone(); - } - - private void getSupportedInputFormats( - Format format, - int deviceIndex, - int minOutputChannels, int maxOutputChannels, - List supportedInputFormats) - { - AudioFormat audioFormat = (AudioFormat) format; - int sampleSizeInBits = audioFormat.getSampleSizeInBits(); - long sampleFormat = PortAudio.getPaSampleFormat(sampleSizeInBits); - double sampleRate = audioFormat.getSampleRate(); - - for (int channels = minOutputChannels; - channels <= maxOutputChannels; - channels++) - { - long outputParameters - = PortAudio.PaStreamParameters_new( - deviceIndex, - channels, - sampleFormat, - PortAudio.LATENCY_UNSPECIFIED); - - if (outputParameters != 0) - { - try - { - if (PortAudio.Pa_IsFormatSupported( - 0, - outputParameters, - sampleRate)) - { - supportedInputFormats.add( - new AudioFormat( - audioFormat.getEncoding(), - sampleRate, - sampleSizeInBits, - channels, - audioFormat.getEndian(), - audioFormat.getSigned(), - Format.NOT_SPECIFIED /* frameSizeInBits */, - Format.NOT_SPECIFIED /* frameRate */, - audioFormat.getDataType())); - } - } - finally - { - PortAudio.PaStreamParameters_free(outputParameters); - } - } - } - } - - /** - * Opens the PortAudio device and output stream represented by this instance - * which are to be used to render audio. - * - * @throws ResourceUnavailableException if the PortAudio device or output - * stream cannot be created or opened - */ - public synchronized void open() - throws ResourceUnavailableException - { - try - { - doOpen(); - } - catch (Throwable t) - { - /* - * Log the problem because FMJ may swallow it and thus make - * debugging harder than necessary. - */ - if (logger.isDebugEnabled()) - logger.debug("Failed to open PortAudioRenderer", t); - - if (t instanceof ThreadDeath) - throw (ThreadDeath) t; - else if (t instanceof ResourceUnavailableException) - throw (ResourceUnavailableException) t; - else - { - ResourceUnavailableException rue - = new ResourceUnavailableException(); - - rue.initCause(t); - throw rue; - } - } - } - - /** - * Opens the PortAudio device and output stream represented by this instance - * which are to be used to render audio. - * - * @throws ResourceUnavailableException if the PortAudio device or output - * stream cannot be created or opened - */ - private void doOpen() - throws ResourceUnavailableException - { - if (stream == 0) - { - MediaLocator locator = getLocator(); - - if (locator == null) - throw new ResourceUnavailableException("locator not set"); - - int deviceIndex = DataSource.getDeviceIndex(locator); - AudioFormat inputFormat = this.inputFormat; - - if (inputFormat == null) - throw new ResourceUnavailableException("inputFormat not set"); - - int channels = inputFormat.getChannels(); - - if (channels == Format.NOT_SPECIFIED) - channels = 1; - - long sampleFormat - = PortAudio.getPaSampleFormat( - inputFormat.getSampleSizeInBits()); - double sampleRate = inputFormat.getSampleRate(); - - framesPerBuffer - = (int) - ((sampleRate * PortAudio.DEFAULT_MILLIS_PER_BUFFER) - / (channels * 1000)); - - try - { - outputParameters - = PortAudio.PaStreamParameters_new( - deviceIndex, - channels, - sampleFormat, - PortAudio.getSuggestedLatency()); - - stream - = PortAudio.Pa_OpenStream( - 0 /* inputParameters */, - outputParameters, - sampleRate, - framesPerBuffer, - PortAudio.STREAM_FLAGS_CLIP_OFF - | PortAudio.STREAM_FLAGS_DITHER_OFF, - null /* streamCallback */); - } - catch (PortAudioException paex) - { - throw new ResourceUnavailableException(paex.getMessage()); - } - finally - { - if ((stream == 0) && (outputParameters != 0)) - { - PortAudio.PaStreamParameters_free(outputParameters); - outputParameters = 0; - } - } - if (stream == 0) - throw new ResourceUnavailableException("Pa_OpenStream"); - - bytesPerBuffer - = PortAudio.Pa_GetSampleSize(sampleFormat) - * channels - * framesPerBuffer; - } - } - - /** - * Renders the audio data contained in a specific Buffer onto the - * PortAudio device represented by this Renderer. - * - * @param buffer the Buffer which contains the audio data to be - * rendered - * @return BUFFER_PROCESSED_OK if the specified buffer has - * been successfully processed - */ - public int process(Buffer buffer) - { - synchronized (this) - { - if (!started || (stream == 0)) - return BUFFER_PROCESSED_OK; - else - streamIsBusy = true; - } - try - { - process( - (byte[]) buffer.getData(), - buffer.getOffset(), - buffer.getLength()); - } - catch (PortAudioException paex) - { - logger.error("Failed to process Buffer.", paex); - } - finally - { - synchronized (this) - { - streamIsBusy = false; - notifyAll(); - } - } - return BUFFER_PROCESSED_OK; - } - - private void process(byte[] buffer, int offset, int length) - throws PortAudioException - { - - /* - * If there are audio samples left unwritten from a previous write, - * prepend them to the specified buffer. If it's possible to write them - * now, do it. - */ - if ((bufferLeft != null) && (bufferLeftLength > 0)) - { - int numberOfBytesInBufferLeftToBytesPerBuffer - = bytesPerBuffer - bufferLeftLength; - int numberOfBytesToCopyToBufferLeft - = (numberOfBytesInBufferLeftToBytesPerBuffer < length) - ? numberOfBytesInBufferLeftToBytesPerBuffer - : length; - - System - .arraycopy( - buffer, - offset, - bufferLeft, - bufferLeftLength, - numberOfBytesToCopyToBufferLeft); - offset += numberOfBytesToCopyToBufferLeft; - length -= numberOfBytesToCopyToBufferLeft; - bufferLeftLength += numberOfBytesToCopyToBufferLeft; - - if (bufferLeftLength == bytesPerBuffer) - { - PortAudio.Pa_WriteStream(stream, bufferLeft, framesPerBuffer); - bufferLeftLength = 0; - } - } - - // Write the audio samples from the specified buffer. - int numberOfWrites = length / bytesPerBuffer; - - if (numberOfWrites > 0) - { - // if we have some volume setting apply them - if (gainControl != null) - { - AbstractVolumeControl.applyGain( - gainControl, - buffer, offset, length); - } - - PortAudio.Pa_WriteStream( - stream, - buffer, offset, framesPerBuffer, - numberOfWrites); - - int bytesWritten = numberOfWrites * bytesPerBuffer; - - offset += bytesWritten; - length -= bytesWritten; - } - - // If anything was left unwritten, remember it for next time. - if (length > 0) - { - if (bufferLeft == null) - bufferLeft = new byte[bytesPerBuffer]; - System.arraycopy(buffer, offset, bufferLeft, 0, length); - bufferLeftLength = length; - } - } - - /** - * Sets the MediaLocator which specifies the device index of the - * PortAudio device to be used by this instance for rendering. - * - * @param locator a MediaLocator which specifies the device index - * of the PortAudio device to be used by this instance for rendering - */ - public void setLocator(MediaLocator locator) - { - if (this.locator == null) - { - if (locator == null) - return; - } - else if (this.locator.equals(locator)) - return; - - this.locator = locator; - supportedInputFormats = null; - } - - /** - * Starts the rendering process. Any audio data available in the internal - * resources associated with this PortAudioRenderer will begin - * being rendered. - */ - public synchronized void start() - { - if (!started && (stream != 0)) - { - try - { - PortAudio.Pa_StartStream(stream); - started = true; - } - catch (PortAudioException paex) - { - logger.error("Failed to start PortAudio stream.", paex); - } - } - } - - /** - * Stops the rendering process. - */ - public synchronized void stop() - { - boolean interrupted = false; - - while (streamIsBusy) - { - try - { - wait(); - } - catch (InterruptedException iex) - { - interrupted = true; - } - } - if (interrupted) - Thread.currentThread().interrupt(); - - if (started && (stream != 0)) - { - try - { - PortAudio.Pa_StopStream(stream); - started = false; - - bufferLeft = null; - } - catch (PortAudioException paex) - { - logger.error("Failed to close PortAudio stream.", paex); - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/audio/PulseAudioRenderer.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/audio/PulseAudioRenderer.java deleted file mode 100644 index a7b972062..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/audio/PulseAudioRenderer.java +++ /dev/null @@ -1,543 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.audio; - -import java.io.*; -import java.lang.reflect.*; - -import javax.media.*; -import javax.media.format.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.*; -import net.java.sip.communicator.impl.neomedia.pulseaudio.*; - -public class PulseAudioRenderer - extends AbstractRenderer -{ - /** - * The human-readable PlugIn name of the - * PulseAudioRenderer instances. - */ - private static final String PLUGIN_NAME = "PulseAudio Renderer"; - - private static final boolean SOFTWARE_GAIN = false; - - private static final Format[] SUPPORTED_INPUT_FORMATS - = new Format[] - { - new AudioFormat( - AudioFormat.LINEAR, - Format.NOT_SPECIFIED /* sampleRate */, - 16, - Format.NOT_SPECIFIED /* channels */, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED /* frameSizeInBits */, - Format.NOT_SPECIFIED /* frameRate */, - Format.byteArray) - }; - - private int channels; - - private boolean corked = true; - - private long cvolume; - - private final GainControl gainControl; - - private float gainControlLevel; - - private MediaLocator locator; - - private final String mediaRole; - - private final PulseAudioSystem pulseAudioSystem; - - private long stream; - - private final PA.stream_request_cb_t writeCallback - = new PA.stream_request_cb_t() - { - public void callback(long s, int nbytes) - { - pulseAudioSystem.signalMainloop(false); - } - }; - - /** - * Initializes a new PulseAudioRenderer instance. - */ - public PulseAudioRenderer() - { - this(null); - } - - public PulseAudioRenderer(String mediaRole) - { - pulseAudioSystem = PulseAudioSystem.getPulseAudioSystem(); - if (pulseAudioSystem == null) - throw new IllegalStateException("pulseAudioSystem"); - - this.mediaRole - = (mediaRole == null) - ? PulseAudioSystem.MEDIA_ROLE_PHONE - : mediaRole; - - if (PulseAudioSystem.MEDIA_ROLE_PHONE.equals(this.mediaRole)) - { - /* - * XXX The Renderer implementations are probed for their - * supportedInputFormats during the initialization of - * MediaServiceImpl so the latter may not be available at this time. - * Which is not much of a problem given than the GainControl is of - * no interest during the probing of the supportedInputFormats. - */ - MediaServiceImpl mediaServiceImpl - = NeomediaActivator.getMediaServiceImpl(); - - gainControl - = (mediaServiceImpl == null) - ? null - : (GainControl) mediaServiceImpl.getOutputVolumeControl(); - } - else - gainControl = null; - } - - public void close() - { - pulseAudioSystem.lockMainloop(); - try - { - long stream = this.stream; - - if (stream != 0) - { - try - { - stopWithMainloopLock(); - } - finally - { - long cvolume = this.cvolume; - - this.cvolume = 0; - this.stream = 0; - - corked = true; - - pulseAudioSystem.signalMainloop(false); - - if (cvolume != 0) - PA.cvolume_free(cvolume); - PA.stream_disconnect(stream); - PA.stream_unref(stream); - } - } - } - finally - { - pulseAudioSystem.unlockMainloop(); - } - } - - private void cork(boolean b) - { - try - { - PulseAudioSystem.corkStream(stream, b); - corked = b; - } - catch (IOException ioe) - { - throw new UndeclaredThrowableException(ioe); - } - finally - { - pulseAudioSystem.signalMainloop(false); - } - } - - public MediaLocator getLocator() - { - MediaLocator locator = this.locator; - - if (locator == null) - { - CaptureDeviceInfo playbackDevice - = pulseAudioSystem.getPlaybackDevice(); - - if (playbackDevice != null) - locator = playbackDevice.getLocator(); - } - return locator; - } - - private String getLocatorDev() - { - MediaLocator locator = getLocator(); - String locatorDev; - - if (locator == null) - locatorDev = null; - else - { - locatorDev = locator.getRemainder(); - if ((locatorDev != null) && (locatorDev.length() <= 0)) - locatorDev = null; - } - return locatorDev; - } - - public String getName() - { - return PLUGIN_NAME; - } - - public Format[] getSupportedInputFormats() - { - return SUPPORTED_INPUT_FORMATS.clone(); - } - - public void open() - throws ResourceUnavailableException - { - pulseAudioSystem.lockMainloop(); - try - { - openWithMainloopLock(); - } - finally - { - pulseAudioSystem.unlockMainloop(); - } - } - - private void openWithMainloopLock() - throws ResourceUnavailableException - { - if (stream != 0) - return; - - AudioFormat format = this.inputFormat; - int sampleRate = (int) format.getSampleRate(); - int channels = format.getChannels(); - int sampleSizeInBits = format.getSampleSizeInBits(); - - if ((sampleRate == Format.NOT_SPECIFIED) - && (MediaUtils.MAX_AUDIO_SAMPLE_RATE - != Format.NOT_SPECIFIED)) - sampleRate = (int) MediaUtils.MAX_AUDIO_SAMPLE_RATE; - if (channels == Format.NOT_SPECIFIED) - channels = 1; - if (sampleSizeInBits == Format.NOT_SPECIFIED) - sampleSizeInBits = 16; - - long stream = 0; - Throwable exception = null; - - try - { - stream - = pulseAudioSystem.createStream( - sampleRate, - channels, - getClass().getName(), - mediaRole); - this.channels = channels; - } - catch (IllegalStateException ise) - { - exception = ise; - } - catch (RuntimeException re) - { - exception = re; - } - if (exception != null) - { - ResourceUnavailableException rue - = new ResourceUnavailableException(); - - rue.initCause(exception); - throw rue; - } - if (stream == 0) - throw new ResourceUnavailableException("stream"); - - try - { - long attr - = PA.buffer_attr_new( - -1, - 2 /* millis / 10 */ - * (sampleRate / 100) - * channels - * (sampleSizeInBits / 8), - -1, - -1, - -1); - - if (attr == 0) - throw new ResourceUnavailableException("pa_buffer_attr_new"); - - try - { - Runnable stateCallback - = new Runnable() - { - public void run() - { - pulseAudioSystem.signalMainloop(false); - } - }; - - PA.stream_set_state_callback( - stream, - stateCallback); - PA.stream_connect_playback( - stream, - getLocatorDev(), - attr, - PA.STREAM_ADJUST_LATENCY - | PA.STREAM_START_CORKED, - 0, - 0); - - try - { - if (attr != 0) - { - PA.buffer_attr_free(attr); - attr = 0; - } - - int state - = pulseAudioSystem.waitForStreamState( - stream, - PA.STREAM_READY); - - if (state != PA.STREAM_READY) - throw new ResourceUnavailableException("stream.state"); - - PA.stream_set_write_callback( - stream, - writeCallback); - - if (!SOFTWARE_GAIN && (gainControl != null)) - { - cvolume = PA.cvolume_new(); - - boolean freeCvolume = true; - - try - { - float gainControlLevel = gainControl.getLevel(); - - setStreamVolume(stream, gainControlLevel); - this.gainControlLevel = gainControlLevel; - freeCvolume = false; - } - finally - { - if (freeCvolume) - { - PA.cvolume_free(cvolume); - cvolume = 0; - } - } - } - - this.stream = stream; - } - finally - { - if (this.stream == 0) - PA.stream_disconnect(stream); - } - } - finally - { - if (attr != 0) - PA.buffer_attr_free(attr); - } - } - finally - { - if (this.stream == 0) - PA.stream_unref(stream); - } - } - - public int process(Buffer buffer) - { - if (buffer.isDiscard()) - return BUFFER_PROCESSED_OK; - if (buffer.getLength() <= 0) - return BUFFER_PROCESSED_OK; - - int ret; - - pulseAudioSystem.lockMainloop(); - try - { - ret = processWithMainloopLock(buffer); - } - finally - { - pulseAudioSystem.unlockMainloop(); - } - if ((ret != BUFFER_PROCESSED_FAILED) && (buffer.getLength() > 0)) - ret |= INPUT_BUFFER_NOT_CONSUMED; - - return ret; - } - - private int processWithMainloopLock(Buffer buffer) - { - if ((stream == 0) || corked) - return BUFFER_PROCESSED_FAILED; - - int writableSize = PA.stream_writable_size(stream); - int ret; - - if (writableSize <= 0) - { - pulseAudioSystem.waitMainloop(); - ret = BUFFER_PROCESSED_OK; - } - else - { - byte[] data = (byte[]) buffer.getData(); - int offset = buffer.getOffset(); - int length = buffer.getLength(); - - if (length < writableSize) - writableSize = length; - - if (gainControl != null) - { - if (SOFTWARE_GAIN || (cvolume == 0)) - { - if (length > 0) - { - AbstractVolumeControl.applyGain( - gainControl, - data, offset, writableSize); - } - } - else - { - float gainControlLevel = gainControl.getLevel(); - - if (this.gainControlLevel != gainControlLevel) - { - this.gainControlLevel = gainControlLevel; - setStreamVolume(stream, gainControlLevel); - } - } - } - - int writtenSize - = PA.stream_write( - stream, - data, offset, writableSize, - null, - 0, - PA.SEEK_RELATIVE); - - if (writtenSize < 0) - ret = BUFFER_PROCESSED_FAILED; - else - { - ret = BUFFER_PROCESSED_OK; - buffer.setLength(length - writtenSize); - buffer.setOffset(offset + writtenSize); - } - } - - return ret; - } - - public void setLocator(MediaLocator locator) - { - if (this.locator == null) - { - if (locator == null) - return; - } - else if (this.locator.equals(locator)) - return; - - this.locator = locator; - } - - private void setStreamVolume(long stream, float level) - { - int volume - = PA.sw_volume_from_linear( - level * (AbstractVolumeControl.MAX_VOLUME_PERCENT / 100)); - - PA.cvolume_set(cvolume, channels, volume); - - long o - = PA.context_set_sink_input_volume( - pulseAudioSystem.getContext(), - PA.stream_get_index(stream), - cvolume, - null); - - if (o != 0) - PA.operation_unref(o); - } - - public void start() - { - pulseAudioSystem.lockMainloop(); - try - { - if (stream == 0) - { - try - { - openWithMainloopLock(); - } - catch (ResourceUnavailableException rue) - { - throw new UndeclaredThrowableException(rue); - } - } - - cork(false); - } - finally - { - pulseAudioSystem.unlockMainloop(); - } - } - - public void stop() - { - pulseAudioSystem.lockMainloop(); - try - { - stopWithMainloopLock(); - } - finally - { - pulseAudioSystem.unlockMainloop(); - } - } - - private void stopWithMainloopLock() - { - if (stream != 0) - cork(true); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java deleted file mode 100644 index 05aeab814..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java +++ /dev/null @@ -1,640 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.video; - -import java.awt.*; -import java.lang.reflect.*; - -import javax.media.*; -import javax.media.format.*; -import javax.media.renderer.*; -import javax.swing.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.util.*; - -/** - * Implements a VideoRenderer which uses JAWT to perform native - * painting in an AWT or Swing Component. - * - * @author Lyubomir Marinov - */ -public class JAWTRenderer - extends AbstractRenderer - implements VideoRenderer -{ - /** - * The Logger used by the JAWTRenderer class and its - * instances for logging output. - */ - private static final Logger logger = Logger.getLogger(JAWTRenderer.class); - - /** - * The human-readable PlugIn name of the JAWTRenderer - * instances. - */ - private static final String PLUGIN_NAME = "JAWT Renderer"; - - /** - * The array of supported input formats. - */ - private static final Format[] SUPPORTED_INPUT_FORMATS - = new Format[] - { - OSUtils.IS_LINUX - ? new YUVFormat( - null /* size */, - Format.NOT_SPECIFIED /* maxDataLength */, - Format.intArray, - Format.NOT_SPECIFIED /* frameRate */, - YUVFormat.YUV_420, - Format.NOT_SPECIFIED /* strideY */, - Format.NOT_SPECIFIED /* strideUV */, - Format.NOT_SPECIFIED /* offsetY */, - Format.NOT_SPECIFIED /* offsetU */, - Format.NOT_SPECIFIED /* offsetV */) - : new RGBFormat( - null, - Format.NOT_SPECIFIED, - Format.intArray, - Format.NOT_SPECIFIED, - 32, - 0x00FF0000, 0x0000FF00, 0x000000FF) - }; - - /** - * The indicator which determines whether CALayer-based painting is - * to be performed by JAWTRenderer on Mac OS X. - */ - private static final boolean USE_MACOSX_CALAYERS; - - static - { - System.loadLibrary("jnawtrenderer"); - - /* - * XXX The native JAWTRenderer implementation on Mac OS X which paints - * in a CALayer-like fashion has been determined through testing to not - * work as expected on MacBookPro8. Unfortunately, the cause of the - * problem has not been determined. As a workaround, fall back to the - * alternative implementation (currently used on the other supported - * operating systems) on the problematic model. - */ - if (OSUtils.IS_MAC) - { - ConfigurationService cfg - = NeomediaActivator.getConfigurationService(); - - if ((cfg == null) - || cfg.getBoolean( - JAWTRenderer.class.getName() - + ".USE_MACOSX_CALAYERS", - false)) - { - String hwModel = sysctlbyname("hw.model"); - - USE_MACOSX_CALAYERS - = (hwModel == null) - || !(hwModel.startsWith("MacBookPro8") - || hwModel.startsWith("MacBookAir4")); - } - else - USE_MACOSX_CALAYERS = false; - } - else - { - // CALayer-like painting is currently only supported on Mac OS X. - USE_MACOSX_CALAYERS = false; - } - } - - /** - * The AWT Component into which this VideoRenderer draws. - */ - private Component component; - - /** - * The handle to the native counterpart of this JAWTRenderer. - */ - private long handle = 0; - - /** - * The last known height of the input processed by this - * JAWTRenderer. - */ - private int inputHeight = 0; - - /** - * The last known width of the input processed by this - * JAWTRenderer. - */ - private int inputWidth = 0; - - /** - * Initializes a new JAWTRenderer instance. - */ - public JAWTRenderer() - { - } - - static native void addNotifyLightweightComponent( - long handle, Component component, - long parentHandle); - - /** - * Closes this PlugIn and releases the resources it has retained - * during its execution. No more data will be accepted by this - * PlugIn afterwards. A closed PlugIn can be reinstated by - * calling open again. - */ - public synchronized void close() - { - if (handle != 0) - { - try - { - /* - * It may or may not be necessary to ensure that #removeNotify() - * is delivered to the native counterpart of this JAWTRenderer. - * Anyway, do so for the sake of completeness. - */ - /* - * Unfortunately, doing so in the synchronized block leads to a - * deadlock. - */ -// if (JComponent.isLightweightComponent(component)) -// { -// Container parent = component.getParent(); -// -// if (parent != null) -// parent.remove(component); -// } - } - finally - { - close(handle, component); - handle = 0; - } - } - } - - /** - * Closes the native counterpart of a JAWTRenderer specified by its - * handle as returned by {@link #open(Component)} and rendering into a - * specific AWT Component. Releases the resources which the - * specified native counterpart has retained during its execution and its - * handle is considered to be invalid afterwards. - * - * @param handle the handle to the native counterpart of a - * JAWTRenderer as returned by {@link #open(Component)} which is to - * be closed - * @param component the AWT Component into which the - * JAWTRenderer and its native counterpart are drawing. The - * platform-specific info of component is not guaranteed to be - * valid. - */ - static native void close(long handle, Component component); - - /** - * Gets the region in the component of this VideoRenderer where the - * video is rendered. - * - * @return the region in the component of this VideoRenderer where - * the video is rendered; null if the entire component is used - */ - public Rectangle getBounds() - { - // TODO Auto-generated method stub - return null; - } - - /** - * Gets the AWT Component into which this VideoRenderer - * draws. - * - * @return the AWT Component into which this VideoRenderer - * draws - */ - public synchronized Component getComponent() - { - if (component == null) - { - StringBuilder componentClassName = new StringBuilder(); - - componentClassName.append(JAWTRenderer.class.getName()); - if (USE_MACOSX_CALAYERS && OSUtils.IS_MAC) - componentClassName.append("Swing"); - else if (OSUtils.IS_ANDROID) - componentClassName.append("Android"); - componentClassName.append("VideoComponent"); - - Class componentClass; - - try - { - componentClass = Class.forName(componentClassName.toString()); - } - catch (ClassNotFoundException cnfe) - { - throw new RuntimeException(cnfe); - } - - Constructor componentConstructor; - - try - { - componentConstructor - = componentClass.getConstructor(JAWTRenderer.class); - } - catch (NoSuchMethodException nsme) - { - throw new RuntimeException(nsme); - } - try - { - component = (Component) componentConstructor.newInstance(this); - } - catch (IllegalAccessException iae) - { - throw new RuntimeException(iae); - } - catch (InstantiationException ie) - { - throw new RuntimeException(ie); - } - catch (InvocationTargetException ite) - { - throw new RuntimeException(ite); - } - } - return component; - } - - /** - * Gets the handle to the native counterpart of this JAWTRenderer. - * - * @return the handle to the native counterpart of this - * JAWTRenderer - */ - long getHandle() - { - return handle; - } - - /** - * Gets the Object which synchronizes the access to the handle to - * the native counterpart of this JAWTRenderer. - * - * @return the Object which synchronizes the access to the handle - * to the native counterpart of this JAWTRenderer - */ - Object getHandleLock() - { - return this; - } - - /** - * Gets the human-readable name of this PlugIn. - * - * @return the human-readable name of this PlugIn - */ - public String getName() - { - return PLUGIN_NAME; - } - - /** - * Gets the list of input Formats supported by this - * Renderer. - * - * @return an array of Format elements which represent the input - * Formats supported by this Renderer - */ - public Format[] getSupportedInputFormats() - { - return SUPPORTED_INPUT_FORMATS.clone(); - } - - /** - * Opens this PlugIn and acquires the resources that it needs to - * operate. The input format of this Renderer has to be set before - * open is called. Buffers should not be passed into this - * PlugIn without first calling open. - * - * @throws ResourceUnavailableException if there is a problem during opening - */ - public void open() - throws ResourceUnavailableException - { - boolean addNotify; - final Component component; - - synchronized (this) - { - if (handle == 0) - { - /* - * If this JAWTRenderer gets opened after its visual/video - * Component has been created, send addNotify to the Component - * once this JAWTRenderer gets opened so that the Component may - * use the handle if it needs to. - */ - addNotify - = (this.component != null) - && (this.component.getParent() != null); - component = getComponent(); - - handle = open(component); - if (handle == 0) - { - throw new ResourceUnavailableException( - "Failed to open the native counterpart of JAWTRenderer"); - } - } - else - { - addNotify = false; - component = null; - } - } - /* - * The #addNotify() invocation, if any, should happen outside the - * synchronized block in order to avoid a deadlock. - */ - if (addNotify) - { - SwingUtilities.invokeLater( - new Runnable() - { - public void run() - { - component.addNotify(); - } - }); - } - } - - /** - * Opens a handle to a native counterpart of a JAWTRenderer which - * is to draw into a specific AWT Component. - * - * @param component the AWT Component into which a - * JAWTRenderer and the native counterpart to be opened are to - * draw. The platform-specific info of component is not guaranteed - * to be valid. - * @return a handle to a native counterpart of a JAWTRenderer which - * is to draw into the specified AWT Component - * @throws ResourceUnavailableException if there is a problem during opening - */ - static native long open(Component component) - throws ResourceUnavailableException; - - /** - * Paints a specific Component which is the AWT Component - * of a JAWTRenderer specified by the handle to its native - * counterpart. - * - * @param handle the handle to the native counterpart of a - * JAWTRenderer which is to draw into the specified AWT - * Component - * @param component the AWT Component into which the - * JAWTRenderer and its native counterpart specified by - * handle are to draw. The platform-specific info of - * component is guaranteed to be valid only during the execution of - * paint. - * @param g the Graphics context into which the drawing is to be - * performed - * @return true if the native counterpart of a - * JAWTRenderer wants to continue receiving the paint - * calls on the AWT Component; otherwise, false. For example, after - * the native counterpart has been able to acquire the native handle of the - * AWT Component, it may be able to determine when the native - * handle needs painting without waiting for AWT to call paint on - * the Component. In such a scenario, the native counterpart may - * indicate with false that it does not need further paint - * deliveries. - */ - static native boolean paint( - long handle, Component component, Graphics g); - - static native boolean paintLightweightComponent( - long handle, Component component, Graphics g); - - /** - * Processes the data provided in a specific Buffer and renders it - * to the output device represented by this Renderer. - * - * @param buffer a Buffer containing the data to be processed and - * rendered - * @return BUFFER_PROCESSED_OK if the processing is successful; - * otherwise, the other possible return codes defined in the PlugIn - * interface - */ - public synchronized int process(Buffer buffer) - { - if (buffer.isDiscard()) - return BUFFER_PROCESSED_OK; - - int bufferLength = buffer.getLength(); - - if (bufferLength == 0) - return BUFFER_PROCESSED_OK; - - Format bufferFormat = buffer.getFormat(); - - if ((bufferFormat != null) - && (bufferFormat != this.inputFormat) - && !bufferFormat.equals(this.inputFormat)) - { - if (setInputFormat(bufferFormat) == null) - return BUFFER_PROCESSED_FAILED; - } - - if (handle == 0) - return BUFFER_PROCESSED_FAILED; - else - { - Dimension size = null; - - if (bufferFormat != null) - size = ((VideoFormat) bufferFormat).getSize(); - if (size == null) - { - size = this.inputFormat.getSize(); - if (size == null) - return BUFFER_PROCESSED_FAILED; - } - - Component component = getComponent(); - boolean repaint = false; - - repaint - = process( - handle, - component, - (int[]) buffer.getData(), buffer.getOffset(), bufferLength, - size.width, size.height); - - if (repaint) - component.repaint(); - return BUFFER_PROCESSED_OK; - } - } - - /** - * Processes the data provided in a specific int array with a - * specific offset and length and renders it to the output device - * represented by a JAWTRenderer specified by the handle to it - * native counterpart. - * - * @param handle the handle to the native counterpart of a - * JAWTRenderer to process the specified data and render it - * @param component the AWT component into which the specified - * JAWTRenderer and its native counterpart draw - * @param data an int array which contains the data to be processed - * and rendered - * @param offset the index in data at which the data to be - * processed and rendered starts - * @param length the number of elements in data starting at - * offset which represent the data to be processed and rendered - * @param width the width of the video frame in data - * @param height the height of the video frame in data - * @return true if data has been successfully processed - */ - static native boolean process( - long handle, - Component component, - int[] data, int offset, int length, - int width, int height); - - static native void processLightweightComponentEvent( - long handle, - int x, int y, int width, int height); - - static native void removeNotifyLightweightComponent( - long handle, Component component); - - /** - * Sets the region in the component of this VideoRenderer where the - * video is to be rendered. - * - * @param bounds the region in the component of this VideoRenderer - * where the video is to be rendered; null if the entire component - * is to be used - */ - public void setBounds(Rectangle bounds) - { - // TODO Auto-generated method stub - } - - /** - * Sets the AWT Component into which this VideoRenderer is - * to draw. JAWTRenderer cannot draw into any other AWT - * Component but its own so it always returns false. - * - * @param component the AWT Component into which this - * VideoRenderer is to draw - * @return true if this VideoRenderer accepted the - * specified component as the AWT Component into which it - * is to draw; false, otherwise - */ - public boolean setComponent(Component component) - { - // We cannot draw into any other AWT Component but our own. - return false; - } - - /** - * Sets the Format of the input to be processed by this - * Renderer. - * - * @param format the Format to be set as the Format of the - * input to be processed by this Renderer - * @return the Format of the input to be processed by this - * Renderer if the specified format is supported or - * null if the specified format is not supported by this - * Renderer. Typically, it is the supported input Format - * which most closely matches the specified Format. - */ - @Override - public Format setInputFormat(Format format) - { - super.setInputFormat(format); - - /* - * Know the width and height of the input because we'll be depicting it - * and we may want, for example, to report it as the preferred size of - * our AWT Component. - */ - Dimension inputSize = inputFormat.getSize(); - - if (inputSize != null) - { - inputWidth = inputSize.width; - inputHeight = inputSize.height; - } - - /* - * Reflect the width and height of the input onto the preferredSize of - * our AWT Component (if necessary). - */ - if ((inputWidth > 0) && (inputHeight > 0)) - { - Component component = getComponent(); - Dimension preferredSize = component.getPreferredSize(); - - /* - * Apart from the simplest of cases in which the component has no - * preferredSize, it is also necessary to reflect the width and - * height of the input onto the preferredSize when the ratio of the - * input is different than the ratio of the preferredSize. - */ - if ((preferredSize == null) - || (preferredSize.width < 1) - || (preferredSize.height < 1) - || (preferredSize.width * inputHeight - != preferredSize.height * inputWidth)) - { - component.setPreferredSize( - new Dimension(inputWidth, inputHeight)); - } - - /* - * If the component does not have a size, it looks strange given - * that we know a preferredSize for it. - */ - Dimension size = component.getSize(); - - if ((size.width < 1) || (size.height < 1)) - { - preferredSize = component.getPreferredSize(); - component.setSize(preferredSize.width, preferredSize.height); - } - } - - return inputFormat; - } - - /** - * Starts the rendering process. Begins rendering any data available in the - * internal buffers of this Renderer. - */ - public void start() - { - } - - /** - * Stops the rendering process. - */ - public void stop() - { - } - - private static native String sysctlbyname(String name); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRendererSwingVideoComponent.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRendererSwingVideoComponent.java deleted file mode 100644 index fd2d74f3c..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRendererSwingVideoComponent.java +++ /dev/null @@ -1,908 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.video; - -import java.awt.*; -import java.awt.event.*; -import java.awt.image.*; -import java.util.*; -import java.util.List; // disambiguation - -import javax.media.*; -import javax.swing.*; - -import net.java.sip.communicator.util.*; -import net.java.sip.communicator.util.swing.*; - -/** - * Implements a Swing Component in which JAWTRenderer paints. - * - * @author Lyubomir Marinov - */ -public class JAWTRendererSwingVideoComponent - extends JPanel -{ - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * The Logger used by the JAWTRendererSwingVideoComponent - * class and its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(JAWTRendererSwingVideoComponent.class); - - /** - * The SwingVideoComponentCanvas in which this - * SwingVideoComponent is painted according to the last call to - * {@link #addNotify()}. - */ - private SwingVideoComponentCanvas canvas; - - /** - * The Container which is the last-known parent of this - * SwingVideoComponent. - */ - private Container parent; - - /** - * The ComponentListener which is to be or is listening to - * ComponentEvents fired by {@link #parent}. - */ - private final ComponentListener parentComponentListener - = new ComponentAdapter() - { - @Override - public void componentResized(ComponentEvent e) - { - /* - * It is necessary to call - * #procesLightweightComponentEvent() when the parent gets - * resized only if the native counterpart of this - * SwingVideoComponent expects bounds in a coordinate system - * which changes with respect to the bounds of this - * SwingVideoComponent when the parent gets resized. - */ - //processLightweightComponentEvent(); - } - }; - - /** - * The JAWTRenderer which paints in this - * JAWTRendererSwingVideoComponent. - */ - private final JAWTRenderer renderer; - - /** - * The indicator which determines whether the native counterpart of this - * JAWTRenderer wants paint calls on its Swing - * Component to be delivered. - * - * @see JAWTRendererVideoComponent#wantsPaint - */ - private boolean wantsPaint = true; - - /** - * Constructor. - * - * @param renderer JAWTRenderer instance - */ - public JAWTRendererSwingVideoComponent(JAWTRenderer renderer) - { - if (VideoContainer.DEFAULT_BACKGROUND_COLOR != null) - setBackground(VideoContainer.DEFAULT_BACKGROUND_COLOR); - - this.renderer = renderer; - } - - @Override - public void addNotify() - { - /* - * Since JAWTRenderer#open() may be performing the call, it may be - * wrong about this SwingVideoComponent having a parent. - */ - Container parent = getParent(); - - if (parent == null) - return; - - super.addNotify(); - - wantsPaint = true; - - synchronized (renderer.getHandleLock()) - { - long handle = renderer.getHandle(); - - if (handle != 0) - { - SwingVideoComponentCanvas canvas = findCanvas(); - - if (canvas == null) - { - JAWTRenderer.addNotifyLightweightComponent( - handle, this, - 0); - } - else - { - long canvasHandle; - - synchronized (canvas.getHandleLock()) - { - canvasHandle = canvas.getHandle(); - JAWTRenderer.addNotifyLightweightComponent( - handle, this, - canvasHandle); - } - if ((canvasHandle != 0) && (this.canvas != canvas)) - { - this.canvas = canvas; - } - } - - /* - * Emulate a ComponentEvent so that, for example, the native - * counterpart of this Component gets its bounds up to date. - */ - processLightweightComponentEvent(); - } - } - - if (this.parent != parent) - { - this.parent = parent; - this.parent.addComponentListener(parentComponentListener); - } - } - - /** - * Creates a new AWT Component in which - * SwingVideoComponents can be rendered. - * @return new AWT Component in which SwingVideoComponents - * can be rendered - */ - public Component createCanvas() - { - return new SwingVideoComponentCanvas(renderer); - } - - /** - * Finds a SwingVideoComponentCanvas in which this - * SwingVideoComponent can be painted. - * - * @return a SwingVideoComponentCanvas in which this - * SwingVideoComponent can be painted if any; otherwise, - * null - */ - private SwingVideoComponentCanvas findCanvas() - { - Container parent = getParent(); - - if (parent != null) - for (Component component : parent.getComponents()) - if (component instanceof SwingVideoComponentCanvas) - return (SwingVideoComponentCanvas) component; - return null; - } - - /** - * Gets the SwingVideoComponentCanvas in which this - * SwingVideoComponent is being painted. - * - * @return the SwingVideoComponentCanvas in which this - * SwingVideoComponent is being painted if any; otherwise, - * null - */ - SwingVideoComponentCanvas getCanvas() - { - return canvas; - } - - @Override - public void paint(Graphics g) - { - synchronized (renderer.getHandleLock()) - { - long handle = renderer.getHandle(); - - if (wantsPaint && (handle != 0)) - { - wantsPaint - = JAWTRenderer.paintLightweightComponent( - handle, - this, - g); - } - } - } - - @Override - protected void processComponentEvent(ComponentEvent e) - { - super.processComponentEvent(e); - - if (equals(e.getComponent())) - { - switch(e.getID()) - { - case ComponentEvent.COMPONENT_MOVED: - case ComponentEvent.COMPONENT_RESIZED: - processLightweightComponentEvent(); - break; - } - } - } - - /** - * Notifies this SwingVideoComponent that a - * ComponentEvent related to it has occurred. - */ - private void processLightweightComponentEvent() - { - Rectangle bounds = getBounds(); - - if (bounds != null) - { - synchronized (renderer.getHandleLock()) - { - long handle = renderer.getHandle(); - - if (handle != 0) - { - JAWTRenderer.processLightweightComponentEvent( - handle, - bounds.x, - bounds.y, - bounds.width, - bounds.height); - } - } - } - } - - @Override - public void removeNotify() - { - if (parent != null) - { - parent.removeComponentListener(parentComponentListener); - parent = null; - } - - synchronized (renderer.getHandleLock()) - { - long handle = renderer.getHandle(); - - if (handle != 0) - { - if (canvas != null) - { - synchronized (canvas.getHandleLock()) - { - JAWTRenderer.removeNotifyLightweightComponent( - handle, this); - } - canvas = null; - } - else - { - JAWTRenderer.removeNotifyLightweightComponent( - handle, this); - } - } - } - - /* - * In case the associated JAWTRenderer has said that it does not - * want paint events/notifications, ask it again next time because - * the native handle of this Canvas may be recreated. - */ - wantsPaint = true; - - super.removeNotify(); - } - - @Override - public void repaint() - { - super.repaint(); - - /* - * Since SwingVideoComponent is to be painted in a - * SwingVideoComponentCanvas, the latter should repaint when the - * former does. - */ - Component canvas = getCanvas(); - - if (canvas != null) - canvas.repaint(); - } - - @Override - public void setBounds(int x, int y, int width, int height) - { - super.setBounds(x, y, width, height); - - /* - * Calling #setBounds(int, int, int, int) does not seem to cause - * this SwingVideoComponent to process a ComponentEvent so force it - * because it is really necessary to deliver the up-to-date bounds - * to the native counterpart. - */ - processLightweightComponentEvent(); - } - - @Override - public void setLocation(int x, int y) - { - super.setLocation(x, y); - - processLightweightComponentEvent(); - } - - /** - * Represents a Component which is neither a - * AWTVideoComponent nor a SwingVideoComponent but which - * is to be painted by a SwingVideoComponentCanvas anyway. - */ - private static class NonVideoComponent - { - /** - * The BufferedImage into which {@link #component} is to be - * painted so that it can be processed and then rendered by - * {@link #handle}. - */ - private BufferedImage bufferedImage; - - /** - * The Component represented by this NonVideoComponent - * instance. - */ - public final Component component; - - /** - * The handle of the native JAWTRenderer which paints this - * NonVideoComponent. - */ - private long handle; - - /** - * The height in pixels of {@link #bufferedImage} and {@link #rgb}. - */ - private int height; - - /** - * The pixels of {@link #bufferedImage} to be processed by - * {@link #handle}. - */ - private int[] rgb; - - /** - * The width in pixels of {@link #bufferedImage} and {@link #rgb}. - */ - private int width; - - /** - * Initializes a new NonVideoComponent instance which is to - * paint a specific Component in the context of a parent - * JAWTRenderer. - * - * @param component the Component to be painted - * @param parentHandle the handle of the native JAWTRenderer in - * the context of which component is to be painted - */ - public NonVideoComponent(Component component, long parentHandle) - { - this.component = component; - - try - { - handle = JAWTRenderer.open(this.component); - if (handle != 0) - { - JAWTRenderer.addNotifyLightweightComponent( - handle, this.component, - parentHandle); - } - } - catch (ResourceUnavailableException rue) - { - logger.error( - "Failed to JAWTRenderer.open for NonVideoComponent", - rue); - } - } - - /** - * Releases the resources of this NonVideoComponent and - * prepares it to be garbage collected. - */ - public void dispose() - { - if (handle != 0) - { - JAWTRenderer.removeNotifyLightweightComponent( - handle, component); - JAWTRenderer.close(handle, component); - handle = 0; - } - } - - /** - * Paints the Component associated with this - * NonVideoComponent instance. - */ - public void paint() - { - if (handle != 0) - { - /* - * Make sure the location, the size and the visibility known to - * the associated native JAWTRenderer are in sync with these of - * the component. - */ - Rectangle bounds = component.getBounds(); - - if (!component.isVisible()) - { - bounds.height = 0; - bounds.width = 0; - } - JAWTRenderer.processLightweightComponentEvent( - handle, - bounds.x, bounds.y, bounds.width, bounds.height); - - /* - * If the component is not visible, the native JAWTRenderer - * already knows that it is not to be rendered. - */ - if ((bounds.height < 1) || (bounds.width < 1)) - return; - - /* - * Paint the component and tell the native JAWTRenderer about - * the latest painting. - */ - if ((height != bounds.height) || (width != bounds.width)) - { - rgb = new int[bounds.width * bounds.height]; - bufferedImage - = new BufferedImage( - bounds.width, bounds.height, - BufferedImage.TYPE_INT_ARGB); - height = bounds.height; - width = bounds.width; - } - if ((bufferedImage != null) && (rgb != null)) - { - Graphics g = bufferedImage.createGraphics(); - boolean process = false; - - try - { - component.paint(g); - process = true; - } - finally - { - g.dispose(); - } - if (process) - { - bufferedImage.getRGB( - 0, 0, width, height, - rgb, 0, width); - JAWTRenderer.process( - handle, component, - rgb, 0, rgb.length, - width, height); - } - } - } - } - } - - /** - * Implements an AWT Component in which - * SwingVideoComponents can be rendered. - */ - private static class SwingVideoComponentCanvas - extends JAWTRendererVideoComponent - { - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * The handle to the native JAWTRenderer which does the actual - * painting of this SwingVideoComponentCanvas. - */ - private long handle; - - /** - * The Component to which this - * SwingVideoComponentCanvas has dispatched a - * {@link MouseEvent#MOUSE_PRESSED}. - */ - private Component mousePressedComponent; - - /** - * The NoVideoComponents painted by this - * SwingVideoComponentCanvas. - */ - private final List nonVideoComponents - = new LinkedList(); - - /** - * The Container which is the last-known parent of this - * SwingVideoComponentCanvas. - */ - private Container parent; - - /** - * The ContainerListener which listens to {@link #parent}. - */ - private final ContainerListener parentContainerListener - = new ContainerListener() - { - public void componentAdded(ContainerEvent e) - { - Component c = e.getChild(); - - if (!(c instanceof JAWTRendererVideoComponent) - && !(c instanceof JAWTRendererSwingVideoComponent)) - { - nonVideoComponentAdded(c); - } - } - - public void componentRemoved(ContainerEvent e) - { - Component c = e.getChild(); - - if (mousePressedComponent == c) - mousePressedComponent = null; - - if (!(c instanceof JAWTRendererVideoComponent) - && !(c instanceof JAWTRendererSwingVideoComponent)) - { - nonVideoComponentRemoved(c); - } - else if (SwingVideoComponentCanvas.this.equals(c)) - removeAllNonVideoComponents(); - } - }; - - /** - * Initializes a new SwingVideoComponentCanvas instance. - * - * @param renderer - */ - public SwingVideoComponentCanvas(JAWTRenderer renderer) - { - super(renderer); - - enableEvents( - AWTEvent.MOUSE_EVENT_MASK - | AWTEvent.MOUSE_MOTION_EVENT_MASK); - } - - @Override - public void addNotify() - { - super.addNotify(); - - synchronized (getHandleLock()) - { - if (getHandle() == 0) - { - try - { - this.handle = JAWTRenderer.open(this); - } - catch (ResourceUnavailableException rue) - { - throw new RuntimeException(rue); - } - if (getHandle() == 0) - { - throw new RuntimeException( - "JAWTRenderer#open(Component)"); - } - } - } - - Container parent = getParent(); - - if ((parent != null) && (this.parent != parent)) - { - this.parent = parent; - this.parent.addContainerListener(parentContainerListener); - } - } - - @Override - public boolean contains(int x, int y) - { - /* - * Act as a "glass pane" i.e. be transparent with respect to points - * and pretend they are in whatever is underneath. - */ - return false; - } - - /** - * Dispatches MouseEvents to whatever is underneath this - * SwingVideoComponentCanvas because it only renders - * Components i.e. it is like a "glass pane". - */ - private boolean dispatchMouseEvent(MouseEvent e) - { - Component srcc = e.getComponent(); - - if (srcc != null) - { - int id = e.getID(); - Component dstc = null; - - /* - * After a MOUSE_PRESSED, this SwingVideoComponentCanvas will - * continue to receive, for example, MouseMotionEvents even - * when the point has moved out of it. Emulate the same behavior - * for the Components this SwingVideoComponentCanvas dispatches - * events to since it is transparent in this respect. - */ - if (MouseEvent.MOUSE_PRESSED == id) - mousePressedComponent = null; - else if (mousePressedComponent != null) - { - dstc = mousePressedComponent; - if ((MouseEvent.MOUSE_CLICKED == id) - || (MouseEvent.MOUSE_RELEASED == id)) - mousePressedComponent = null; - } - - if (dstc == null) - { - Container parent = getParent(); - - if (parent != null) - { - Point parentPoint - = SwingUtilities.convertPoint( - srcc, - e.getPoint(), - parent); - - dstc = getComponentAt(parent, parentPoint); - } - } - - if (dstc != null) - { - if (MouseEvent.MOUSE_PRESSED == id) - mousePressedComponent = dstc; - dstc.dispatchEvent( - SwingUtilities.convertMouseEvent( - srcc, - e, - dstc)); - return true; - } - } - return false; - } - - /** - * Determines the Component which is a child of a specific - * Container which contains a specific Point. Since - * SwingVideoComponentCanvas is like a "glass pane", it never - * contains the specified point. - * - * @param parent the Container which contains the - * Components which may contain the specified point - * @param point the point in the coordinate system of parent - * which is to be determined which Component contains it - * @return the Component which is a child of the specified - * Container and contains the specified Point or - * null if there is no such Component - */ - private Component getComponentAt(Container parent, Point point) - { - Component[] components = parent.getComponents(); - - for (int componentIndex = components.length - 1; - componentIndex >= 0; - componentIndex--) - { - Component component = components[componentIndex]; - - if (!equals(component) - && component.isVisible() - && component.contains( - SwingUtilities.convertPoint( - parent, - point, - component))) - { - return component; - } - } - return null; - } - - /* Overrides JAWTRendererVideoComponent#getHandle(). */ - @Override - protected long getHandle() - { - return handle; - } - - /* Overrides JAWTRendererVideoComponent#getHandleLock(). */ - @Override - protected Object getHandleLock() - { - return this; - } - - /** - * Notifies this SwingVideoComponentCanvas that a - * Component which is neither an AWTVideoComponent nor - * a SwingVideoComponent has been added to {@link #parent}. - * - * @param c the component which has been added - */ - private void nonVideoComponentAdded(Component c) - { - synchronized (getHandleLock()) - { - synchronized (nonVideoComponents) - { - for (NonVideoComponent nonVideoComponent - : nonVideoComponents) - { - if (nonVideoComponent.component.equals(c)) - return; - } - - nonVideoComponents.add( - new NonVideoComponent(c, getHandle())); - } - } - } - - /** - * Notifies this SwingVideoComponentCanvas that a - * Component which is neither an AWTVideoComponent nor - * a SwingVideoComponent has been removed from {@link #parent}. - * - * @param c the component which has been removed - */ - private void nonVideoComponentRemoved(Component c) - { - synchronized (nonVideoComponents) - { - Iterator nonVideoComponentIter - = nonVideoComponents.iterator(); - - while (nonVideoComponentIter.hasNext()) - { - NonVideoComponent nonVideoComponent - = nonVideoComponentIter.next(); - - if (nonVideoComponent.component.equals(c)) - { - nonVideoComponentIter.remove(); - nonVideoComponent.dispose(); - break; - } - } - } - } - - @Override - public void paint(Graphics g) - { - try - { - synchronized (nonVideoComponents) - { - for (NonVideoComponent nonVideoComponent - : nonVideoComponents) - nonVideoComponent.paint(); - } - } - finally - { - super.paint(g); - } - } - - @Override - protected void processMouseEvent(MouseEvent e) - { - /* - * Act as a "glass pane" i.e. be transparent with respect to - * MouseEvents and dispatch them to whatever is underneath. - */ - if (!dispatchMouseEvent(e)) - super.processMouseEvent(e); - } - - @Override - protected void processMouseMotionEvent(MouseEvent e) - { - /* - * Act as a "glass pane" i.e. be transparent with respect to - * MouseEvents and dispatch them to whatever is underneath. - */ - if (!dispatchMouseEvent(e)) - super.processMouseMotionEvent(e); - } - - /** - * Removes all NonVideoComponents from this - * SwingVideoComponentCanvas so that their associated - * Components are no longer painted by the represented native - * JAWTRenderer. - */ - private void removeAllNonVideoComponents() - { - synchronized (nonVideoComponents) - { - Iterator nonVideoComponentIter - = nonVideoComponents.iterator(); - - while (nonVideoComponentIter.hasNext()) - { - NonVideoComponent nonVideoComponent - = nonVideoComponentIter.next(); - - nonVideoComponentIter.remove(); - nonVideoComponent.dispose(); - } - } - } - - @Override - public void removeNotify() - { - mousePressedComponent = null; - - if (parent != null) - { - parent.removeContainerListener(parentContainerListener); - removeAllNonVideoComponents(); - parent = null; - } - - synchronized (getHandleLock()) - { - long handle = getHandle(); - - if (handle != 0) - { - try - { - JAWTRenderer.close(handle, this); - } - finally - { - this.handle = 0; - } - } - } - - super.removeNotify(); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRendererVideoComponent.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRendererVideoComponent.java deleted file mode 100644 index 61841946f..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRendererVideoComponent.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.video; - -import java.awt.*; - -import net.java.sip.communicator.util.swing.*; - -/** - * Implements an AWT Component in which JAWTRenderer paints. - * - * @author Lyubomir Marinov - */ -public class JAWTRendererVideoComponent - extends Canvas -{ - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * The JAWTRenderer which paints in this - * JAWTRendererVideoComponent. - */ - protected final JAWTRenderer renderer; - - /** - * The indicator which determines whether the native counterpart of this - * JAWTRenderer wants paint calls on its AWT - * Component to be delivered. For example, after the native - * counterpart has been able to acquire the native handle of the AWT - * Component, it may be able to determine when the native - * handle needs painting without waiting for AWT to call paint - * on the Component. In such a scenario, the native counterpart - * may indicate with false that it does not need further - * paint deliveries. - */ - private boolean wantsPaint = true; - - /** - * Initializes a new JAWTRendererVideoComponent instance. - * - * @param renderer - */ - public JAWTRendererVideoComponent(JAWTRenderer renderer) - { - if (VideoContainer.DEFAULT_BACKGROUND_COLOR != null) - setBackground(VideoContainer.DEFAULT_BACKGROUND_COLOR); - - this.renderer = renderer; - } - - @Override - public void addNotify() - { - super.addNotify(); - - wantsPaint = true; - } - - /** - * Gets the handle of the native counterpart of the - * JAWTRenderer which paints in this - * AWTVideoComponent. - * - * @return the handle of the native counterpart of the - * JAWTRenderer which paints in this AWTVideoComponent - */ - protected long getHandle() - { - return renderer.getHandle(); - } - - /** - * Gets the synchronization lock which protects the access to the - * handle property of this AWTVideoComponent. - * - * @return the synchronization lock which protects the access to the - * handle property of this AWTVideoComponent - */ - protected Object getHandleLock() - { - return renderer.getHandleLock(); - } - - @Override - public void paint(Graphics g) - { - if (wantsPaint) - { - synchronized (getHandleLock()) - { - long handle; - - if ((handle = getHandle()) != 0) - wantsPaint = JAWTRenderer.paint(handle, this, g); - } - } - } - - @Override - public void removeNotify() - { - /* - * In case the associated JAWTRenderer has said that it does not - * want paint events/notifications, ask it again next time because - * the native handle of this Canvas may be recreated. - */ - wantsPaint = true; - - super.removeNotify(); - } - - @Override - public void update(Graphics g) - { - synchronized (getHandleLock()) - { - if (!wantsPaint || (getHandle() == 0)) - { - super.update(g); - return; - } - } - - /* - * Skip the filling with the background color because it causes - * flickering. - */ - paint(g); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/neomedia.manifest.mf b/src/net/java/sip/communicator/impl/neomedia/neomedia.manifest.mf index 061e16e0d..a7979b859 100644 --- a/src/net/java/sip/communicator/impl/neomedia/neomedia.manifest.mf +++ b/src/net/java/sip/communicator/impl/neomedia/neomedia.manifest.mf @@ -4,18 +4,16 @@ Bundle-Description: A bundle that offers Media capture and presentation capabili Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes -Import-Package: org.bouncycastle.crypto, - org.bouncycastle.crypto.digests, - org.bouncycastle.crypto.engines, - org.bouncycastle.crypto.macs, - org.bouncycastle.crypto.params, - org.bouncycastle.crypto.prng, - org.ice4j.socket, - org.json, - org.osgi.framework, - org.w3c.dom, - org.xml.sax, +Import-Package: apple.awt, + ch.imvs.sdes4j, + ch.imvs.sdes4j.srtp, + gnu.java.zrtp, + gnu.java.zrtp.packets, + gnu.java.zrtp.utils, + gnu.java.zrtp.zidfile, javax.imageio, + javax.media, + javax.media.protocol, javax.sound.sampled, javax.swing, javax.swing.border, @@ -26,33 +24,45 @@ Import-Package: org.bouncycastle.crypto, javax.xml.transform, javax.xml.transform.dom, javax.xml.transform.stream, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.fileaccess, net.java.sip.communicator.service.gui, - net.java.sip.communicator.service.packetlogging, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.resources, - net.java.sip.communicator.service.version, net.java.sip.communicator.util, net.java.sip.communicator.util.event, net.java.sip.communicator.util.swing, + org.bouncycastle.crypto, + org.bouncycastle.crypto.digests, + org.bouncycastle.crypto.engines, + org.bouncycastle.crypto.macs, + org.bouncycastle.crypto.params, + org.bouncycastle.crypto.prng, + org.ice4j.socket, + org.jitsi.impl.neomedia, + org.jitsi.impl.neomedia.codec, + org.jitsi.impl.neomedia.codec.video.h264, + org.jitsi.impl.neomedia.device, + org.jitsi.impl.neomedia.format, + org.jitsi.service.audionotifier, + org.jitsi.service.configuration, + org.jitsi.service.fileaccess, + org.jitsi.service.libjitsi, + org.jitsi.service.neomedia, + org.jitsi.service.neomedia.control, + org.jitsi.service.neomedia.device, + org.jitsi.service.neomedia.event, + org.jitsi.service.neomedia.format, + org.jitsi.service.packetlogging, + org.jitsi.service.resources, + org.jitsi.service.version, + org.jitsi.util, + org.jitsi.util.swing, + org.json, + org.osgi.framework, + org.w3c.dom, + org.xml.sax, quicktime, quicktime.qd, quicktime.std.image, quicktime.std.sg, - quicktime.util, - gnu.java.zrtp, - gnu.java.zrtp.packets, - gnu.java.zrtp.utils, - gnu.java.zrtp.zidfile, - apple.awt, - ch.imvs.sdes4j, - ch.imvs.sdes4j.srtp -Export-Package: net.java.sip.communicator.service.audionotifier, - net.java.sip.communicator.service.neomedia, - net.java.sip.communicator.service.neomedia.control, - net.java.sip.communicator.service.neomedia.device, - net.java.sip.communicator.service.neomedia.event, - net.java.sip.communicator.service.neomedia.format, - net.java.sip.communicator.service.neomedia.imgstreaming + quicktime.util diff --git a/src/net/java/sip/communicator/impl/neomedia/notify/AudioNotifierServiceImpl.java b/src/net/java/sip/communicator/impl/neomedia/notify/AudioNotifierServiceImpl.java deleted file mode 100644 index f2c1f6a1a..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/notify/AudioNotifierServiceImpl.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.notify; - -import java.beans.*; -import java.net.*; -import java.util.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.device.*; -import net.java.sip.communicator.service.audionotifier.*; -import net.java.sip.communicator.service.resources.*; - -/** - * The implementation of the AudioNotifierService. - * - * @author Yana Stamcheva - */ -public class AudioNotifierServiceImpl - implements AudioNotifierService, - PropertyChangeListener -{ - /** - * Map of differents audio clips. - */ - private static final Map audioClips = - new HashMap(); - - /** - * If the sound is currently disabled. - */ - private boolean isMute; - - /** - * Device config to look for notify device. - */ - private final DeviceConfiguration deviceConfiguration; - - /** - * Creates audio notify service. - * @param deviceConfiguration the device configuration. - */ - public AudioNotifierServiceImpl(DeviceConfiguration deviceConfiguration) - { - this.deviceConfiguration = deviceConfiguration; - - deviceConfiguration.addPropertyChangeListener(this); - } - - /** - * Creates an SCAudioClip from the given URI and adds it to the list of - * available audio-s. - * - * @param uri the path where the audio file could be found - * @return a newly created SCAudioClip from uri - */ - public SCAudioClipImpl createAudio(String uri) - { - SCAudioClipImpl audioClip; - - synchronized (audioClips) - { - if(audioClips.containsKey(uri)) - { - audioClip = audioClips.get(uri); - } - else - { - ResourceManagementService resources - = NeomediaActivator.getResources(); - URL url - = (resources == null) - ? null - : resources.getSoundURLForPath(uri); - - if (url == null) - { - // Not found by the class loader. Perhaps it's a local file. - try - { - url = new URL(uri); - } - catch (MalformedURLException e) - { - //logger.error("The given uri could not be parsed.", e); - return null; - } - } - - try - { - AudioSystem audioSystem - = getDeviceConfiguration().getAudioSystem(); - - if (audioSystem == null) - audioClip = new JavaSoundClipImpl(url, this); - else if (NoneAudioSystem.LOCATOR_PROTOCOL.equalsIgnoreCase( - audioSystem.getLocatorProtocol())) - audioClip = null; - else - { - audioClip - = new AudioSystemClipImpl(url, this, audioSystem); - } - } - catch (Throwable t) - { - if (t instanceof ThreadDeath) - throw (ThreadDeath) t; - // Cannot create audio to play - return null; - } - - audioClips.put(uri, audioClip); - } - } - - return audioClip; - } - - /** - * Removes the given audio from the list of available audio clips. - * - * @param audioClip the audio to destroy - */ - public void destroyAudio(SCAudioClip audioClip) - { - synchronized (audioClips) - { - audioClips.remove(audioClip); - } - } - - /** - * Enables or disables the sound in the application. If FALSE, we try to - * restore all looping sounds if any. - * - * @param isMute when TRUE disables the sound, otherwise enables the sound. - */ - public void setMute(boolean isMute) - { - this.isMute = isMute; - - for (SCAudioClipImpl audioClip : audioClips.values()) - { - if (isMute) - { - audioClip.internalStop(); - } - else if (audioClip.isLooping()) - { - audioClip.playInLoop(audioClip.getLoopInterval()); - } - } - } - - /** - * Returns TRUE if the sound is currently disabled, FALSE otherwise. - * @return TRUE if the sound is currently disabled, FALSE otherwise - */ - public boolean isMute() - { - return isMute; - } - - /** - * The device configuration. - * - * @return the deviceConfiguration - */ - public DeviceConfiguration getDeviceConfiguration() - { - return deviceConfiguration; - } - - /** - * Listens for changes in notify device - * @param event the event that notify device has changed. - */ - public void propertyChange(PropertyChangeEvent event) - { - if (DeviceConfiguration.AUDIO_NOTIFY_DEVICE.equals( - event.getPropertyName())) - { - audioClips.clear(); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/notify/AudioSystemClipImpl.java b/src/net/java/sip/communicator/impl/neomedia/notify/AudioSystemClipImpl.java deleted file mode 100644 index e0fbabee0..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/notify/AudioSystemClipImpl.java +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.notify; - -import java.io.*; -import java.net.*; - -import javax.media.*; -import javax.sound.sampled.*; - -import net.java.sip.communicator.impl.neomedia.codec.audio.speex.*; -import net.java.sip.communicator.util.*; - -/** - * Implementation of SCAudioClip using PortAudio. - * - * @author Damyian Minkov - * @author Lubomir Marinov - */ -public class AudioSystemClipImpl - extends SCAudioClipImpl -{ - /** - * The Logger used by the AudioSystemClipImpl class and - * its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(AudioSystemClipImpl.class); - - private final AudioNotifierServiceImpl audioNotifier; - - private final net.java.sip.communicator.impl.neomedia.device.AudioSystem - audioSystem; - - private boolean started = false; - - private final Object syncObject = new Object(); - - private final URL url; - - /** - * Creates the audio clip and initializes the listener used from the - * loop timer. - * - * @param url the URL pointing to the audio file - * @param audioNotifier the audio notify service - * @throws IOException cannot audio clip with supplied URL. - */ - public AudioSystemClipImpl( - URL url, - AudioNotifierServiceImpl audioNotifier, - net.java.sip.communicator.impl.neomedia.device.AudioSystem - audioSystem) - throws IOException - { - this.url = url; - this.audioNotifier = audioNotifier; - this.audioSystem = audioSystem; - } - - /** - * Plays this audio. - */ - public void play() - { - if ((url != null) && !audioNotifier.isMute()) - { - started = true; - new Thread() - { - @Override - public void run() - { - runInPlayThread(); - } - }.start(); - } - } - - /** - * Plays this audio in loop. - * - * @param interval the loop interval - */ - public void playInLoop(int interval) - { - setLoopInterval(interval); - setIsLooping(true); - - play(); - } - - /** - * Stops this audio. - */ - public void stop() - { - internalStop(); - setIsLooping(false); - } - - /** - * Stops this audio without setting the isLooping property in the case of - * a looping audio. The AudioNotifier uses this method to stop the audio - * when setMute(true) is invoked. This allows us to restore all looping - * audios when the sound is restored by calling setMute(false). - */ - public void internalStop() - { - synchronized (syncObject) - { - if (url != null && started) - { - started = false; - syncObject.notifyAll(); - } - } - } - - /** - * Runs in a separate thread to perform the actual playback of the audio - * stream pointed to by {@link #url} looping as necessary. - */ - private void runInPlayThread() - { - Buffer buffer = new Buffer(); - byte[] bufferData = new byte[1024]; - // don't enable volume control for notifications - Renderer renderer = audioSystem.createRenderer(false); - - buffer.setData(bufferData); - while (started) - { - try - { - if (!runOnceInPlayThread(renderer, buffer, bufferData)) - break; - } - finally - { - try - { - renderer.stop(); - } - finally - { - renderer.close(); - } - } - - if(isLooping()) - { - synchronized(syncObject) - { - if (started) - { - try - { - syncObject.wait(getLoopInterval()); - } - catch (InterruptedException e) - { - } - } - } - } - else - break; - } - } - - /** - * Runs in a separate thread to perform the actual playback of the audio - * stream pointed to by {@link #url} once using a specific - * PortAudioRenderer and giving it the audio data for processing - * through a specific JMF Buffer. - * - * @param renderer the PortAudioRenderer which is to render the - * audio data read from the audio stream pointed to by {@link #url} - * @param buffer the JMF Buffer through which the audio data to be - * rendered is to be given to renderer - * @param bufferData the value of the data property of - * buffer explicitly specified for performance reasons so that it - * doesn't have to be read and cast during every iteration of the playback - * loop - * @return true if the playback was successful and it is to be - * carried out again in accord with the looping property value of - * this SCAudioClipImpl; otherwise, false - */ - private boolean runOnceInPlayThread( - Renderer renderer, - Buffer buffer, - byte[] bufferData) - { - AudioInputStream audioStream = null; - - try - { - audioStream = AudioSystem.getAudioInputStream(url); - } - catch (IOException ioex) - { - logger.error("Failed to get audio stream " + url, ioex); - } - catch (UnsupportedAudioFileException uafex) - { - logger.error("Unsupported format of audio stream " + url, uafex); - } - if (audioStream == null) - return false; - - Codec resampler = null; - - try - { - AudioFormat audioStreamFormat = audioStream.getFormat(); - Format rendererFormat - = new javax.media.format.AudioFormat( - javax.media.format.AudioFormat.LINEAR, - audioStreamFormat.getSampleRate(), - audioStreamFormat.getSampleSizeInBits(), - audioStreamFormat.getChannels()); - Format resamplerFormat = null; - - if (renderer.setInputFormat(rendererFormat) == null) - { - /* - * Try to negotiate a resampling of the audioStreamFormat to one - * of the formats supported by the renderer. - */ - resampler = new SpeexResampler(); - resamplerFormat = rendererFormat; - resampler.setInputFormat(resamplerFormat); - - Format[] supportedResamplerFormats - = resampler.getSupportedOutputFormats(resamplerFormat); - - for (Format supportedRendererFormat - : renderer.getSupportedInputFormats()) - { - for (Format supportedResamplerFormat - : supportedResamplerFormats) - { - if (supportedRendererFormat.matches( - supportedResamplerFormat)) - { - rendererFormat = supportedRendererFormat; - resampler.setOutputFormat(rendererFormat); - renderer.setInputFormat(rendererFormat); - break; - } - } - } - } - - Buffer rendererBuffer = buffer; - Buffer resamplerBuffer; - - rendererBuffer.setFormat(rendererFormat); - if (resampler == null) - resamplerBuffer = null; - else - { - resamplerBuffer = new Buffer(); - bufferData = new byte[bufferData.length]; - resamplerBuffer.setData(bufferData); - resamplerBuffer.setFormat(resamplerFormat); - - resampler.open(); - } - - try - { - renderer.open(); - renderer.start(); - - int bufferLength; - - while(started - && ((bufferLength = audioStream.read(bufferData)) - != -1)) - { - if (resampler == null) - { - rendererBuffer.setLength(bufferLength); - rendererBuffer.setOffset(0); - } - else - { - resamplerBuffer.setLength(bufferLength); - resamplerBuffer.setOffset(0); - rendererBuffer.setLength(0); - rendererBuffer.setOffset(0); - resampler.process(resamplerBuffer, rendererBuffer); - } - while ((renderer.process(rendererBuffer) - & Renderer.INPUT_BUFFER_NOT_CONSUMED) - == Renderer.INPUT_BUFFER_NOT_CONSUMED); - } - } - catch (IOException ioex) - { - logger.error("Failed to read from audio stream " + url, ioex); - return false; - } - catch (ResourceUnavailableException ruex) - { - logger.error("Failed to open PortAudioRenderer.", ruex); - return false; - } - } - catch (ResourceUnavailableException ruex) - { - if (resampler != null) - { - logger.error("Failed to open SpeexResampler.", ruex); - return false; - } - } - finally - { - try - { - audioStream.close(); - } - catch (IOException ioex) - { - /* - * The audio stream failed to close but it doesn't mean the URL - * will fail to open again so ignore the exception. - */ - } - - if (resampler != null) - resampler.close(); - } - return true; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/notify/JavaSoundClipImpl.java b/src/net/java/sip/communicator/impl/neomedia/notify/JavaSoundClipImpl.java deleted file mode 100644 index 3fcd93553..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/notify/JavaSoundClipImpl.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.notify; - -import java.applet.*; -import java.awt.event.*; -import java.io.*; -import java.lang.reflect.*; -import java.net.*; -import java.security.*; - -import javax.swing.*; - -import net.java.sip.communicator.service.audionotifier.*; - -/** - * Implementation of SCAudioClip. - * - * @author Yana Stamcheva - */ -public class JavaSoundClipImpl - extends SCAudioClipImpl - implements ActionListener - -{ - private static Constructor acConstructor = null; - - private final Timer playAudioTimer = new Timer(1000, null); - - private final AudioClip audioClip; - - private final AudioNotifierService audioNotifier; - - /** - * Creates the audio clip and initialize the listener used from the - * loop timer. - * - * @param url the url pointing to the audio file - * @param audioNotifier the audio notify service - * @throws IOException cannot audio clip with supplied url. - */ - public JavaSoundClipImpl(URL url, AudioNotifierService audioNotifier) - throws IOException - { - this.audioClip = createAppletAudioClip(url.openStream()); - this.audioNotifier = audioNotifier; - - this.playAudioTimer.addActionListener(this); - } - - /** - * Plays this audio. - */ - public void play() - { - if ((audioClip != null) && !audioNotifier.isMute()) - audioClip.play(); - } - - /** - * Plays this audio in loop. - * - * @param interval the loop interval - */ - public void playInLoop(int interval) - { - if(!audioNotifier.isMute()) - { - if(interval == 0) - audioClip.loop(); - else - { - //first play the audio and then start the timer and wait - audioClip.play(); - playAudioTimer.setDelay(interval); - playAudioTimer.setRepeats(true); - - playAudioTimer.start(); - } - } - - setLoopInterval(interval); - setIsLooping(true); - } - - /** - * Stops this audio. - */ - public void stop() - { - if (audioClip != null) - audioClip.stop(); - - if (isLooping()) - { - playAudioTimer.stop(); - setIsLooping(false); - } - } - - /** - * Stops this audio without setting the isLooping property in the case of - * a looping audio. The AudioNotifier uses this method to stop the audio - * when setMute(true) is invoked. This allows us to restore all looping - * audios when the sound is restored by calling setMute(false). - */ - public void internalStop() - { - if (audioClip != null) - audioClip.stop(); - - if (isLooping()) - playAudioTimer.stop(); - } - - /** - * Creates an AppletAudioClip. - * - * @param inputstream the audio input stream - * @throws IOException - */ - private static AudioClip createAppletAudioClip(InputStream inputstream) - throws IOException - { - if (acConstructor == null) - { - try - { - acConstructor - = AccessController.doPrivileged( - new PrivilegedExceptionAction>() - { - public Constructor run() - throws ClassNotFoundException, - NoSuchMethodException, - SecurityException - { - return createAcConstructor(); - } - }); - } - catch (PrivilegedActionException paex) - { - throw - new IOException( - "Failed to get AudioClip constructor: " - + paex.getException()); - } - } - - try - { - return acConstructor.newInstance(inputstream); - } - catch (Exception ex) - { - throw new IOException("Failed to construct the AudioClip: " + ex); - } - } - - @SuppressWarnings("unchecked") - private static Constructor createAcConstructor() - throws ClassNotFoundException, - NoSuchMethodException, - SecurityException - { - Class class1; - try - { - class1 - = Class.forName( - "com.sun.media.sound.JavaSoundAudioClip", - true, - ClassLoader.getSystemClassLoader()); - } - catch (ClassNotFoundException cnfex) - { - class1 - = Class.forName("sun.audio.SunAudioClip", true, null); - } - return - (Constructor) class1.getConstructor(InputStream.class); - } - - /** - * Plays an audio clip. Used in the playAudioTimer to play an audio in loop. - * @param e the event. - */ - public void actionPerformed(ActionEvent e) - { - if (audioClip != null) - { - audioClip.stop(); - audioClip.play(); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/notify/SCAudioClipImpl.java b/src/net/java/sip/communicator/impl/neomedia/notify/SCAudioClipImpl.java deleted file mode 100644 index f13d909cc..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/notify/SCAudioClipImpl.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.notify; - -import net.java.sip.communicator.service.audionotifier.*; - -/** - * Common properties impl for SCAudioClip. - * - * @author Damian Minkov - */ -public abstract class SCAudioClipImpl - implements SCAudioClip -{ - private boolean isLooping; - - private int loopInterval; - - private boolean isInvalid; - - /** - * Returns TRUE if this audio is invalid, FALSE otherwise. - * - * @return TRUE if this audio is invalid, FALSE otherwise - */ - public boolean isInvalid() - { - return isInvalid; - } - - /** - * Marks this audio as invalid or not. - * - * @param isInvalid TRUE to mark this audio as invalid, FALSE otherwise - */ - public void setInvalid(boolean isInvalid) - { - this.setIsInvalid(isInvalid); - } - - /** - * Returns TRUE if this audio is currently playing in loop, FALSE otherwise. - * @return TRUE if this audio is currently playing in loop, FALSE otherwise. - */ - public boolean isLooping() - { - return isLooping; - } - - /** - * Returns the loop interval if this audio is looping. - * @return the loop interval if this audio is looping - */ - public int getLoopInterval() - { - return loopInterval; - } - - /** - * @param isLooping the isLooping to set - */ - public void setIsLooping(boolean isLooping) - { - this.isLooping = isLooping; - } - - /** - * @param loopInterval the loopInterval to set - */ - public void setLoopInterval(int loopInterval) - { - this.loopInterval = loopInterval; - } - - /** - * @param isInvalid the isInvalid to set - */ - public void setIsInvalid(boolean isInvalid) - { - this.isInvalid = isInvalid; - } - - /** - * Stops this audio without setting the isLooping property in the case of - * a looping audio. The AudioNotifier uses this method to stop the audio - * when setMute(true) is invoked. This allows us to restore all looping - * audios when the sound is restored by calling setMute(false). - */ - public abstract void internalStop(); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudio.java b/src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudio.java deleted file mode 100644 index b76edaa46..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudio.java +++ /dev/null @@ -1,806 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.portaudio; - -import java.io.*; -import java.lang.reflect.*; -import java.nio.charset.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.util.*; - -/** - * Provides the interface to the native PortAudio library. - * - * @author Lyubomir Marinov - * @author Damian Minkov - * @author Sebastien Vincent - */ -public final class PortAudio -{ - /** - * The Logger used by the PortAudio class for logging - * output. - */ - private static final Logger logger = Logger.getLogger(PortAudio.class); - - static - { - System.loadLibrary("jnportaudio"); - - try - { - Pa_Initialize(); - } - catch (PortAudioException paex) - { - throw new UndeclaredThrowableException(paex); - } - } - - /** - * The number of milliseconds to be read from or written to a native - * PortAudio stream in a single transfer of data. - */ - public static final int DEFAULT_MILLIS_PER_BUFFER = 20; - - /** - * The default value for the sample rate of the input and the output - * PortAudio streams with which they are to be opened if no other specific - * sample rate is specified to the PortAudio DataSource or - * PortAudioRenderer that they represent. - */ - public static final double DEFAULT_SAMPLE_RATE = 44100; - - private static Runnable devicesChangedCallback; - - /** - * Can be passed as the framesPerBuffer parameter to - * Pa_OpenStream() or Pa_OpenDefaultStream() to indicate - * that the stream callback will accept buffers of any size. - */ - public static final long FRAMES_PER_BUFFER_UNSPECIFIED = 0; - - /** - * Used when creating new stream parameters for suggested latency to use - * high input/output value. - */ - public static final double LATENCY_HIGH = -1d; - - /** - * Used when creating new stream parameters for suggested latency to use low - * input/default value. - */ - public static final double LATENCY_LOW = -2d; - - /** - * Used when creating new stream parameters for suggested latency to use - * default value. - */ - public static final double LATENCY_UNSPECIFIED = 0d; - - /** - * PortAudio "no device" constant. - */ - public static final int paNoDevice = -1; - - /** - * The name of the double property which determines the suggested - * latency to be used when opening PortAudio streams. - */ - private static final String PROP_SUGGESTED_LATENCY - = "net.java.sip.communicator.impl.neomedia.portaudio.suggestedLatency"; - - /** - * A type used to specify one or more sample formats. The standard format - * paFloat32. - */ - public static final long SAMPLE_FORMAT_FLOAT32 = 0x00000001; - - /** - * A type used to specify one or more sample formats. The standard format - * paInt8. - */ - public static final long SAMPLE_FORMAT_INT8 = 0x00000010; - - /** - * A type used to specify one or more sample formats. The standard format - * paInt16. - */ - public static final long SAMPLE_FORMAT_INT16 = 0x00000008; - - /** - * A type used to specify one or more sample formats. The standard format - * paInt24. - */ - public static final long SAMPLE_FORMAT_INT24 = 0x00000004; - - /** - * A type used to specify one or more sample formats. The standard format - * paInt32. - */ - public static final long SAMPLE_FORMAT_INT32 = 0x00000002; - - /** - * A type used to specify one or more sample formats. The standard format - * paUInt8. - */ - public static final long SAMPLE_FORMAT_UINT8 = 0x00000020; - - /** Disables default clipping of out of range samples. */ - public static final long STREAM_FLAGS_CLIP_OFF = 0x00000001; - - /** Disables default dithering. */ - public static final long STREAM_FLAGS_DITHER_OFF = 0x00000002; - - /** - * Flag requests that where possible a full duplex stream will not discard - * overflowed input samples without calling the stream callback. This flag - * is only valid for full duplex callback streams and only when used in - * combination with the paFramesPerBufferUnspecified (0) - * framesPerBuffer parameter. Using this flag incorrectly results in a - * paInvalidFlag error being returned from Pa_OpenStream - * and Pa_OpenDefaultStream. - */ - public static final long STREAM_FLAGS_NEVER_DROP_INPUT = 0x00000004; - - /** - * Flags used to control the behavior of a stream. They are passed as - * parameters to Pa_OpenStream or Pa_OpenDefaultStream. - */ - public static final long STREAM_FLAGS_NO_FLAG = 0; - - /** A mask specifying the platform specific bits. */ - public static final long STREAM_FLAGS_PLATFORM_SPECIFIC_FLAGS = 0xFFFF0000; - - /** - * Call the stream callback to fill initial output buffers, rather than the - * default behavior of priming the buffers with zeros (silence). This flag - * has no effect for input-only and blocking read/write streams. - */ - public static final long - STREAM_FLAGS_PRIME_OUTPUT_BUFFERS_USING_STREAM_CALLBACK - = 0x00000008; - - /** - * Unchanging unique identifiers for each supported host API. This type - * is used in the PaHostApiInfo structure. The values are guaranteed to be - * unique and to never change, thus allowing code to be written that - * conditionally uses host API specific extensions. - */ - public static enum PaHostApiTypeId - { - undefined(-1), /* Used only outside pa for undefined PaHostApiTypeId */ - paInDevelopment(0),/* use while developing support for a new host API */ - paDirectSound(1), - paMME(2), - paASIO(3), - paSoundManager(4), - paCoreAudio(5), - paOSS(7), - paALSA(8), - paAL(9), - paBeOS(10), - paWDMKS(11), - paJACK(12), - paWASAPI(13), - paAudioScienceHPI(14); - - int value; - private PaHostApiTypeId(int value) - { - this.value = value; - } - - /** - * Returns PaHostApiTypeId by its type unique value. - * - * @param value the value. - * @return the corresponding PaHostApiTypeId. - */ - public static PaHostApiTypeId valueOf(int value) - { - for(PaHostApiTypeId ha : values()) - { - if(ha.value == value) - return ha; - } - - return valueOf(value); - } - } - - private static native void free(long ptr); - - /** - * Gets the native PaSampleFormat with a specific size in bits. - * - * @param sampleSizeInBits the size in bits of the native - * PaSampleFormat to get - * @return the native PaSampleFormat with the specified size in - * bits - */ - public static long getPaSampleFormat(int sampleSizeInBits) - { - switch (sampleSizeInBits) - { - case 8: - return PortAudio.SAMPLE_FORMAT_INT8; - case 24: - return PortAudio.SAMPLE_FORMAT_INT24; - case 32: - return PortAudio.SAMPLE_FORMAT_INT32; - default: - return PortAudio.SAMPLE_FORMAT_INT16; - } - } - - /** - * Gets the suggested latency to be used when opening PortAudio streams. - * - * @return the suggested latency to be used when opening PortAudio streams - */ - public static double getSuggestedLatency() - { - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - - if (cfg != null) - { - String suggestedLatencyString - = cfg.getString(PROP_SUGGESTED_LATENCY); - - if (suggestedLatencyString != null) - { - try - { - double suggestedLatency - = Double.parseDouble(suggestedLatencyString); - - if (suggestedLatency != LATENCY_UNSPECIFIED) - return suggestedLatency; - } - catch (NumberFormatException nfe) - { - logger.error( - "Failed to parse configuration property " - + PROP_SUGGESTED_LATENCY - + " value as a double", - nfe); - } - } - } - - if (OSUtils.IS_MAC || OSUtils.IS_LINUX) - return LATENCY_HIGH; - else if (OSUtils.IS_WINDOWS) - return 0.1d; - else - return LATENCY_UNSPECIFIED; - } - - /** - * Terminates audio processing immediately without waiting for pending - * buffers to complete. - * - * @param stream the steam pointer. - * @throws PortAudioException - */ - public static native void Pa_AbortStream(long stream) - throws PortAudioException; - - /** - * Closes an audio stream. If the audio stream is active it discards any - * pending buffers as if Pa_AbortStream() had been called. - * - * @param stream the steam pointer. - * @throws PortAudioException - */ - public static native void Pa_CloseStream(long stream) - throws PortAudioException; - - /** - * Retrieve the index of the default input device. - * - * @return The default input device index for the default host API, or - * paNoDevice if no default input device is available or an error - * was encountered. - */ - public static native int Pa_GetDefaultInputDevice(); - - /** - * Retrieve the index of the default output device. - * - * @return The default input device index for the default host API, or - * paNoDevice if no default input device is available or an error - * was encountered. - */ - public static native int Pa_GetDefaultOutputDevice(); - - /** - * Retrieve the number of available devices. The number of available devices - * may be zero. - * - * @return the number of devices. - * @throws PortAudioException - */ - public static native int Pa_GetDeviceCount() - throws PortAudioException; - - /** - * Retrieve a pointer to a PaDeviceInfo structure containing information - * about the specified device. - * - * @param deviceIndex the device index - * @return pointer to device info structure. - */ - public static native long Pa_GetDeviceInfo(int deviceIndex); - - /** - * Retrieve a pointer to a structure containing information about a specific - * host Api. - * - * @param hostApiIndex host api index. - * @return A pointer to an immutable PaHostApiInfo structure describing a - * specific host API. - */ - public static native long Pa_GetHostApiInfo(int hostApiIndex); - - /** - * Retrieve the size of a given sample format in bytes. - * - * @param format the format. - * @return The size in bytes of a single sample in the specified format, or - * paSampleFormatNotSupported if the format is not supported. - */ - public static native int Pa_GetSampleSize(long format); - - /** - * Retrieve the number of frames that can be read from the stream without - * waiting. - * - * @param stream pointer to the stream. - * @return returns a non-negative value representing the maximum number of - * frames that can be read from the stream without blocking or busy waiting - * or, a PaErrorCode (which are always negative) if PortAudio is - * not initialized or an error is encountered. - */ - public static native long Pa_GetStreamReadAvailable(long stream); - - /** - * Retrieve the number of frames that can be written to the stream - * without waiting. - * @param stream pointer to the stream. - * @return returns a non-negative value representing the maximum number - * of frames that can be written to the stream without blocking - * or busy waiting or, a PaErrorCode (which are always negative) - * if PortAudio is not initialized or an error is encountered. - */ - public static native long Pa_GetStreamWriteAvailable(long stream); - - /** - * Initializes the native PortAudio library. - * - * @throws PortAudioException - */ - private static native void Pa_Initialize() - throws PortAudioException; - - /** - * Determine whether it would be possible to open a stream - * with the specified parameters. - * @param inputParameters A structure that describes the - * input parameters used to open a stream. - * @param outputParameters A structure that describes the output - * parameters used to open a stream. - * @param sampleRate The required sampleRate. - * @return returns 0 if the format is supported, and an error code - * indicating why the format is not supported otherwise. - * The constant paFormatIsSupported is provided to compare - * with the return value for success. - */ - public static native boolean Pa_IsFormatSupported( - long inputParameters, - long outputParameters, - double sampleRate); - - /** - * Opens a stream for either input, output or both. - * @param inputParameters the input params or 0 if absent. - * @param outputParameters the ouput params or 0 if absent. - * @param sampleRate The desired sampleRate. - * @param framesPerBuffer The number of frames passed to the stream - * callback function, or the preferred block granularity for - * a blocking read/write stream - * @param streamFlags Flags which modify the - * behaviour of the streaming process. - * @param streamCallback A pointer to a client supplied function that is - * responsible for processing and filling input and output buffers. - * If this parameter is NULL the stream will be opened in - * 'blocking read/write' mode. - * @return pointer to the opened stream. - * @throws PortAudioException - */ - public static native long Pa_OpenStream( - long inputParameters, - long outputParameters, - double sampleRate, - long framesPerBuffer, - long streamFlags, - PortAudioStreamCallback streamCallback) - throws PortAudioException; - - /** - * Read samples from an input stream. The function doesn't return until - * the entire buffer has been filled - this may involve waiting for - * the operating system to supply the data. - * @param stream pointer to the stream. - * @param buffer a buffer of sample frames. - * @param frames The number of frames to be read into buffer. - * @throws PortAudioException - */ - public static native void Pa_ReadStream( - long stream, byte[] buffer, long frames) - throws PortAudioException; - - /** - * Commences audio processing. - * @param stream pointer to the stream - * @throws PortAudioException - */ - public static native void Pa_StartStream(long stream) - throws PortAudioException; - - /** - * Terminates audio processing. It waits until all pending audio buffers - * have been played before it returns. - * @param stream pointer to the stream - * @throws PortAudioException - */ - public static native void Pa_StopStream(long stream) - throws PortAudioException; - - public static void Pa_UpdateAvailableDeviceList() - { - updateAvailableDeviceList(); - } - - /** - * Write samples to an output stream. This function doesn't return until - * the entire buffer has been consumed - this may involve waiting for the - * operating system to consume the data. - * @param stream pointer to the stream - * @param buffer A buffer of sample frames. - * @param frames The number of frames to be written from buffer. - * @throws PortAudioException - */ - public static void Pa_WriteStream(long stream, byte[] buffer, long frames) - throws PortAudioException - { - Pa_WriteStream(stream, buffer, 0, frames, 1); - } - - /** - * Writes samples to an output stream. Does not return until the specified - * samples have been consumed - this may involve waiting for the operating - * system to consume the data. - *

- * Provides better efficiency than achieved through multiple consecutive - * calls to {@link #Pa_WriteStream(long, byte[], long)} with one and the - * same buffer because the JNI access to the bytes of the buffer which is - * likely to copy the whole buffer is only performed once. - *

- * - * @param stream the pointer to the PortAudio stream to write the samples to - * @param buffer the buffer containing the samples to be written - * @param offset the byte offset in buffer at which the samples to - * be written start - * @param frames the number of frames from buffer starting at - * offset are to be written with a single write - * @param numberOfWrites the number of writes each writing frames - * number of frames to be performed - * @throws PortAudioException if anything goes wrong while writing - */ - public static native void Pa_WriteStream( - long stream, - byte[] buffer, - int offset, - long frames, - int numberOfWrites) - throws PortAudioException; - - /** - * Gets the human-readable name of the PaDeviceInfo specified by a - * pointer to it. - * - * @param deviceInfo the pointer to the PaDeviceInfo to get the - * human-readable name of - * @return the human-readable name of the PaDeviceInfo pointed to - * by deviceInfo - */ - public static String PaDeviceInfo_getName(long deviceInfo) - { - byte[] nameBytes = PaDeviceInfo_getNameBytes(deviceInfo); - Charset defaultCharset = Charset.defaultCharset(); - String charsetName - = (defaultCharset == null) ? "UTF-8" : defaultCharset.name(); - - try - { - return new String(nameBytes, charsetName); - } - catch (UnsupportedEncodingException ueex) - { - return new String(nameBytes); - } - } - - /** - * Returns defaultHighInputLatency for the device. - * @param deviceInfo device info pointer. - * @return defaultHighInputLatency for the device. - */ - public static native double PaDeviceInfo_getDefaultHighInputLatency( - long deviceInfo); - - /** - * Returns defaultHighOutputLatency for the device. - * @param deviceInfo device info pointer. - * @return defaultHighOutputLatency for the device. - */ - public static native double PaDeviceInfo_getDefaultHighOutputLatency( - long deviceInfo); - - /** - * Returns defaultLowInputLatency for the device. - * @param deviceInfo device info pointer. - * @return defaultLowInputLatency for the device. - */ - public static native double PaDeviceInfo_getDefaultLowInputLatency( - long deviceInfo); - - /** - * Returns defaultLowOutputLatency for the device. - * @param deviceInfo device info pointer. - * @return defaultLowOutputLatency for the device. - */ - public static native double PaDeviceInfo_getDefaultLowOutputLatency( - long deviceInfo); - - /** - * The default samplerate for the deviec. - * @param deviceInfo device info pointer. - * @return the default sameple rate for the device. - */ - public static native double PaDeviceInfo_getDefaultSampleRate( - long deviceInfo); - - /** - * The host api of the device. - * @param deviceInfo device info pointer. - * @return The host api of the device. - */ - public static native int PaDeviceInfo_getHostApi(long deviceInfo); - - /** - * Maximum input channels for the device. - * @param deviceInfo device info pointer. - * @return Maximum input channels for the device. - */ - public static native int PaDeviceInfo_getMaxInputChannels(long deviceInfo); - - /** - * Maximum output channels for the device. - * @param deviceInfo device info pointer. - * @return Maximum output channels for the device. - */ - public static native int PaDeviceInfo_getMaxOutputChannels(long deviceInfo); - - /** - * Gets the name as a byte array of the PortAudio device specified - * by the pointer to its PaDeviceInfo instance. - * - * @param deviceInfo the pointer to the PaDeviceInfo instance to - * get the name of - * @return the name as a byte array of the PortAudio device - * specified by the PaDeviceInfo instance pointed to by - * deviceInfo - */ - private static native byte[] PaDeviceInfo_getNameBytes(long deviceInfo); - - /** - * The default input device for this host API. - * @param hostApiInfo pointer to host api info structure. - * @return The default input device for this host API. - */ - public static native int PaHostApiInfo_getDefaultInputDevice( - long hostApiInfo); - - /** - * The default output device for this host API. - * @param hostApiInfo pointer to host api info structure. - * @return The default output device for this host API. - */ - public static native int PaHostApiInfo_getDefaultOutputDevice( - long hostApiInfo); - - /** - * The number of devices belonging to this host API. - * @param hostApiInfo pointer to host api info structure. - * @return The number of devices belonging to this host API. - */ - public static native int PaHostApiInfo_getDeviceCount(long hostApiInfo); - - /** - * Gets the human-readable name of the PaHostApiInfo specified by a - * pointer to it. - * - * @param hostApiInfo the pointer to the PaHostApiInfo to get the - * human-readable name of - * @return the human-readable name of the PaHostApiInfo pointed to - * by hostApiInfo - * @deprecated Presumes that the name of PaHostApiInfo is - * encoded in modified UTF-8 - */ - @Deprecated - public static native String PaHostApiInfo_getName(long hostApiInfo); - - /** - * The well known unique identifier of this host API. - * @param hostApiInfo pointer to host api info structure. - * @return The well known unique identifier of this host API. - * Enumerator: - * paInDevelopment - * paDirectSound - * paMME - * paASIO - * paSoundManager - * paCoreAudio - * paOSS - * paALSA - * paAL - * paBeOS - * paWDMKS - * paJACK - * paWASAPI - * paAudioScienceHPI - */ - public static native int PaHostApiInfo_getType(long hostApiInfo); - - /** - * Free StreamParameters resources specified by a pointer to it. - * - * @param streamParameters the pointer to the PaStreamParameters - * to free - */ - public static void PaStreamParameters_free(long streamParameters) - { - try - { - free(streamParameters); - return; - } - catch (UnsatisfiedLinkError ulerr) - { - /* - * Ignore it because we'll try to fallback to another - * implementation. - */ - logger.warn( - "The JNI library jnportaudio is out-of-date and needs to be" - + " recompiled.", - ulerr); - } - /* - * FFmpeg on Windows seems to be compiled with --enable-memalign-hack so - * av_free(void *) isn't the same as free(void *) and thus is not a - * suitable/safe fallback. - */ - if (OSUtils.IS_LINUX || OSUtils.IS_MAC) - { - try - { - FFmpeg.av_free(streamParameters); - } - catch (NoClassDefFoundError ncdferr) - { - // We'll warn bellow, don't fail. - } - catch (UnsatisfiedLinkError ulerr) - { - // We'll warn bellow, don't fail. - } - return; - } - logger.warn("Leaking a PaStreamParameters instance."); - } - - /** - * Creates parameters used for opening streams. - * @param deviceIndex the device. - * @param channelCount the channels to be used. - * @param sampleFormat the sample format. - * @param suggestedLatency the suggested latency in milliseconds: - * LATENCY_UNSPECIFIED - - * use default(default high input/output latency) - * LATENCY_HIGH - use default high input/output latency - * LATENCY_LOW - use default low input/output latency - * ... - any other value in milliseconds (e.g. 0.1 is acceptable) - * @return pointer to the params used for Pa_OpenStream. - */ - public static native long PaStreamParameters_new( - int deviceIndex, - int channelCount, - long sampleFormat, - double suggestedLatency); - - /** - * Sets the indicator which determines whether a specific (input) PortAudio - * stream is to have denoise performed on the audio data it provides. - * - * @param stream the (input) PortAudio stream for which denoise is to be - * enabled or disabled - * @param denoise true if denoise is to be performed on the audio - * data provided by stream; otherwise, false - */ - public static native void setDenoise(long stream, boolean denoise); - - /** - * Sets the number of milliseconds of echo to be canceled in the audio data - * provided by a specific (input) PortAudio stream. - * - * @param stream the (input) PortAudio stream for which the number of - * milliseconds of echo to be canceled is to be set - * @param echoFilterLengthInMillis the number of milliseconds of echo to be - * canceled in the audio data provided by stream - */ - public static native void setEchoFilterLengthInMillis( - long stream, - long echoFilterLengthInMillis); - - /** - * Updates available device lists in PortAudio. - */ - private static native void updateAvailableDeviceList(); - - /** - * Implements a (legacy) callback which gets called by the native PortAudio - * counterpart to notify the Java counterpart that the list of PortAudio - * devices has changed. - */ - public static void deviceChanged() - { - devicesChangedCallback(); - } - - /** - * Implements a callback which gets called by the native PortAudio - * counterpart to notify the Java counterpart that the list of PortAudio - * devices has changed. - */ - public static void devicesChangedCallback() - { - Runnable devicesChangedCallback = PortAudio.devicesChangedCallback; - - if (devicesChangedCallback != null) - devicesChangedCallback.run(); - } - - public static void setDevicesChangedCallback( - Runnable devicesChangedCallback) - { - PortAudio.devicesChangedCallback = devicesChangedCallback; - } - - /** - * Prevents the initialization of PortAudio instances. - */ - private PortAudio() - { - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudioException.java b/src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudioException.java deleted file mode 100644 index 95f4046da..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudioException.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.portaudio; - -/** - * @author Lubomir Marinov - */ -public class PortAudioException - extends Exception -{ - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * Constructs a PortAudioException with message as - * description. - * @param message description of the exception - */ - public PortAudioException(String message) - { - super(message); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudioStreamCallback.java b/src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudioStreamCallback.java deleted file mode 100644 index 4dfcceebb..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudioStreamCallback.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.portaudio; - -import java.nio.*; - -/** - * @author Lubomir Marinov - */ -public interface PortAudioStreamCallback -{ - /** - * "Abort" resut code. - */ - public static final int RESULT_ABORT = 2; - - /** - * "Complete" resut code. - */ - public static final int RESULT_COMPLETE = 1; - - /** - * "Continue" resut code. - */ - public static final int RESULT_CONTINUE = 0; - - /** - * Callback. - * - * @param input input ByteBuffer - * @param output output ByteBuffer - * @return - */ - public int callback(ByteBuffer input, ByteBuffer output); - - /** - * Finished callback. - */ - public void finishedCallback(); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/protocol/BufferStreamAdapter.java b/src/net/java/sip/communicator/impl/neomedia/protocol/BufferStreamAdapter.java deleted file mode 100644 index 2f14ee7a7..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/protocol/BufferStreamAdapter.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.protocol; - -import java.io.*; - -import javax.media.*; -import javax.media.protocol.*; - -/** - * Represents a base class for adapters of SourceStreams, usually - * ones reading data in arrays of bytes and not in Buffers, to - * SourceStreams reading data in Buffers. An example - * use is creating a PushBufferStream representation of a PushSourceStream. - * - * @param the very type of SourceStream to be adapted by a - * BufferStreamAdapter - * @author Lubomir Marinov - */ -public abstract class BufferStreamAdapter - implements SourceStream -{ - - /** - * The Format of this stream to be reported through the output - * Buffer this instance reads data into. - */ - private final Format format; - - /** - * The SourceStream being adapted by this instance. - */ - protected final T stream; - - /** - * Initializes a new BufferStreamAdapter which is to adapt a - * specific SourceStream into a SourceStream with - * a specific Format. - * - * @param stream the SourceStream to be adapted - * @param format the specific Format of the SourceStream - */ - public BufferStreamAdapter(T stream, Format format) - { - this.stream = stream; - this.format = format; - } - - /** - * Implements SourceStream#endOfStream(). Delegates to the wrapped - * SourceStream. - * - * @return true if the stream is finished, false otherwise - */ - public boolean endOfStream() - { - return stream.endOfStream(); - } - - /** - * Implements SourceStream#getContentDescriptor(). Delegates to the wrapped - * SourceStream. - * - * @return the ContentDescriptor of the stream - */ - public ContentDescriptor getContentDescriptor() - { - return stream.getContentDescriptor(); - } - - /** - * Implements SourceStream#getContentLength(). Delegates to the wrapped - * SourceStream. - * - * @return content length - */ - public long getContentLength() - { - return stream.getContentLength(); - } - - /** - * Implements Controls#getControl(String). Delegates to the wrapped - * SourceStream. - * - * @param controlType a String value naming the type of the control - * of this instance to be retrieved - * @return an Object which represents the control of this instance - * with the specified type - */ - public Object getControl(String controlType) - { - return stream.getControl(controlType); - } - - /** - * Implements Controls#getControls(). Delegates to the wrapped SourceStream. - * - * @return array of JMF Control objects - */ - public Object[] getControls() - { - return stream.getControls(); - } - - /** - * Gets the Format of the data this stream provides. - * - * @return the Format of the data this stream provides - */ - public Format getFormat() - { - return format; - } - - /** - * Gets the SourceStream wrapped by this instance. - * - * @return the SourceStream wrapped by this instance - */ - public T getStream() - { - return stream; - } - - /** - * Reads byte data from this stream into a specific Buffer - * which is to use a specific array of bytes for its data. - * - * @param buffer the Buffer to read byte data into from this - * instance - * @param bytes the array of bytes to read data into from this - * instance and to be set as the data of the specified - * buffer - * @throws IOException if I/O related errors occurred during read operation - */ - protected void read(Buffer buffer, byte[] bytes) - throws IOException - { - int offset = 0; - int numberOfBytesRead = read(bytes, offset, bytes.length); - - if (numberOfBytesRead > -1) - { - buffer.setData(bytes); - buffer.setOffset(offset); - buffer.setLength(numberOfBytesRead); - - Format format = getFormat(); - - if (format != null) - buffer.setFormat(format); - } - } - - /** - * Reads byte data from this stream into a specific array of - * bytes starting the storing at a specific offset and reading - * at most a specific number of bytes. - * - * @param buffer the array of bytes into which the data read - * from this stream is to be written - * @param offset the offset in the specified buffer at which - * writing data read from this stream should start - * @param length the maximum number of bytes to be written into the - * specified buffer - * @return the number of bytes read from this stream and written into the - * specified buffer - * @throws IOException if I/O related errors occurred during read operation - */ - protected abstract int read(byte[] buffer, int offset, int length) - throws IOException; -} diff --git a/src/net/java/sip/communicator/impl/neomedia/protocol/CachingPushBufferStream.java b/src/net/java/sip/communicator/impl/neomedia/protocol/CachingPushBufferStream.java deleted file mode 100644 index 4101e610f..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/protocol/CachingPushBufferStream.java +++ /dev/null @@ -1,777 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.protocol; - -import java.io.*; -import java.util.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; -import javax.media.protocol.*; - -/** - * Enables reading from a PushBufferStream a certain maximum number - * of data units (e.g. bytes, shorts, ints) even if the - * PushBufferStream itself pushes a larger number of data units. - *

- * An example use of this functionality is pacing a - * PushBufferStream which pushes more data units in a single step - * than a CaptureDevice. When these two undergo audio mixing, the - * different numbers of per-push data units will cause the - * PushBufferStream "play" itself faster than the - * CaptureDevice. - *

- * - * @author Lyubomir Marinov - */ -public class CachingPushBufferStream - implements PushBufferStream -{ - - /** - * The default length in milliseconds of the buffering to be performed by - * CachePushBufferStreams. - */ - public static final long DEFAULT_BUFFER_LENGTH = 20; - - /** - * The maximum number of Buffers to be cached in a - * CachingPushBufferStream. Generally, defined to a relatively - * large value which allows large buffering and yet tries to prevent - * OutOfMemoryError. - */ - private static final int MAX_CACHE_SIZE = 1024; - - /** - * The BufferControl of this PushBufferStream which allows - * the adjustment of the size of the buffering it performs. - */ - private BufferControl bufferControl; - - /** - * The Object which synchronizes the access to - * {@link #bufferControl}. - */ - private final Object bufferControlSyncRoot = new Object(); - - /** - * The list of Buffers in which this instance stores the data it - * reads from the wrapped PushBufferStream and from which it reads - * in chunks later on when its {@link #read(Buffer)} method is called. - */ - private final List cache = new LinkedList(); - - /** - * The length of the media in milliseconds currently available in - * {@link #cache}. - */ - private long cacheLengthInMillis = 0; - - /** - * The last IOException this stream has received from the - * #read(Buffer) method of the wrapped stream and to be thrown - * by this stream on the earliest call of its #read(Buffer) - * method. - */ - private IOException readException; - - /** - * The PushBufferStream being paced by this instance with - * respect to the maximum number of data units it provides in a single push. - */ - private final PushBufferStream stream; - - /** - * The BufferTransferHandler set on {@link #stream}. - */ - private BufferTransferHandler transferHandler; - - /** - * Initializes a new CachingPushBufferStream instance which is - * to pace the number of per-push data units a specific - * PushBufferStream provides. - * - * @param stream the PushBufferStream to be paced with respect to - * the number of per-push data units it provides - */ - public CachingPushBufferStream(PushBufferStream stream) - { - this.stream = stream; - } - - /** - * Determines whether adding a new Buffer to {@link #cache} is - * acceptable given the maximum size of the cache and the length of - * the media currently available in it. - * - * @return true if adding a new Buffer to cache - * is acceptable; otherwise, false which means that the reading - * from the wrapped PushBufferStream should be blocked until - * true is returned - */ - private boolean canWriteInCache() - { - synchronized (cache) - { - int cacheSize = cache.size(); - - /* - * Obviously, if there's nothing in the cache, we desperately want - * something to be written into it. - */ - if (cacheSize < 1) - return true; - /* - * For the sake of not running out of memory, don't let the sky be - * the limit. - */ - if (cacheSize >= MAX_CACHE_SIZE) - return false; - - long bufferLength = getBufferLength(); - - /* - * There is no bufferLength specified by a BufferControl so don't - * buffer anything. - */ - if (bufferLength < 1) - return false; - /* - * Having Buffers in the cache and yet not having their length in - * milliseconds is weird so don't buffer anything. - */ - if (cacheLengthInMillis < 1) - return false; - /* - * Of course, if the media in the cache hasn't reached the specified - * buffer length, write more to the cache. - */ - return (cacheLengthInMillis < bufferLength); - } - } - - /** - * Implements {@link SourceStream#endOfStream()}. Delegates to the wrapped - * PushBufferStream when the cache of this instance is fully read; - * otherwise, returns false. - * - * @return true if this PushBufferStream has reached the - * end of the content it makes available; otherwise, false - */ - public boolean endOfStream() - { - /* - * TODO If the cache is still not exhausted, don't report the end of - * this stream even if the wrapped stream has reached its end. - */ - return stream.endOfStream(); - } - - /** - * Gets the BufferControl of this PushBufferStream which - * allows the adjustment of the size of the buffering it performs. If it - * does not exist yet, it is created. - * - * @return the BufferControl of this PushBufferStream - * which allows the adjustment of the size of the buffering it performs - */ - private BufferControl getBufferControl() - { - synchronized (bufferControlSyncRoot) - { - if (bufferControl == null) - bufferControl = new BufferControlImpl(); - return bufferControl; - } - } - - /** - * Gets the length in milliseconds of the buffering performed by this - * PushBufferStream. - * - * @return the length in milliseconds of the buffering performed by this - * PushBufferStream if such a value has been set; otherwise, - * {@link BufferControl#DEFAULT_VALUE} - */ - private long getBufferLength() - { - synchronized (bufferControlSyncRoot) - { - return - (bufferControl == null) - ? BufferControl.DEFAULT_VALUE - : bufferControl.getBufferLength(); - } - } - - /** - * Implements {@link SourceStream#getContentDescriptor()}. Delegates to the - * wrapped PushBufferStream. - * - * @return a ContentDescriptor which describes the type of the - * content made available by the wrapped PushBufferStream - */ - public ContentDescriptor getContentDescriptor() - { - return stream.getContentDescriptor(); - } - - /** - * Implements {@link SourceStream#getContentLength()}. Delegates to the - * wrapped PushBufferStream. - * - * @return the length of the content made available by the wrapped - * PushBufferStream - */ - public long getContentLength() - { - return stream.getContentLength(); - } - - /** - * Implements {@link javax.media.Controls#getControl(String)}. Delegates to - * the wrapped PushBufferStream and gives access to the - * BufferControl of this instance if such a controlType is - * specified and the wrapped PushBufferStream does not have such a - * control available. - * - * @param controlType a String value which names the type of the - * control of the wrapped PushBufferStream to be retrieved - * @return an Object which represents the control of the wrapped - * PushBufferStream with the specified type if such a control is - * available; otherwise, null - */ - public Object getControl(String controlType) - { - Object control = stream.getControl(controlType); - - if ((control == null) - && BufferControl.class.getName().equals(controlType)) - control = getBufferControl(); - return control; - } - - /** - * Implements {@link javax.media.Controls#getControls()}. Delegates to the - * wrapped PushBufferStream and adds the BufferControl of - * this instance if the wrapped PushBufferStream does not have a - * control of such type available. - * - * @return an array of Objects which represent the control - * available for the wrapped PushBufferStream - */ - public Object[] getControls() - { - Object[] controls = stream.getControls(); - - if (controls == null) - { - BufferControl bufferControl = getBufferControl(); - - if (bufferControl != null) - controls = new Object[] { bufferControl }; - } - else - { - boolean bufferControlExists = false; - - for (Object control : controls) - if (control instanceof BufferControl) - { - bufferControlExists = true; - break; - } - if (!bufferControlExists) - { - BufferControl bufferControl = getBufferControl(); - - if (bufferControl != null) - { - Object[] newControls = new Object[controls.length + 1]; - - newControls[0] = bufferControl; - System.arraycopy( - controls, 0, - newControls, 1, - controls.length); - } - } - } - return controls; - } - - /** - * Implements {@link PushBufferStream#getFormat()}. Delegates to the wrapped - * PushBufferStream. - * - * @return the Format of the media data available for reading in - * this PushBufferStream - */ - public Format getFormat() - { - return stream.getFormat(); - } - - /** - * Gets the length in milliseconds of the media in a specific - * Buffer (often referred to as duration). - * - * @param buffer the Buffer which contains media the length in - * milliseconds of which is to be calculated - * @return the length in milliseconds of the media in buffer if - * there actually is media in buffer and its length in milliseconds - * can be calculated; otherwise, 0 - */ - private long getLengthInMillis(Buffer buffer) - { - int length = buffer.getLength(); - - if (length < 1) - return 0; - - Format format = buffer.getFormat(); - - if (format == null) - { - format = getFormat(); - if (format == null) - return 0; - } - if (!(format instanceof AudioFormat)) - return 0; - - AudioFormat audioFormat = (AudioFormat) format; - long duration = audioFormat.computeDuration(length); - - return (duration < 1) ? 0 : (duration / 1000000); - } - - /** - * Gets the PushBufferStream wrapped by this instance. - * - * @return the PushBufferStream wrapped by this instance - */ - public PushBufferStream getStream() - { - return stream; - } - - /** - * Implements {@link PushBufferStream#read(Buffer)}. If an - * IOException has been thrown by the wrapped stream when data was - * last read from it, re-throws it. If there has been no such exception, - * reads from the cache of this instance. - * - * @param buffer the Buffer to receive the read media data - * @throws IOException if the wrapped stream has thrown such an exception - * when data was last read from it - */ - public void read(Buffer buffer) - throws IOException - { - synchronized (cache) - { - if (readException != null) - { - IOException ex = new IOException(); - - ex.initCause(readException); - readException = null; - throw ex; - } - - buffer.setLength(0); - if (!cache.isEmpty()) - { - int bufferOffset = buffer.getOffset(); - - while (!cache.isEmpty()) - { - Buffer cacheBuffer = cache.get(0); - int nextBufferOffset - = read(cacheBuffer, buffer, bufferOffset); - - if ((cacheBuffer.getLength() <= 0) - || (cacheBuffer.getData() == null)) - cache.remove(0); - if (nextBufferOffset < 0) - break; - else - bufferOffset = nextBufferOffset; - } - - cacheLengthInMillis -= getLengthInMillis(buffer); - if (cacheLengthInMillis < 0) - cacheLengthInMillis = 0; - - if (canWriteInCache()) - cache.notify(); - } - } - } - - /** - * Reads data from a specific input Buffer (if such data is - * available) and writes the read data into a specific output - * Buffer. The input Buffer will be modified to reflect - * the number of read data units. If the output Buffer has - * allocated an array for storing the read data and the type of this array - * matches that of the input Buffer, it will be used and thus the - * output Buffer may control the maximum number of data units to be - * read into it. - * - * @param input the Buffer to read data from - * @param output the Buffer into which to write the data read - * from the specified input - * @param outputOffset the offset in output at which the data read - * from input is to be written - * @return the offset in output at which a next round of writing is - * to continue; -1 if no more writing in output is to be - * performed and output is to be returned to the caller - * @throws IOException if reading from input into output - * fails including if either of the formats of input and - * output are not supported - */ - private int read(Buffer input, Buffer output, int outputOffset) - throws IOException - { - Object outputData = output.getData(); - - if (outputData != null) - { - Object inputData = input.getData(); - - if (inputData == null) - { - output.setFormat(input.getFormat()); - /* - * There was nothing to read so continue reading and - * concatenating. - */ - return outputOffset; - } - - Class dataType = outputData.getClass(); - - if (inputData.getClass().equals(dataType) - && dataType.equals(byte[].class)) - { - int inputOffset = input.getOffset(); - int inputLength = input.getLength(); - byte[] outputBytes = (byte[]) outputData; - int outputLength - = outputBytes.length - outputOffset; - - // Where is it supposed to be written? - if (outputLength < 1) - return -1; - - if (inputLength < outputLength) - outputLength = inputLength; - System.arraycopy( - (byte[]) inputData, - inputOffset, - outputBytes, - outputOffset, - outputLength); - - output.setData(outputBytes); - output.setLength(output.getLength() + outputLength); - - /* - * If we're currently continuing a concatenation, the parameters - * of the first read from input are left as the parameters of - * output. Mostly done at least for timeStamp. - */ - if (output.getOffset() == outputOffset) - { - output.setFormat(input.getFormat()); - - output.setDiscard(input.isDiscard()); - output.setEOM(input.isEOM()); - output.setFlags(input.getFlags()); - output.setHeader(input.getHeader()); - output.setSequenceNumber(input.getSequenceNumber()); - output.setTimeStamp(input.getTimeStamp()); - - /* - * It's possible that we've split the input into multiple - * outputs so the output duration may be different than the - * input duration. An alternative to Buffer.TIME_UNKNOWN is - * possibly the calculation of the output duration as the - * input duration multiplied by the ratio between the - * current output length and the initial input length. - */ - output.setDuration(Buffer.TIME_UNKNOWN); - } - - input.setLength(inputLength - outputLength); - input.setOffset(inputOffset + outputLength); - // Continue reading and concatenating. - return (outputOffset + outputLength); - } - } - - /* - * If we were supposed to continue a concatenation and we discovered - * that it could not be continued, flush whatever has already been - * written to the caller. - */ - if (output.getOffset() == outputOffset) - { - output.copy(input); - - int outputLength = output.getLength(); - - input.setLength(input.getLength() - outputLength); - input.setOffset(input.getOffset() + outputLength); - } - /* - * We didn't know how to concatenate the media so return it to the - * caller. - */ - return -1; - } - - /** - * Implements - * {@link PushBufferStream#setTransferHandler(BufferTransferHandler)}. - * Delegates to the wrapped PushBufferStream but wraps the specified - * BufferTransferHandler in order to intercept the calls to - * {@link BufferTransferHandler#transferData(PushBufferStream)} and read - * data from the wrapped PushBufferStream into the cache during the - * calls in question. - * - * @param transferHandler the BufferTransferHandler to be notified - * by this PushBufferStream when media data is available for - * reading - */ - public void setTransferHandler(BufferTransferHandler transferHandler) - { - synchronized (cache) - { - BufferTransferHandler substituteTransferHandler - = (transferHandler == null) - ? null - : new StreamSubstituteBufferTransferHandler( - transferHandler, - stream, - this) - { - @Override - public void transferData(PushBufferStream stream) - { - if (CachingPushBufferStream.this.stream - == stream) - { - CachingPushBufferStream.this.transferData( - this); - } - - super.transferData(stream); - } - }; - - stream.setTransferHandler(substituteTransferHandler); - this.transferHandler = substituteTransferHandler; - cache.notifyAll(); - } - } - - /** - * Reads data from the wrapped/input PushBufferStream into the - * cache of this stream if the cache accepts it. If the cache does not - * accept a new read, blocks the calling thread until the cache accepts a - * new read and data is read from the wrapped PushBufferStream into - * the cache. - * - * @param transferHandler the BufferTransferHandler which has been - * notified - */ - protected void transferData(BufferTransferHandler transferHandler) - { - synchronized (cache) - { - boolean interrupted = false; - - while (true) - { - if (this.transferHandler != transferHandler) - return; - if (canWriteInCache()) - break; - try - { - cache.wait(); - } - catch (InterruptedException iex) - { - interrupted = true; - } - } - if (interrupted) - Thread.currentThread().interrupt(); - - Buffer buffer = new Buffer(); - - try - { - stream.read(buffer); - readException = null; - } - catch (IOException ioex) - { - readException = ioex; - } - cache.add(buffer); - cacheLengthInMillis += getLengthInMillis(buffer); - } - } - - /** - * Implements a BufferControl which enables the adjustment of the - * length of the buffering performed by a CachingPushBufferStream. - */ - private static class BufferControlImpl - implements BufferControl - { - - /** - * The length of the buffering to be performed by the owner of this - * instance. - */ - private long bufferLength = DEFAULT_VALUE; - - /** - * The indicator which determines whether threshold calculations are - * enabled. - * - * @see BufferControl#setEnabledThreshold(boolean) - */ - private boolean enabledThreshold; - - /** - * The minimum threshold in milliseconds for the buffering performed by - * the owner of this instance. - * - * @see BufferControl#getMinimumThreshold() - */ - private long minimumThreshold = DEFAULT_VALUE; - - /** - * Implements {@link BufferControl#getBufferLength()}. Gets the length - * in milliseconds of the buffering performed by the owner of this - * instance. - * - * @return the length in milliseconds of the buffering performed by the - * owner of this instance; {@link BufferControl#DEFAULT_VALUE} if it is - * up to the owner of this instance to decide the length in milliseconds - * of the buffering to perform if any - */ - public long getBufferLength() - { - return bufferLength; - } - - /** - * Implements {@link Control#getControlComponent()}. Gets the UI - * Component representing this instance and exported by the - * owner of this instance. Returns null. - * - * @return the UI Component representing this instance and - * exported by the owner of this instance if such a Component - * is available; otherwise, null - */ - public java.awt.Component getControlComponent() - { - return null; - } - - /** - * Implements {@link BufferControl#getEnabledThreshold()}. Gets the - * indicator which determines whether threshold calculations are - * enabled. - * - * @return true if threshold calculations are enabled; - * otherwise, false - */ - public boolean getEnabledThreshold() - { - return enabledThreshold; - } - - /** - * Implements {@link BufferControl#getMinimumThreshold()}. Gets the - * minimum threshold in milliseconds for the buffering performed by the - * owner of this instance. - * - * @return the minimum threshold in milliseconds for the buffering - * performed by the owner of this instance - */ - public long getMinimumThreshold() - { - return minimumThreshold; - } - - /** - * Implements {@link BufferControl#setBufferLength(long)}. Sets the - * length in milliseconds of the buffering to be performed by the owner - * of this instance and returns the value actually in effect after - * attempting to set it to the specified value. - * - * @param bufferLength the length in milliseconds of the buffering to be - * performed by the owner of this instance - * @return the length in milliseconds of the buffering performed by the - * owner of this instance that is actually in effect after the attempt - * to set it to the specified bufferLength - */ - public long setBufferLength(long bufferLength) - { - if ((bufferLength == DEFAULT_VALUE) || (bufferLength > 0)) - this.bufferLength = bufferLength; - // Returns the current value as specified by the javadoc. - return getBufferLength(); - } - - /** - * Implements {@link BufferControl#setEnabledThreshold(boolean)}. Sets - * the indicator which determines whether threshold calculations are - * enabled. - * - * @param enabledThreshold true if threshold calculations are - * to be enabled; otherwise, false - */ - public void setEnabledThreshold(boolean enabledThreshold) - { - this.enabledThreshold = enabledThreshold; - } - - /** - * Implements {@link BufferControl#setMinimumThreshold(long)}. Sets the - * minimum threshold in milliseconds for the buffering to be performed - * by the owner of this instance and returns the value actually in - * effect after attempting to set it to the specified value. - * - * @param minimumThreshold the minimum threshold in milliseconds for the - * buffering to be performed by the owner of this instance - * @return the minimum threshold in milliseconds for the buffering - * performed by the owner of this instance that is actually in effect - * after the attempt to set it to the specified - * minimumThreshold - */ - public long setMinimumThreshold(long minimumThreshold) - { - /* - * The minimumThreshold property is not supported in any way at the - * time of this writing so returns the current value as specified by - * the javadoc. - */ - return getMinimumThreshold(); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/protocol/CaptureDeviceDelegatePullBufferDataSource.java b/src/net/java/sip/communicator/impl/neomedia/protocol/CaptureDeviceDelegatePullBufferDataSource.java deleted file mode 100644 index 9ef72671d..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/protocol/CaptureDeviceDelegatePullBufferDataSource.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.protocol; - -import java.io.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.control.*; - -/** - * Represents a PullBufferDataSource which is also a - * CaptureDevice through delegation to a specific - * CaptureDevice. - * - * @author Damian Minkov - * @author Lubomir Marinov - */ -public class CaptureDeviceDelegatePullBufferDataSource - extends PullBufferDataSource - implements CaptureDevice -{ - /** - * The CaptureDevice this instance delegates to in order to - * implement its CaptureDevice functionality. - */ - protected final CaptureDevice captureDevice; - - /** - * The constant which represents an empty array with - * PullBufferStream element type. Explicitly defined in order to - * reduce unnecessary allocations. - */ - protected static final PullBufferStream[] EMPTY_STREAMS - = new PullBufferStream[0]; - - /** - * Initializes a new CaptureDeviceDelegatePullBufferDataSource - * instance which delegates to a specific CaptureDevice in order to - * implement its CaptureDevice functionality. - * - * @param captureDevice the CaptureDevice the new instance is to - * delegate to in order to provide its CaptureDevice functionality - */ - public CaptureDeviceDelegatePullBufferDataSource( - CaptureDevice captureDevice) - { - this.captureDevice = captureDevice; - } - - /** - * Implements {@link PullBufferDataSource#getStreams()}. Delegates to the - * wrapped CaptureDevice if it implements - * PullBufferDataSource; otherwise, returns an empty array with - * PullBufferStream element type. - * - * @return an array of PullBufferStreams as returned by the wrapped - * CaptureDevice if it implements PullBufferDataSource; - * otherwise, an empty array with PullBufferStream element type - */ - @Override - public PullBufferStream[] getStreams() - { - if (captureDevice instanceof PullBufferDataSource) - return ((PullBufferDataSource) captureDevice).getStreams(); - return EMPTY_STREAMS; - } - - /** - * Implements {@link DataSource#getContentType()}. Delegates to the wrapped - * CaptureDevice if it implements DataSource; otherwise, - * returns {@link ContentDescriptor#CONTENT_UNKNOWN}. - * - * @return a String value which describes the content type of the - * wrapped CaptureDevice if it implements DataSource; - * otherwise, ContentDescriptor#CONTENT_UNKNOWN - */ - @Override - public String getContentType() - { - if (captureDevice instanceof DataSource) - return ((DataSource) captureDevice).getContentType(); - return ContentDescriptor.CONTENT_UNKNOWN; - } - - /** - * Implements {@link CaptureDevice#connect()}. Delegates to the wrapped - * CaptureDevice if available; otherwise, does nothing. - * - * @throws IOException if the wrapped CaptureDevice throws such an - * exception - */ - @Override - public void connect() - throws IOException - { - if (captureDevice != null) - captureDevice.connect(); - } - - /** - * Implements {@link CaptureDevice#disconnect()}. Delegates to the wrapped - * CaptureDevice if available; otherwise, does nothing. - */ - @Override - public void disconnect() - { - if (captureDevice != null) - captureDevice.disconnect(); - } - - /** - * Implements {@link CaptureDevice#start()}. Delegates to the wrapped - * CaptureDevice if available; otherwise, does nothing. - * - * @throws IOException if the wrapped CaptureDevice throws such an - * exception - */ - @Override - public void start() - throws IOException - { - if (captureDevice != null) - captureDevice.start(); - } - - /** - * Implements {@link CaptureDevice#start()}. Delegates to the wrapped - * CaptureDevice if available; otherwise, does nothing. - * - * @throws IOException if the wrapped CaptureDevice throws such an - * exception - */ - @Override - public void stop() - throws IOException - { - if (captureDevice != null) - captureDevice.stop(); - } - - /** - * Implements {@link DataSource#getControl(String)}. Delegates to the - * wrapped CaptureDevice if it implements DataSource; - * otherwise, returns null. - * - * @param controlType a String value which names the type of the - * control to be retrieved - * @return an Object which represents the control of the requested - * controlType of the wrapped CaptureDevice if it - * implements DataSource; otherwise, null - */ - @Override - public Object getControl(String controlType) - { - if (captureDevice instanceof DataSource) - return ((DataSource) captureDevice).getControl(controlType); - return null; - } - - /** - * Implements {@link DataSource#getControls()}. Delegates to the wrapped - * CaptureDevice if it implements DataSource; otherwise, - * returns an empty array with Object element type. - * - * @return the array of controls for the wrapped CaptureDevice if - * it implements DataSource; otherwise, an empty array with - * Object element type - */ - @Override - public Object[] getControls() - { - if (captureDevice instanceof DataSource) - return ((DataSource) captureDevice).getControls(); - return ControlsAdapter.EMPTY_CONTROLS; - } - - /** - * Implements {@link DataSource#getDuration()}. Delegates to the wrapped - * CaptureDevice if it implements DataSource; otherwise, - * returns {@link DataSource#DURATION_UNKNOWN}. - * - * @return the duration of the wrapped CaptureDevice as returned by - * its implementation of DataSource if any; otherwise, returns - * DataSource#DURATION_UNKNOWN - */ - @Override - public Time getDuration() - { - if (captureDevice instanceof DataSource) - return ((DataSource) captureDevice).getDuration(); - return DataSource.DURATION_UNKNOWN; - } - - /** - * Implements {@link CaptureDevice#getFormatControls()}. Delegates to the - * wrapped CaptureDevice if available; otherwise, returns an empty - * array with FormatControl element type. - * - * @return the array of FormatControls of the wrapped - * CaptureDevice if available; otherwise, an empty array with - * FormatControl element type - */ - public FormatControl[] getFormatControls() - { - return - (captureDevice != null) - ? captureDevice.getFormatControls() - : new FormatControl[0]; - } - - - /** - * Implements {@link CaptureDevice#getCaptureDeviceInfo()}. Delegates to the - * wrapped CaptureDevice if available; otherwise, returns - * null. - * - * @return the CaptureDeviceInfo of the wrapped - * CaptureDevice if available; otherwise, null - */ - public CaptureDeviceInfo getCaptureDeviceInfo() - { - return - (captureDevice != null) - ? captureDevice.getCaptureDeviceInfo() - : null; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/protocol/CaptureDeviceDelegatePushBufferDataSource.java b/src/net/java/sip/communicator/impl/neomedia/protocol/CaptureDeviceDelegatePushBufferDataSource.java deleted file mode 100644 index 73edab69d..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/protocol/CaptureDeviceDelegatePushBufferDataSource.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.protocol; - -import java.io.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.control.*; - -/** - * Represents a PushBufferDataSource which is also a - * CaptureDevice through delegation to a specific - * CaptureDevice. - * - * @author Lubomir Marinov - */ -public class CaptureDeviceDelegatePushBufferDataSource - extends PushBufferDataSource - implements CaptureDevice -{ - - /** - * The constant which represents an empty array with - * PushBufferStream element type. Explicitly defined in order to - * reduce unnecessary allocations. - */ - protected static final PushBufferStream[] EMPTY_STREAMS - = new PushBufferStream[0]; - - /** - * The CaptureDevice this instance delegates to in order to - * implement its CaptureDevice functionality. - */ - protected final CaptureDevice captureDevice; - - /** - * Initializes a new CaptureDeviceDelegatePushBufferDataSource - * instance which delegates to a specific CaptureDevice in order to - * implement its CaptureDevice functionality. - * - * @param captureDevice the CaptureDevice the new instance is to - * delegate to in order to provide its CaptureDevice functionality - */ - public CaptureDeviceDelegatePushBufferDataSource( - CaptureDevice captureDevice) - { - this.captureDevice = captureDevice; - } - - /** - * Implements {@link CaptureDevice#connect()}. Delegates to the wrapped - * CaptureDevice if available; otherwise, does nothing. - * - * @throws IOException if the wrapped CaptureDevice throws such an - * exception - */ - public void connect() - throws IOException - { - if (captureDevice != null) - captureDevice.connect(); - } - - /** - * Implements {@link CaptureDevice#disconnect()}. Delegates to the wrapped - * CaptureDevice if available; otherwise, does nothing. - */ - public void disconnect() - { - if (captureDevice != null) - captureDevice.disconnect(); - } - - /** - * Implements {@link CaptureDevice#getCaptureDeviceInfo()}. Delegates to the - * wrapped CaptureDevice if available; otherwise, returns - * null. - * - * @return the CaptureDeviceInfo of the wrapped - * CaptureDevice if available; otherwise, null - */ - public CaptureDeviceInfo getCaptureDeviceInfo() - { - return - (captureDevice != null) - ? captureDevice.getCaptureDeviceInfo() - : null; - } - - /** - * Implements {@link DataSource#getContentType()}. Delegates to the wrapped - * CaptureDevice if it implements DataSource; otherwise, - * returns {@link ContentDescriptor#CONTENT_UNKNOWN}. - * - * @return a String value which describes the content type of the - * wrapped CaptureDevice if it implements DataSource; - * otherwise, ContentDescriptor#CONTENT_UNKNOWN - */ - public String getContentType() - { - if (captureDevice instanceof DataSource) - return ((DataSource) captureDevice).getContentType(); - return ContentDescriptor.CONTENT_UNKNOWN; - } - - /** - * Implements {@link DataSource#getControl(String)}. Delegates to the - * wrapped CaptureDevice if it implements DataSource; - * otherwise, returns null. - * - * @param controlType a String value which names the type of the - * control to be retrieved - * @return an Object which represents the control of the requested - * controlType of the wrapped CaptureDevice if it - * implements DataSource; otherwise, null - */ - public Object getControl(String controlType) - { - if (captureDevice instanceof DataSource) - return ((DataSource) captureDevice).getControl(controlType); - return null; - } - - /** - * Implements {@link DataSource#getControls()}. Delegates to the wrapped - * CaptureDevice if it implements DataSource; otherwise, - * returns an empty array with Object element type. - * - * @return the array of controls for the wrapped CaptureDevice if - * it implements DataSource; otherwise, an empty array with - * Object element type - */ - public Object[] getControls() - { - if (captureDevice instanceof DataSource) - return ((DataSource) captureDevice).getControls(); - return ControlsAdapter.EMPTY_CONTROLS; - } - - /** - * Implements {@link DataSource#getDuration()}. Delegates to the wrapped - * CaptureDevice if it implements DataSource; otherwise, - * returns {@link DataSource#DURATION_UNKNOWN}. - * - * @return the duration of the wrapped CaptureDevice as returned by - * its implementation of DataSource if any; otherwise, returns - * DataSource#DURATION_UNKNOWN - */ - public Time getDuration() - { - if (captureDevice instanceof DataSource) - return ((DataSource) captureDevice).getDuration(); - return DataSource.DURATION_UNKNOWN; - } - - /** - * Implements {@link CaptureDevice#getFormatControls()}. Delegates to the - * wrapped CaptureDevice if available; otherwise, returns an empty - * array with FormatControl element type. - * - * @return the array of FormatControls of the wrapped - * CaptureDevice if available; otherwise, an empty array with - * FormatControl element type - */ - public FormatControl[] getFormatControls() - { - return - (captureDevice != null) - ? captureDevice.getFormatControls() - : new FormatControl[0]; - } - - /** - * Implements {@link PushBufferDataSource#getStreams()}. Delegates to the - * wrapped CaptureDevice if it implements - * PushBufferDataSource; otherwise, returns an empty array with - * PushBufferStream element type. - * - * @return an array of PushBufferStreams as returned by the wrapped - * CaptureDevice if it implements PushBufferDataSource; - * otherwise, an empty array with PushBufferStream element type - */ - public PushBufferStream[] getStreams() - { - if (captureDevice instanceof PushBufferDataSource) - return ((PushBufferDataSource) captureDevice).getStreams(); - return EMPTY_STREAMS; - } - - /** - * Implements {@link CaptureDevice#start()}. Delegates to the wrapped - * CaptureDevice if available; otherwise, does nothing. - * - * @throws IOException if the wrapped CaptureDevice throws such an - * exception - */ - public void start() - throws IOException - { - if (captureDevice != null) - captureDevice.start(); - } - - /** - * Implements {@link CaptureDevice#stop()}. Delegates to the wrapped - * CaptureDevice if available; otherwise, does nothing. - * - * @throws IOException if the wrapped CaptureDevice throws such an - * exception - */ - public void stop() - throws IOException - { - if (captureDevice != null) - captureDevice.stop(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/protocol/InbandDTMFDataSource.java b/src/net/java/sip/communicator/impl/neomedia/protocol/InbandDTMFDataSource.java deleted file mode 100644 index ae0f08cb1..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/protocol/InbandDTMFDataSource.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.protocol; - -import net.java.sip.communicator.service.neomedia.*; - -/** - * All datasources that support inband DTMF functionalities implement - * InbandDTMFDataSource. - * - * @author Vincent Lucas - */ -public interface InbandDTMFDataSource -{ - /** - * Adds a new inband DTMF tone to send. - * - * @param tone the DTMF tone to send. - */ - public void addDTMF(DTMFInbandTone tone); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/protocol/MuteDataSource.java b/src/net/java/sip/communicator/impl/neomedia/protocol/MuteDataSource.java deleted file mode 100644 index 787d1253c..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/protocol/MuteDataSource.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.protocol; - -/** - * All datasources that support muting functionality implement - * MuteDataSource. - * - * @author Damian Minkov - */ -public interface MuteDataSource -{ - /** - * Determines whether this DataSource is mute. - * - * @return true if this DataSource is mute; otherwise, - * false - */ - public boolean isMute(); - - /** - * Sets the mute state of this DataSource. - * - * @param mute true to mute this DataSource; otherwise, - * false - */ - public void setMute(boolean mute); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/protocol/PullBufferDataSourceDelegate.java b/src/net/java/sip/communicator/impl/neomedia/protocol/PullBufferDataSourceDelegate.java deleted file mode 100644 index 8b0ee68e4..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/protocol/PullBufferDataSourceDelegate.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.protocol; - -import java.io.*; - -import javax.media.*; -import javax.media.protocol.*; - -/** - * Implements most of PullBufferDataSource for a particular - * DataSource and requires extenders to only implement - * {@link PullBufferDataSource#getStreams()}. Intended to allow easier - * overriding of the streams returned by a DataSource. - * - * @param the very type of DataSource to be wrapped in a - * PullBufferDataSourceDelegate - * - * @author Damian Minkov - */ -public abstract class PullBufferDataSourceDelegate - extends CaptureDeviceDelegatePullBufferDataSource -{ - /** - * The wrapped DataSource this instance delegates to. - */ - protected final T dataSource; - - /** - * Initializes a new PullBufferDataSourceDelegate which is to - * delegate to a specific DataSource. - * - * @param dataSource the DataSource the new instance is to delegate - * to - */ - public PullBufferDataSourceDelegate(T dataSource) - { - super( - (dataSource instanceof CaptureDevice) - ? (CaptureDevice) dataSource - : null); - - if (dataSource == null) - throw new NullPointerException("dataSource"); - - this.dataSource = dataSource; - } - - /** - * Implements {@link DataSource#connect()}. Delegates to the wrapped - * DataSource. Overrides - * {@link CaptureDeviceDelegatePullBufferDataSource#connect()} because the - * wrapped DataSource may not be a CaptureDevice yet it - * still needs to be connected. - * - * @throws IOException if the wrapped DataSource throws such an - * exception - */ - @Override - public void connect() - throws IOException - { - dataSource.connect(); - } - - /** - * Implements {@link DataSource#disconnect()}. Delegates to the wrapped - * DataSource. Overrides - * {@link CaptureDeviceDelegatePullBufferDataSource#disconnect()} because - * the wrapped DataSource may not be a CaptureDevice yet - * it still needs to be disconnected. - */ - @Override - public void disconnect() - { - dataSource.disconnect(); - } - - /** - * Implements {@link DataSource#getContentType()}. Delegates to the wrapped - * DataSource. Overrides - * {@link CaptureDeviceDelegatePullBufferDataSource#getContentType()} - * because the wrapped DataSource may not be a - * CaptureDevice yet it still needs to report the content type. - * - * @return a String value which describes the content type of the - * wrapped DataSource - */ - @Override - public String getContentType() - { - return dataSource.getContentType(); - } - - /** - * Implements {@link DataSource#getLocator()}. Delegates to the wrapped - * DataSource. - * - * @return a MediaLocator value which describes the locator of the - * wrapped DataSource - */ - @Override - public MediaLocator getLocator() - { - return dataSource.getLocator(); - } - - /** - * Implements {@link DataSource#getControl(String)}. Delegates to the - * wrapped DataSource. Overrides - * {@link CaptureDeviceDelegatePullBufferDataSource#getControl(String)} - * because the wrapped DataSource may not be a - * CaptureDevice yet it still needs to give access to the control. - * - * @param controlType a String value which names the type of the - * control to be retrieved - * @return an Object which represents the control of the requested - * controlType of the wrapped DataSource - */ - @Override - public Object getControl(String controlType) - { - return dataSource.getControl(controlType); - } - - /** - * Implements {@link DataSource#getControls()}. Delegates to the wrapped - * PullBufferDataSource. Overrides - * {@link CaptureDeviceDelegatePullBufferDataSource#getControls()} because - * the wrapped DataSource may not be a CaptureDevice yet - * it still needs to give access to the controls. - * - * @return an array of Objects which represent the controls of the - * wrapped DataSource - */ - @Override - public Object[] getControls() - { - return dataSource.getControls(); - } - - /** - * Gets the DataSource wrapped by this instance. - * - * @return the DataSource wrapped by this instance - */ - public T getDataSource() - { - return dataSource; - } - - /** - * Implements {@link DataSource#getDuration()}. Delegates to the wrapped - * DataSource. Overrides - * {@link CaptureDeviceDelegatePullBufferDataSource#getDuration()} because - * the wrapped DataSource may not be a CaptureDevice yet - * it still needs to report the duration. - * - * @return the duration of the wrapped DataSource - */ - @Override - public Time getDuration() - { - return dataSource.getDuration(); - } - - /** - * Gets the PullBufferStreams through which this - * PullBufferDataSource gives access to its media data. - * - * @return an array of PullBufferStreams through which this - * PullBufferDataSource gives access to its media data - */ - @Override - public abstract PullBufferStream[] getStreams(); - - /** - * Implements {@link DataSource#start()}. Delegates to the wrapped - * DataSource. Overrides - * {@link CaptureDeviceDelegatePullBufferDataSource#start()} because the - * wrapped DataSource may not be a CaptureDevice yet it - * still needs to be started. - * - * @throws IOException if the wrapped DataSource throws such an - * exception - */ - @Override - public void start() - throws IOException - { - dataSource.start(); - } - - /** - * Implements {@link DataSource#stop()}. Delegates to the wrapped - * DataSource. Overrides - * {@link CaptureDeviceDelegatePullBufferDataSource#stop()} because the - * wrapped DataSource may not be a CaptureDevice yet it - * still needs to be stopped. - * - * @throws IOException if the wrapped DataSource throws such an - * exception - */ - @Override - public void stop() - throws IOException - { - dataSource.stop(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/protocol/PullBufferStreamAdapter.java b/src/net/java/sip/communicator/impl/neomedia/protocol/PullBufferStreamAdapter.java deleted file mode 100644 index f204e7401..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/protocol/PullBufferStreamAdapter.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.protocol; - -import java.io.*; - -import javax.media.*; -import javax.media.format.*; -import javax.media.protocol.*; - -/** - * Represents a PullBufferStream which reads its data from a - * specific PullSourceStream. - * - * @author Lubomir Marinov - */ -public class PullBufferStreamAdapter - extends BufferStreamAdapter - implements PullBufferStream -{ - - /** - * Initializes a new PullBufferStreamAdapter instance which - * reads its data from a specific PullSourceStream with a - * specific Format - * - * @param stream the PullSourceStream the new instance is to - * read its data from - * @param format the Format of the specified input - * stream and of the new instance - */ - public PullBufferStreamAdapter(PullSourceStream stream, Format format) - { - super(stream, format); - } - - /** - * Gets the frame size measured in bytes defined by a specific - * Format. - * - * @param format the Format to determine the frame size in - * bytes of - * @return the frame size measured in bytes defined by the specified - * Format - */ - private static int getFrameSizeInBytes(Format format) - { - AudioFormat audioFormat = (AudioFormat) format; - int frameSizeInBits = audioFormat.getFrameSizeInBits(); - - if (frameSizeInBits <= 0) - return - (audioFormat.getSampleSizeInBits() / 8) - * audioFormat.getChannels(); - return (frameSizeInBits <= 8) ? 1 : (frameSizeInBits / 8); - } - - /** - * Implements PullBufferStream#read(Buffer). Delegates to the wrapped - * PullSourceStream by either allocating a new byte[] buffer or using the - * existing one in the specified Buffer. - * - * @param buffer Buffer to read - * @throws IOException if I/O errors occurred during read operation - */ - public void read(Buffer buffer) - throws IOException - { - Object data = buffer.getData(); - byte[] bytes = null; - - if (data != null) - { - if (data instanceof byte[]) - bytes = (byte[]) data; - else if (data instanceof short[]) - { - short[] shorts = (short[]) data; - - bytes = new byte[2 * shorts.length]; - } - else if (data instanceof int[]) - { - int[] ints = (int[]) data; - - bytes = new byte[4 * ints.length]; - } - } - if (bytes == null) - { - int frameSizeInBytes = getFrameSizeInBytes(getFormat()); - - bytes - = new byte[ - 1024 * ((frameSizeInBytes <= 0) ? 4 : frameSizeInBytes)]; - } - - read(buffer, bytes); - } - - /** - * Implements BufferStreamAdapter#read(byte[], int, int). Delegates to the - * wrapped PullSourceStream. - * - * @param buffer byte array to read - * @param offset to start reading - * @param length length to read - * @return number of bytes read - * @throws IOException if I/O related errors occurred during read operation - */ - protected int read(byte[] buffer, int offset, int length) - throws IOException - { - return stream.read(buffer, offset, length); - } - - /** - * Implements PullBufferStream#willReadBlock(). Delegates to the wrapped - * PullSourceStream. - * - * @return true if this stream will block on read operation, false otherwise - */ - public boolean willReadBlock() - { - return stream.willReadBlock(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/protocol/PushBufferDataSourceAdapter.java b/src/net/java/sip/communicator/impl/neomedia/protocol/PushBufferDataSourceAdapter.java deleted file mode 100644 index 8fa2c8664..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/protocol/PushBufferDataSourceAdapter.java +++ /dev/null @@ -1,573 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.protocol; - -import java.io.*; -import java.util.*; - -import javax.media.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.util.*; - -/** - * Implements PushBufferDataSource for a specific - * PullBufferDataSource. - * - * @author Lubomir Marinov - */ -public class PushBufferDataSourceAdapter - extends PushBufferDataSourceDelegate -{ - - /** - * The Logger used by the PushBufferDataSourceAdapter - * class and its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(PushBufferDataSourceAdapter.class); - - /** - * The indicator which determines whether the - * PushBufferStreamAdapater instances should wait for their - * {@link PushBufferStreamAdapter#streamReadThread}s to exit before their - * {@link PushBufferStreamAdapter#stop()} returns. - */ - private static final boolean STRICT_STOP = false; - - /** - * The indicator which determines whether {@link #start()} has been called - * on this DataSource without a subsequent call to {@link #stop()}. - */ - private boolean started = false; - - /** - * The PushBufferStreams through which this - * PushBufferDataSource gives access to its media data. - */ - private final List streams - = new ArrayList(); - - /** - * Initializes a new PushBufferDataSourceAdapter which is to - * implement PushBufferDataSource capabilities for a specific - * PullBufferDataSource. - * - * @param dataSource the PullBufferDataSource the new instance is - * to implement PushBufferDataSource capabilities for - */ - public PushBufferDataSourceAdapter(PullBufferDataSource dataSource) - { - super(dataSource); - } - - /** - * Implements {@link DataSource#disconnect()}. Disposes of the - * PushBufferStreamAdapters which wrap the - * PullBufferStreams of the PullBufferDataSource wrapped - * by this instance. - */ - @Override - public void disconnect() - { - synchronized (streams) - { - Iterator streamIter = streams.iterator(); - - while (streamIter.hasNext()) - { - PushBufferStreamAdapter stream = streamIter.next(); - - streamIter.remove(); - stream.close(); - } - } - - super.disconnect(); - } - - /** - * Implements {@link DataSource#start()}. Starts the wrapped - * PullBufferDataSource and the pushing from the - * PushBufferStreamAdapters which wrap the - * PullBufferStreams of the PullBufferDataSource wrapped - * by this instance. - * - * @throws IOException if anything wrong happens while starting the wrapped - * PullBufferDataSource or the pushing from the - * PushBufferStreamAdapters which wrap the - * PullBufferStreams of the PullBufferDataSource wrapped - * by this instance - */ - @Override - public void start() - throws IOException - { - super.start(); - - synchronized (streams) - { - started = true; - - for (PushBufferStreamAdapter stream : streams) - stream.start(); - } - } - - /** - * Implements {@link DataSource#start()}. Stops the wrapped - * PullBufferDataSource and the pushing from the - * PushBufferStreamAdapters which wrap the - * PullBufferStreams of the PullBufferDataSource wrapped - * by this instance. - * - * @throws IOException if anything wrong happens while stopping the wrapped - * PullBufferDataSource or the pushing from the - * PushBufferStreamAdapters which wrap the - * PullBufferStreams of the PullBufferDataSource wrapped - * by this instance - */ - @Override - public void stop() - throws IOException - { - synchronized (streams) - { - started = false; - - for (PushBufferStreamAdapter stream : streams) - stream.stop(); - } - - super.stop(); - } - - /** - * Implements {@link PushBufferDataSource#getStreams()}. Gets the - * PushBufferStreams through which this - * PushBufferDataSource gives access to its media data. - * - * @return an array of PushBufferStreams through which this - * PushBufferDataSource gives access to its media data - */ - public PushBufferStream[] getStreams() - { - synchronized (streams) - { - PullBufferStream[] dataSourceStreams = dataSource.getStreams(); - int dataSourceStreamCount; - - /* - * I don't know whether dataSource returns a copy of its internal - * storage so I'm not sure if it's safe to modify dataSourceStreams. - */ - if (dataSourceStreams != null) - { - dataSourceStreams = dataSourceStreams.clone(); - dataSourceStreamCount = dataSourceStreams.length; - } - else - dataSourceStreamCount = 0; - - /* - * Dispose of the PushBufferStreamAdapters which adapt - * PullBufferStreams which are no longer returned by dataSource. - */ - Iterator streamIter = streams.iterator(); - - while (streamIter.hasNext()) - { - PushBufferStreamAdapter streamAdapter = streamIter.next(); - PullBufferStream stream = streamAdapter.stream; - boolean removeStream = true; - - for (int dataSourceStreamIndex = 0; - dataSourceStreamIndex < dataSourceStreamCount; - dataSourceStreamIndex++) - if (stream == dataSourceStreams[dataSourceStreamIndex]) - { - removeStream = false; - dataSourceStreams[dataSourceStreamIndex] = null; - break; - } - if (removeStream) - { - streamIter.remove(); - streamAdapter.close(); - } - } - - /* - * Create PushBufferStreamAdapters for the PullBufferStreams - * returned by dataSource which are not adapted yet. - */ - for (int dataSourceStreamIndex = 0; - dataSourceStreamIndex < dataSourceStreamCount; - dataSourceStreamIndex++) - { - PullBufferStream dataSourceStream - = dataSourceStreams[dataSourceStreamIndex]; - - if (dataSourceStream != null) - { - PushBufferStreamAdapter stream - = new PushBufferStreamAdapter(dataSourceStream); - - streams.add(stream); - if (started) - stream.start(); - } - } - - return streams.toArray(EMPTY_STREAMS); - } - } - - /** - * Implements PushBufferStream for a specific - * PullBufferStream. - */ - private static class PushBufferStreamAdapter - implements PushBufferStream - { - - /** - * The Buffer which contains the media data read by this - * instance from {@link #stream} and to be returned by this - * implementation of {@link PushBufferStream#read(Buffer)} by copying. - */ - private final Buffer buffer = new Buffer(); - - /** - * The indicator which determines whether {@link #buffer} contains media - * data read by this instance from {@link #stream} and not returned by - * this implementation of {@link PushBufferStream#read(Buffer)} yet. - */ - private boolean bufferIsWritten = false; - - /** - * The indicator which determined whether {@link #start()} has been - * called without a subsequent call to {@link #stop()}. - */ - private boolean started = false; - - /** - * The PullBufferStream to which this instance provides - * PushBufferStream capabilities. - */ - public final PullBufferStream stream; - - /** - * The IOException, if any, which has been thrown by the last - * call to {@link PullBufferStream#read(Buffer)} on {@link #stream} and - * which still hasn't been rethrown by this implementation of - * {@link PushBufferStream#read(Buffer)}. - */ - private IOException streamReadException; - - /** - * The Thread which currently reads media data from - * {@link #stream} into {@link #buffer}. - */ - private Thread streamReadThread; - - /** - * The Object which synchronizes the access to - * {@link #streamReadThread}-related members. - */ - private final Object streamReadThreadSyncRoot = new Object(); - - /** - * The BufferTransferHandler through which this - * PushBufferStream notifies its user that media data is - * available for reading. - */ - private BufferTransferHandler transferHandler; - - /** - * Initializes a new PushBufferStreamAdapter instance which is - * to implement PushBufferStream for a specific - * PullBufferStream. - * - * @param stream the PullBufferStream the new instance is to - * implement PushBufferStream for - */ - public PushBufferStreamAdapter(PullBufferStream stream) - { - if (stream == null) - throw new NullPointerException("stream"); - - this.stream = stream; - } - - /** - * Disposes of this PushBufferStreamAdapter. Afterwards, this - * instance is not guaranteed to be operation and considered to be - * available for garbage collection. - */ - void close() - { - stop(); - } - - /** - * Implements {@link SourceStream#endOfStream()}. Delegates to the - * wrapped PullBufferStream. - * - * @return true if the wrapped PullBufferStream has - * reached the end of the media data; otherwise, false - */ - public boolean endOfStream() - { - return stream.endOfStream(); - } - - /** - * Implements {@link SourceStream#getContentDescriptor()}. Delegates to - * the wrapped PullBufferStream. - * - * @return the ContentDescriptor of the wrapped - * PullBufferStream which describes the type of the media data - * it gives access to - */ - public ContentDescriptor getContentDescriptor() - { - return stream.getContentDescriptor(); - } - - /** - * Implements {@link SourceStream#getContentLength()}. Delegates to the - * wrapped PullBufferStream. - * - * @return the length of the content the wrapped - * PullBufferStream gives access to - */ - public long getContentLength() - { - return stream.getContentLength(); - } - - /** - * Implements {@link javax.media.Controls#getControl(String)}. Delegates - * to the wrapped PullBufferStream. - * - * @param controlType a String value which specifies the type - * of the control of the wrapped PullBufferStream to be - * retrieved - * @return an Object which represents the control of the - * wrapped PushBufferStream of the requested type if the - * wrapped PushBufferStream has such a control; null - * if the wrapped PushBufferStream does not have a control of - * the specified type - */ - public Object getControl(String controlType) - { - return stream.getControl(controlType); - } - - /** - * Implements {@link javax.media.Controls#getControls()}. Delegates to - * the wrapped PushBufferStream. - * - * @return an array of Objects which represent the controls - * available for the wrapped PushBufferStream - */ - public Object[] getControls() - { - return stream.getControls(); - } - - /** - * Implements {@link PushBufferStream#getFormat()}. Delegates to the - * wrapped PullBufferStream. - * - * @return the Format of the wrapped PullBufferStream - */ - public Format getFormat() - { - return stream.getFormat(); - } - - /** - * Implements {@link PushBufferStream#read(Buffer)}. - * - * @param buffer a Buffer in which media data is to be written - * by this PushBufferDataSource - * @throws IOException if anything wrong happens while reading media - * data from this PushBufferDataSource into the specified - * buffer - */ - public void read(Buffer buffer) - throws IOException - { - synchronized (this.buffer) - { - /* - * If stream has throw an exception during its last read, - * rethrow it as an exception of this stream. - */ - if (streamReadException != null) - { - IOException ie = new IOException(); - - ie.initCause(streamReadException); - streamReadException = null; - throw ie; - } - else if (bufferIsWritten) - { - buffer.copy(this.buffer); - bufferIsWritten = false; - } - else - buffer.setLength(0); - } - } - - /** - * Executes an iteration of {@link #streamReadThread} i.e. reads media - * data from {@link #stream} into {@link #buffer} and invokes - * {@link BufferTransferHandler#transferData(PushBufferStream)} on - * {@link #transferHandler} if any. - */ - private void runInStreamReadThread() - { - boolean bufferIsWritten; - - synchronized (buffer) - { - try - { - stream.read(buffer); - this.bufferIsWritten = !buffer.isDiscard(); - streamReadException = null; - } - catch (IOException ie) - { - this.bufferIsWritten = false; - streamReadException = ie; - } - bufferIsWritten = this.bufferIsWritten; - } - - if (bufferIsWritten) - { - BufferTransferHandler transferHandler = this.transferHandler; - - if (transferHandler != null) - transferHandler.transferData(this); - } - } - - /** - * Implements - * {@link PushBufferStream#setTransferHandler(BufferTransferHandler)}. - * Sets the means through which this PushBufferStream is to - * notify its user that media data is available for reading. - * - * @param transferHandler the BufferTransferHandler through - * which PushBufferStream is to notify its user that media data - * is available for reading - */ - public void setTransferHandler(BufferTransferHandler transferHandler) - { - if (this.transferHandler != transferHandler) - this.transferHandler = transferHandler; - } - - /** - * Starts the reading of media data of this - * PushBufferStreamAdapter from the wrapped - * PullBufferStream. - */ - void start() - { - synchronized (streamReadThreadSyncRoot) - { - PushBufferStreamAdapter.this.started = true; - - if (streamReadThread == null) - { - streamReadThread = new Thread() - { - @Override - public void run() - { - try - { - while (true) - { - synchronized (streamReadThreadSyncRoot) - { - if (!PushBufferStreamAdapter.this.started) - break; - if (streamReadThread - != Thread.currentThread()) - break; - } - runInStreamReadThread(); - } - } - finally - { - synchronized (streamReadThreadSyncRoot) - { - if (streamReadThread - == Thread.currentThread()) - { - streamReadThread = null; - streamReadThreadSyncRoot.notifyAll(); - } - } - } - } - }; - streamReadThread.setDaemon(true); - streamReadThread.start(); - } - } - } - - /** - * Stops the reading of media data of this - * PushBufferStreamAdapter from the wrapped - * PullBufferStream. - */ - void stop() - { - synchronized (streamReadThreadSyncRoot) - { - started = false; - if (STRICT_STOP) - { - boolean interrupted = false; - - while (streamReadThread != null) - try - { - streamReadThreadSyncRoot.wait(); - } - catch (InterruptedException iex) - { - logger - .info( - getClass().getSimpleName() - + " interrupted while waiting for" - + " PullBufferStream read thread" - + " to stop.", - iex); - interrupted = true; - } - if (interrupted) - Thread.currentThread().interrupt(); - } - else - streamReadThread = null; - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/protocol/PushBufferDataSourceDelegate.java b/src/net/java/sip/communicator/impl/neomedia/protocol/PushBufferDataSourceDelegate.java deleted file mode 100644 index cf0eb6cf8..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/protocol/PushBufferDataSourceDelegate.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.protocol; - -import java.io.*; - -import javax.media.*; -import javax.media.protocol.*; - -/** - * Implements most of PushBufferDataSource for a particular - * DataSource and requires extenders to only implement - * {@link PushBufferDataSource#getStreams()}. Intended to allow easier - * overriding of the streams returned by a DataSource. - * - * @param the very type of DataSource to be wrapped in a - * PushBufferDataSourceDelegate - * @author Lubomir Marinov - */ -public abstract class PushBufferDataSourceDelegate - extends CaptureDeviceDelegatePushBufferDataSource -{ - - /** - * The wrapped DataSource this instance delegates to. - */ - protected final T dataSource; - - /** - * Initializes a new PushBufferDataSourceDelegate which is to - * delegate to a specific DataSource. - * - * @param dataSource the DataSource the new instance is to delegate - * to - */ - public PushBufferDataSourceDelegate(T dataSource) - { - super( - (dataSource instanceof CaptureDevice) - ? (CaptureDevice) dataSource - : null); - - if (dataSource == null) - throw new NullPointerException("dataSource"); - - this.dataSource = dataSource; - } - - /** - * Implements {@link DataSource#connect()}. Delegates to the wrapped - * DataSource. Overrides - * {@link CaptureDeviceDelegatePushBufferDataSource#connect()} because the - * wrapped DataSource may not be a CaptureDevice yet it - * still needs to be connected. - * - * @throws IOException if the wrapped DataSource throws such an - * exception - */ - @Override - public void connect() - throws IOException - { - dataSource.connect(); - } - - /** - * Implements {@link DataSource#disconnect()}. Delegates to the wrapped - * DataSource. Overrides - * {@link CaptureDeviceDelegatePushBufferDataSource#disconnect()} because - * the wrapped DataSource may not be a CaptureDevice yet - * it still needs to be disconnected. - */ - @Override - public void disconnect() - { - dataSource.disconnect(); - } - - /** - * Implements {@link DataSource#getContentType()}. Delegates to the wrapped - * DataSource. Overrides - * {@link CaptureDeviceDelegatePushBufferDataSource#getContentType()} - * because the wrapped DataSource may not be a - * CaptureDevice yet it still needs to report the content type. - * - * @return a String value which describes the content type of the - * wrapped DataSource - */ - @Override - public String getContentType() - { - return dataSource.getContentType(); - } - - /** - * Implements {@link DataSource#getLocator()}. Delegates to the wrapped - * DataSource. - * - * @return a MediaLocator value which describes the locator of the - * wrapped DataSource - */ - @Override - public MediaLocator getLocator() - { - return dataSource.getLocator(); - } - - /** - * Implements {@link DataSource#getControl(String)}. Delegates to the - * wrapped DataSource. Overrides - * {@link CaptureDeviceDelegatePushBufferDataSource#getControl(String)} - * because the wrapped DataSource may not be a - * CaptureDevice yet it still needs to give access to the control. - * - * @param controlType a String value which names the type of the - * control to be retrieved - * @return an Object which represents the control of the requested - * controlType of the wrapped DataSource - */ - @Override - public Object getControl(String controlType) - { - return dataSource.getControl(controlType); - } - - /** - * Implements {@link DataSource#getControls()}. Delegates to the wrapped - * PushBufferDataSource. Overrides - * {@link CaptureDeviceDelegatePushBufferDataSource#getControls()} because - * the wrapped DataSource may not be a CaptureDevice yet - * it still needs to give access to the controls. - * - * @return an array of Objects which represent the controls of the - * wrapped DataSource - */ - @Override - public Object[] getControls() - { - return dataSource.getControls(); - } - - /** - * Gets the DataSource wrapped by this instance. - * - * @return the DataSource wrapped by this instance - */ - public T getDataSource() - { - return dataSource; - } - - /** - * Implements {@link DataSource#getDuration()}. Delegates to the wrapped - * DataSource. Overrides - * {@link CaptureDeviceDelegatePushBufferDataSource#getDuration()} because - * the wrapped DataSource may not be a CaptureDevice yet - * it still needs to report the duration. - * - * @return the duration of the wrapped DataSource - */ - @Override - public Time getDuration() - { - return dataSource.getDuration(); - } - - /** - * Gets the PushBufferStreams through which this - * PushBufferDataSource gives access to its media data. - * - * @return an array of PushBufferStreams through which this - * PushBufferDataSource gives access to its media data - */ - @Override - public abstract PushBufferStream[] getStreams(); - - /** - * Implements {@link DataSource#start()}. Delegates to the wrapped - * DataSource. Overrides - * {@link CaptureDeviceDelegatePushBufferDataSource#start()} because the - * wrapped DataSource may not be a CaptureDevice yet it - * still needs to be started. - * - * @throws IOException if the wrapped DataSource throws such an - * exception - */ - @Override - public void start() - throws IOException - { - dataSource.start(); - } - - /** - * Implements {@link DataSource#stop()}. Delegates to the wrapped - * DataSource. Overrides - * {@link CaptureDeviceDelegatePushBufferDataSource#stop()} because the - * wrapped DataSource may not be a CaptureDevice yet it - * still needs to be stopped. - * - * @throws IOException if the wrapped DataSource throws such an - * exception - */ - @Override - public void stop() - throws IOException - { - dataSource.stop(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/protocol/PushBufferStreamAdapter.java b/src/net/java/sip/communicator/impl/neomedia/protocol/PushBufferStreamAdapter.java deleted file mode 100644 index fbdc2dadf..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/protocol/PushBufferStreamAdapter.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.protocol; - -import java.io.*; - -import javax.media.*; -import javax.media.protocol.*; - -/** - * Represents a PushBufferStream which reads its data from a - * specific PushSourceStream. - * - * @author Lubomir Marinov - */ -public class PushBufferStreamAdapter - extends BufferStreamAdapter - implements PushBufferStream -{ - - /** - * Initializes a new PushBufferStreamAdapter instance which - * reads its data from a specific PushSourceStream with a - * specific Format - * - * @param stream the PushSourceStream the new instance is to - * read its data from - * @param format the Format of the specified input - * stream and of the new instance - */ - public PushBufferStreamAdapter(PushSourceStream stream, Format format) - { - super(stream, format); - } - - /** - * Implements PushBufferStream#read(Buffer). Delegates to the wrapped - * PushSourceStream by allocating a new byte[] buffer of size equal to - * PushSourceStream#getMinimumTransferSize(). - * - * @param buffer the Buffer to read - * @throws IOException if I/O related errors occurred during read operation - */ - public void read(Buffer buffer) - throws IOException - { - read(buffer, new byte[stream.getMinimumTransferSize()]); - } - - /** - * Implements BufferStreamAdapter#read(byte[], int, int). Delegates to the - * wrapped PushSourceStream. - * - * @param buffer byte array to read - * @param offset offset to start reading - * @param length length to read - * @return number of bytes read - * @throws IOException if I/O related errors occurred during read operation - */ - protected int read(byte[] buffer, int offset, int length) - throws IOException - { - return stream.read(buffer, offset, length); - } - - /** - * Implements PushBufferStream#setTransferHandler(BufferTransferHandler). - * Delegates to the wrapped PushSourceStream by translating the specified - * BufferTransferHandler to a SourceTransferHandler. - * - * @param transferHandler a BufferTransferHandler to set - */ - public void setTransferHandler(final BufferTransferHandler transferHandler) - { - stream.setTransferHandler(new SourceTransferHandler() - { - public void transferData(PushSourceStream stream) { - transferHandler.transferData(PushBufferStreamAdapter.this); - } - }); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/protocol/RewritablePullBufferDataSource.java b/src/net/java/sip/communicator/impl/neomedia/protocol/RewritablePullBufferDataSource.java deleted file mode 100644 index a5ac6cf81..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/protocol/RewritablePullBufferDataSource.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.protocol; - -import java.io.*; -import java.util.*; - -import javax.media.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.service.neomedia.*; - -/** - * Implements a PullBufferDataSource wrapper which provides mute - * support for the wrapped instance. - *

- * Because the class wouldn't work for our use case without it, - * CaptureDevice is implemented and is being delegated to the wrapped - * DataSource (if it supports the interface in question). - *

- * - * @author Damian Minkov - * @author Lubomir Marinov - */ -public class RewritablePullBufferDataSource - extends PullBufferDataSourceDelegate - implements MuteDataSource, - InbandDTMFDataSource -{ - /** - * The indicator which determines whether this DataSource is mute. - */ - private boolean mute; - - /** - * The tones to send via inband DTMF, if not empty. - */ - private LinkedList tones = new LinkedList(); - - /** - * Initializes a new RewritablePullBufferDataSource instance which - * is to provide mute support for a specific PullBufferDataSource. - * - * @param dataSource the PullBufferDataSource the new instance is - * to provide mute support for - */ - public RewritablePullBufferDataSource(PullBufferDataSource dataSource) - { - super(dataSource); - } - - /** - * Sets the mute state of this DataSource. - * - * @param mute true to mute this DataSource; otherwise, - * false - */ - public void setMute(boolean mute) - { - this.mute = mute; - } - - /** - * Determines whether this DataSource is mute. - * - * @return true if this DataSource is mute; otherwise, - * false - */ - public boolean isMute() - { - return mute; - } - - /** - * Adds a new inband DTMF tone to send. - * - * @param tone the DTMF tone to send. - */ - public void addDTMF(DTMFInbandTone tone) - { - this.tones.add(tone); - } - - /** - * Determines whether this DataSource sends a DTMF tone. - * - * @return true if this DataSource is sending a DTMF tone; - * otherwise, false. - */ - public boolean isSendingDTMF() - { - return !this.tones.isEmpty(); - } - - /** - * Get wrapped DataSource. - * - * @return wrapped DataSource - */ - public PullBufferDataSource getWrappedDataSource() - { - return dataSource; - } - - /** - * Implements {@link PullBufferDataSource#getStreams()}. Wraps the streams - * of the wrapped PullBufferDataSource into - * MutePullBufferStream instances in order to provide mute support - * to them. - * - * @return an array of PullBufferStream instances with enabled mute - * support - */ - public PullBufferStream[] getStreams() - { - PullBufferStream[] streams = dataSource.getStreams(); - - if (streams != null) - for (int streamIndex = 0; streamIndex < streams.length; streamIndex++) - streams[streamIndex] = - new MutePullBufferStream(streams[streamIndex]); - return streams; - } - - /** - * Implements a PullBufferStream wrapper which provides mute - * support for the wrapped instance. - */ - private class MutePullBufferStream - extends SourceStreamDelegate - implements PullBufferStream - { - - /** - * Initializes a new MutePullBufferStream instance which is to - * provide mute support for a specific PullBufferStream. - * - * @param stream the PullBufferStream the new instance is to - * provide mute support for - */ - private MutePullBufferStream(PullBufferStream stream) - { - super(stream); - } - - /** - * Implements {@link PullBufferStream#getFormat()}. Delegates to the - * wrapped PullBufferStream. - * - * @return the Format of the wrapped PullBufferStream - */ - public Format getFormat() - { - return stream.getFormat(); - } - - /** - * Implements PullBufferStream#read(Buffer). If this instance is muted - * (through its owning RewritablePullBufferDataSource), overwrites the - * data read from the wrapped PullBufferStream with silence data. - * @param buffer which data will be filled. @throws IOException Thrown - * if an error occurs while reading. - */ - public void read(Buffer buffer) - throws IOException - { - stream.read(buffer); - - if (isSendingDTMF()) - { - RewritablePushBufferDataSource.sendDTMF(buffer, tones.poll()); - } - else if (isMute()) - { - RewritablePushBufferDataSource.mute(buffer); - } - } - - /** - * Implements PullBufferStream#willReadBlock(). Delegates to the wrapped - * PullSourceStream. - * @return true if read would block; otherwise returns - * false. - */ - public boolean willReadBlock() - { - return stream.willReadBlock(); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/protocol/RewritablePushBufferDataSource.java b/src/net/java/sip/communicator/impl/neomedia/protocol/RewritablePushBufferDataSource.java deleted file mode 100644 index a78d31d32..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/protocol/RewritablePushBufferDataSource.java +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.protocol; - -import java.io.*; -import java.nio.ByteBuffer; // disambiguation. -import java.nio.ByteOrder; // disambiguation. -import java.nio.IntBuffer; // disambiguation. -import java.util.*; - -import javax.media.*; -import javax.media.format.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.service.neomedia.*; - -/** - * Implements a PushBufferDataSource wrapper which provides mute - * support for the wrapped instance. - *

- * Because the class wouldn't work for our use case without it, - * CaptureDevice is implemented and is being delegated to the wrapped - * DataSource (if it supports the interface in question). - *

- * - * @author Lyubomir Marinov - */ -public class RewritablePushBufferDataSource - extends PushBufferDataSourceDelegate - implements MuteDataSource, - InbandDTMFDataSource -{ - - /** - * The indicator which determines whether this DataSource is mute. - */ - private boolean mute; - - /** - * The tones to send via inband DTMF, if not empty. - */ - private LinkedList tones = new LinkedList(); - - /** - * Initializes a new RewritablePushBufferDataSource instance which - * is to provide mute support for a specific PushBufferDataSource. - * - * @param dataSource the PushBufferDataSource the new instance is - * to provide mute support for - */ - public RewritablePushBufferDataSource(PushBufferDataSource dataSource) - { - super(dataSource); - } - - /** - * Implements {@link PushBufferDataSource#getStreams()}. Wraps the streams - * of the wrapped PushBufferDataSource into - * MutePushBufferStream instances in order to provide mute support - * to them. - * - * @return an array of PushBufferStream instances with enabled mute - * support - */ - public PushBufferStream[] getStreams() - { - PushBufferStream[] streams = dataSource.getStreams(); - - if (streams != null) - { - for (int streamIndex = 0; - streamIndex < streams.length; - streamIndex++) - { - PushBufferStream stream = streams[streamIndex]; - - if (stream != null) - streams[streamIndex] = new MutePushBufferStream(stream); - } - } - return streams; - } - - /** - * Determines whether this DataSource is mute. - * - * @return true if this DataSource is mute; otherwise, - * false - */ - public synchronized boolean isMute() - { - return mute; - } - - /** - * Replaces the media data contained in a specific Buffer with a - * compatible representation of silence. - * - * @param buffer the Buffer the data contained in which is to be - * replaced with silence - */ - public static void mute(Buffer buffer) - { - Object data = buffer.getData(); - - if (data != null) - { - Class dataClass = data.getClass(); - final int fromIndex = buffer.getOffset(); - final int toIndex = fromIndex + buffer.getLength(); - - if (Format.byteArray.equals(dataClass)) - Arrays.fill((byte[]) data, fromIndex, toIndex, (byte) 0); - else if (Format.intArray.equals(dataClass)) - Arrays.fill((int[]) data, fromIndex, toIndex, 0); - else if (Format.shortArray.equals(dataClass)) - Arrays.fill((short[]) data, fromIndex, toIndex, (short) 0); - - buffer.setData(data); - } - } - - /** - * Sets the mute state of this DataSource. - * - * @param mute true to mute this DataSource; otherwise, - * false - */ - public synchronized void setMute(boolean mute) - { - this.mute = mute; - } - - /** - * Adds a new inband DTMF tone to send. - * - * @param tone the DTMF tone to send. - */ - public void addDTMF(DTMFInbandTone tone) - { - this.tones.add(tone); - } - - /** - * Determines whether this DataSource sends a DTMF tone. - * - * @return true if this DataSource is sending a DTMF tone; - * otherwise, false. - */ - public boolean isSendingDTMF() - { - return !this.tones.isEmpty(); - } - - /** - * Replaces the media data contained in a specific Buffer with an - * inband DTMF tone signal. - * - * @param buffer the Buffer the data contained in which is to be - * replaced with the DTMF tone - * @param tone the DMFTTone to send via inband DTMF signal. - */ - public static void sendDTMF( - Buffer buffer, - DTMFInbandTone tone) - { - Object data = buffer.getData(); - - // Send the inband DTMF tone only if the buffer contains audio data. - if (data != null && (buffer.getFormat() instanceof AudioFormat)) - { - Class dataClass = data.getClass(); - int fromIndex = buffer.getOffset(); - - AudioFormat audioFormat = (AudioFormat) buffer.getFormat(); - double samplingFrequency = audioFormat.getSampleRate(); - int sampleSizeInBits = audioFormat.getSampleSizeInBits(); - - // Generates the inband DTMF signal. - int[] sampleData = tone.getAudioSamples( - samplingFrequency, - sampleSizeInBits); - IntBuffer.wrap(sampleData); - - int toIndex = fromIndex + - sampleData.length * (sampleSizeInBits / 8); - ByteBuffer newData = ByteBuffer.allocate(toIndex); - - // Prepares newData to be endian compliant with original buffer - // data. - if(audioFormat.getEndian() == AudioFormat.BIG_ENDIAN) - { - newData.order(ByteOrder.BIG_ENDIAN); - } - else - { - newData.order(ByteOrder.LITTLE_ENDIAN); - } - - // Keeps data unchanged if storeed before the original buffer offset - // index. - // Takes care of original data array type (byte, short or int). - if (Format.byteArray.equals(dataClass)) - { - newData.put(((byte[]) data), 0, fromIndex); - } - else if (Format.shortArray.equals(dataClass)) - { - for(int i = 0; i < fromIndex; ++i) - { - newData.putShort(((short[]) data)[i]); - } - } - else if (Format.intArray.equals(dataClass)) - { - for(int i = 0; i < fromIndex; ++i) - { - newData.putInt(((int[]) data)[i]); - } - } - - // Copies inband DTMF singal into newData. - // Takes care of audio format encryption data type (byte, short or - // int). - switch (sampleSizeInBits) - { - case 8: - for(int i = 0; i < sampleData.length; ++i) - { - newData.put(((byte) sampleData[i])); - } - break; - case 16: - for(int i = 0; i < sampleData.length; ++i) - { - newData.putShort(((short) sampleData[i])); - } - break; - case 32: - for(int i = 0; i < sampleData.length; ++i) - { - newData.putInt(sampleData[i]); - } - break; - } - - // Copies newData up to date into the original buffer. - // Takes care of original data array type (byte, short or int). - if (Format.byteArray.equals(dataClass)) - { - buffer.setData(newData.array()); - } - else if (Format.shortArray.equals(dataClass)) - { - buffer.setData(newData.asShortBuffer().array()); - } - else if (Format.intArray.equals(dataClass)) - { - buffer.setData(newData.asIntBuffer().array()); - } - - // Updates the buffer length. - buffer.setLength(toIndex - fromIndex); - } - } - - /** - * Implements a PushBufferStream wrapper which provides mute - * support for the wrapped instance. - */ - private class MutePushBufferStream - extends SourceStreamDelegate - implements PushBufferStream - { - - /** - * Initializes a new MutePushBufferStream instance which is to - * provide mute support to a specific PushBufferStream. - * - * @param stream the PushBufferStream the new instance is to - * provide mute support to - */ - public MutePushBufferStream(PushBufferStream stream) - { - super(stream); - } - - /** - * Implements {@link PushBufferStream#getFormat()}. Delegates to the - * wrapped PushBufferStream. - * - * @return the Format of the wrapped PushBufferStream - */ - public Format getFormat() - { - return stream.getFormat(); - } - - /** - * Implements {@link PushBufferStream#read(Buffer)}. If this instance is - * muted (through its owning RewritablePushBufferDataSource), - * overwrites the data read from the wrapped PushBufferStream - * with silence data. - * - * @param buffer a Buffer in which the read data is to be - * returned to the caller - * @throws IOException if reading from the wrapped - * PushBufferStream fails - */ - public void read(Buffer buffer) - throws IOException - { - stream.read(buffer); - - if (isSendingDTMF()) - { - sendDTMF(buffer, tones.poll()); - } - else if (isMute()) - { - mute(buffer); - } - } - - /** - * Implements - * {@link PushBufferStream#setTransferHandler(BufferTransferHandler)}. - * Sets up the hiding of the wrapped PushBufferStream from the - * specified transferHandler and thus gives this - * MutePushBufferStream full control when the - * transferHandler in question starts calling to the stream - * given to it in - * BufferTransferHandler#transferData(PushBufferStream). - * - * @param transferHandler a BufferTransferHandler to be - * notified by this instance when data is available for reading from it - */ - public void setTransferHandler(BufferTransferHandler transferHandler) - { - stream.setTransferHandler( - (transferHandler == null) - ? null - : new StreamSubstituteBufferTransferHandler( - transferHandler, - stream, - this)); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/protocol/SourceStreamDelegate.java b/src/net/java/sip/communicator/impl/neomedia/protocol/SourceStreamDelegate.java deleted file mode 100644 index add34a47b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/protocol/SourceStreamDelegate.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.protocol; - -import javax.media.protocol.*; - -/** - * Implements a SourceStream which wraps a specific - * SourceStream. - * - * @param the very type of the SourceStream wrapped by - * SourceStreamDelegate - * - * @author Lyubomir Marinov - */ -public class SourceStreamDelegate - implements SourceStream -{ - - /** - * The SourceStreamDelegate wrapped by this instance. - */ - protected final T stream; - - /** - * Initializes a new SourceStreamDelegate instance which is to - * wrap a specific SourceStream. - * - * @param stream the SourceStream the new instance is to - * wrap - */ - public SourceStreamDelegate(T stream) - { - this.stream = stream; - } - - /** - * Implements {@link SourceStream#endOfStream()}. Delegates to the wrapped - * SourceStream. - * - * @return true if the wrapped SourceStream has reached - * the end the content it makes available - */ - public boolean endOfStream() - { - return stream.endOfStream(); - } - - /** - * Implements {@link SourceStream#getContentDescriptor()}. Delegates to the - * wrapped SourceStream. - * - * @return a ContentDescriptor which describes the content made - * available by the wrapped SourceStream - */ - public ContentDescriptor getContentDescriptor() - { - return stream.getContentDescriptor(); - } - - /** - * Implements {@link SourceStream#getContentLength()}. Delegates to the - * wrapped SourceStream. - * - * @return the length of the content made available by the wrapped - * SourceStream - */ - public long getContentLength() - { - return stream.getContentLength(); - } - - /** - * Implements {@link Controls#getControl(String)}. Delegates to the wrapped - * SourceStream. - * - * @param controlType a String value which specifies the type of - * the control to be retrieved - * @return an Object which represents the control of the wrapped - * SourceStream of the specified type if such a control is - * available; otherwise, null - */ - public Object getControl(String controlType) - { - return stream.getControl(controlType); - } - - /** - * Implements {@link Controls#getControls()}. Delegates to the wrapped - * SourceStream. - * - * @return an array of Objects which represent the controls - * available for the wrapped SourceStream - */ - public Object[] getControls() - { - return stream.getControls(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/protocol/StreamSubstituteBufferTransferHandler.java b/src/net/java/sip/communicator/impl/neomedia/protocol/StreamSubstituteBufferTransferHandler.java deleted file mode 100644 index 5757a1529..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/protocol/StreamSubstituteBufferTransferHandler.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.protocol; - -import javax.media.protocol.*; - -/** - * Implements a BufferTransferHandler wrapper which doesn't - * expose a PushBufferStream but rather a specific substitute in order - * to give full control to the {@link PushBufferStream#read(javax.media.Buffer)} - * method of the substitute. - *

- * The purpose is achieved in #transferData(PushBufferStream) - * where the method argument stream is ignored and the substitute - * is used instead. - *

- * - * @author Lubomir Marinov - */ -public class StreamSubstituteBufferTransferHandler - implements BufferTransferHandler -{ - - /** - * The PushBufferStream to be overridden for - * transferHandler with the substitute of this - * instance. - */ - private final PushBufferStream stream; - - /** - * The PushBufferStream to override the stream of - * this instance for transferHandler. - */ - private final PushBufferStream substitute; - - /** - * The wrapped BufferTransferHandler which receives the - * actual events from the wrapped PushBufferStream. - */ - private final BufferTransferHandler transferHandler; - - /** - * Initializes a new StreamSubstituteBufferTransferHandler instance - * which is to overwrite the source PushBufferStream of a specific - * BufferTransferHandler. - * - * @param transferHandler the BufferTransferHandler the new - * instance is to overwrite the source PushBufferStream - * of - * @param stream the PushBufferStream to be overridden for the - * specified transferHandler with the specified - * substitute - * @param substitute the PushBufferStream to override the - * specified stream for the specified - * transferHandler - */ - public StreamSubstituteBufferTransferHandler( - BufferTransferHandler transferHandler, - PushBufferStream stream, - PushBufferStream substitute) - { - this.transferHandler = transferHandler; - this.stream = stream; - this.substitute = substitute; - } - - /** - * Implements BufferTransferHandler#transferData(PushBufferStream). Puts in - * place the essence of the StreamSubstituteBufferTransferHandler class - * which is to report to the transferHandler from the same PushBufferStream - * to which it was set so that the substitute can gain full control. - * - * @param stream the PushBufferStream to transfer - */ - public void transferData(PushBufferStream stream) - { - transferHandler.transferData( - (stream == this.stream) ? substitute : stream); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/protocol/TranscodingDataSource.java b/src/net/java/sip/communicator/impl/neomedia/protocol/TranscodingDataSource.java deleted file mode 100644 index db3240a52..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/protocol/TranscodingDataSource.java +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.protocol; - -import java.io.*; -import java.lang.reflect.*; - -import javax.media.*; -import javax.media.control.*; -import javax.media.format.*; -import javax.media.protocol.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.control.*; - -/** - * Represents a DataSource which transcodes the tracks of a specific - * input DataSource into a specific output Format. The - * transcoding is attempted only for tracks which actually support it for the - * specified output Format. - * - * @author Lubomir Marinov - */ -public class TranscodingDataSource - extends DataSource -{ - - /** - * The DataSource which has its tracks transcoded by this instance. - */ - private final DataSource inputDataSource; - - /** - * The DataSource which contains the transcoded tracks of - * inputDataSource and which is wrapped by this instance. It is the - * output of transcodingProcessor. - */ - private DataSource outputDataSource; - - /** - * The Format in which the tracks of inputDataSource are - * transcoded. - */ - private final Format outputFormat; - - /** - * The Processor which carries out the actual transcoding of the - * tracks of inputDataSource. - */ - private Processor transcodingProcessor; - - /** - * Initializes a new TranscodingDataSource instance to transcode - * the tracks of a specific DataSource into a specific output - * Format. - * - * @param inputDataSource the DataSource which is to have its - * tracks transcoded in a specific outptu Format - * @param outputFormat the Format in which the new instance is to - * transcode the tracks of inputDataSource - */ - public TranscodingDataSource( - DataSource inputDataSource, - Format outputFormat) - { - super(inputDataSource.getLocator()); - - this.inputDataSource = inputDataSource; - this.outputFormat = outputFormat; - } - - /** - * Implements {@link DataSource#connect()}. Sets up the very transcoding - * process and just does not start it i.e. creates a Processor on - * the inputDataSource, sets outputFormat on its tracks - * (which support a Format compatible with outputFormat) - * and connects to its output DataSource. - * - * @throws IOException if creating the transcoding Processor, - * setting its Format or connecting to it fails - */ - public synchronized void connect() - throws IOException - { - if (outputDataSource != null) - return; - - /* - * Manager#createProcessor(DataSource) requires the specified DataSource - * to be connected. - */ - inputDataSource.connect(); - - Processor processor; - - try - { - processor = Manager.createProcessor(inputDataSource); - } - catch (NoProcessorException npex) - { - IOException ioex = new IOException(); - ioex.initCause(npex); - throw ioex; - } - - ProcessorUtility processorUtility = new ProcessorUtility(); - - if (!processorUtility.waitForState(processor, Processor.Configured)) - throw new IOException("Couldn't configure transcoding processor."); - - TrackControl[] trackControls = processor.getTrackControls(); - - if (trackControls != null) - for (TrackControl trackControl : trackControls) - { - Format trackFormat = trackControl.getFormat(); - - /* - * XXX We only care about AudioFormat here and we assume - * outputFormat is of such type because it is in our current and - * only use case of TranscodingDataSource - */ - if ((trackFormat instanceof AudioFormat) - && !trackFormat.matches(outputFormat)) - { - Format[] supportedTrackFormats - = trackControl.getSupportedFormats(); - - if (supportedTrackFormats != null) - for (Format supportedTrackFormat - : supportedTrackFormats) - if (supportedTrackFormat.matches(outputFormat)) - { - Format intersectionFormat - = supportedTrackFormat.intersects( - outputFormat); - - if (intersectionFormat != null) - { - trackControl.setFormat(intersectionFormat); - break; - } - } - } - } - - if (!processorUtility.waitForState(processor, Processor.Realized)) - throw new IOException("Couldn't realize transcoding processor."); - - DataSource outputDataSource = processor.getDataOutput(); - - outputDataSource.connect(); - - transcodingProcessor = processor; - this.outputDataSource = outputDataSource; - } - - /** - * Implements {@link DataSource#disconnect()}. Stops and undoes the whole - * setup of the very transcoding process i.e. disconnects from the output - * DataSource of the transcodingProcessor and disposes of the - * transcodingProcessor. - */ - public synchronized void disconnect() - { - if (outputDataSource == null) - return; - - try - { - stop(); - } - catch (IOException ioex) - { - throw new UndeclaredThrowableException(ioex); - } - - outputDataSource.disconnect(); - - transcodingProcessor.deallocate(); - transcodingProcessor.close(); - transcodingProcessor = null; - - outputDataSource = null; - } - - /** - * Implements {@link DataSource#getContentType()}. Delegates to the actual - * output of the transcoding. - * - * @return a String value which describes the type of the content - * made available by this DataSource - */ - public synchronized String getContentType() - { - return - (outputDataSource == null) - ? null - : outputDataSource.getContentType(); - } - - /** - * Implements {@link DataSource#getControl(String)}. Delegates to the actual - * output of the transcoding. - * - * @param controlType a String value which names the type of the - * control to be retrieved - * @return an Object which represents the control of this instance - * with the specified type if such a control is available; otherwise, - * null - */ - public synchronized Object getControl(String controlType) - { - /* - * The Javadoc of DataSource#getControl(String) says it's an error to - * call the method without being connected and by that time we should - * have the outputDataSource. - */ - return outputDataSource.getControl(controlType); - } - - /** - * Implements {@link DataSource#getControls()}. Delegates to the actual - * output of the transcoding. - * - * @return an array of Objects which represent the controls - * available for this instance - */ - public synchronized Object[] getControls() - { - return - (outputDataSource == null) - ? ControlsAdapter.EMPTY_CONTROLS - : outputDataSource.getControls(); - } - - /** - * Implements {@link DataSource#getDuration()}. Delegates to the actual - * output of the transcoding. - * - * @return a Time value which describes the duration of the content - * made available by this instance - */ - public synchronized Time getDuration() - { - return - (outputDataSource == null) - ? DURATION_UNKNOWN - : outputDataSource.getDuration(); - } - - /** - * Gets the output streams that this instance provides. Some of them may be - * the result of transcoding the tracks of the input DataSource of - * this instance in the output Format of this instance. - * - * @return an array of SourceStreams which represents the - * collection of output streams that this instance provides - */ - public synchronized SourceStream[] getStreams() - { - if (outputDataSource instanceof PushBufferDataSource) - return ((PushBufferDataSource) outputDataSource).getStreams(); - if (outputDataSource instanceof PullBufferDataSource) - return ((PullBufferDataSource) outputDataSource).getStreams(); - if (outputDataSource instanceof PushDataSource) - return ((PushDataSource) outputDataSource).getStreams(); - if (outputDataSource instanceof PullDataSource) - return ((PullDataSource) outputDataSource).getStreams(); - return new SourceStream[0]; - } - - /** - * Implements {@link DataSource#start()}. Starts the actual transcoding - * process already set up with {@link #connect()}. - * - * @throws IOException if starting the transcoding fails - */ - public synchronized void start() - throws IOException - { - /* - * The Javadoc of DataSource#start() says it's an error to call the - * method without being connected and by that time we should have the - * outputDataSource. - */ - outputDataSource.start(); - transcodingProcessor.start(); - } - - /** - * Implements {@link DataSource#stop()}. Stops the actual transcoding - * process if it has already been set up with {@link #connect()}. - * - * @throws IOException if stopping the transcoding fails - */ - public synchronized void stop() - throws IOException - { - if (outputDataSource != null) - { - transcodingProcessor.stop(); - outputDataSource.stop(); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/pulseaudio/PA.java b/src/net/java/sip/communicator/impl/neomedia/pulseaudio/PA.java deleted file mode 100644 index 9f221c252..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/pulseaudio/PA.java +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.pulseaudio; - -public final class PA -{ - public interface context_success_cb_t - { - void callback(long c, boolean success); - } - - public interface sink_info_cb_t - { - void callback(long c, long i, int eol); - } - - public interface source_info_cb_t - { - void callback(long c, long i, int eol); - } - - public interface stream_request_cb_t - { - void callback(long s, int nbytes); - } - - public interface stream_success_cb_t - { - void callback(long s, boolean success); - } - - public static final int CONTEXT_AUTHORIZING = 2; - - public static final int CONTEXT_CONNECTING = 1; - - public static final int CONTEXT_FAILED = 5; - - public static final int CONTEXT_NOFAIL = 2; - - public static final int CONTEXT_NOFLAGS = 0; - - public static final int CONTEXT_READY = 4; - - public static final int CONTEXT_SETTING_NAME = 3; - - public static final int CONTEXT_TERMINATED = 6; - - public static final int CONTEXT_UNCONNECTED = 0; - - public static final int ENCODING_ANY = 0; - - public static final int ENCODING_INVALID = -1; - - public static final int ENCODING_PCM = 1; - - public static final int INVALID_INDEX = -1; - - public static final int OPERATION_CANCELLED = 2; - - public static final int OPERATION_DONE = 1; - - public static final int OPERATION_RUNNING = 0; - - public static final String PROP_APPLICATION_NAME = "application.name"; - - public static final String PROP_APPLICATION_VERSION = "application.version"; - - public static final String PROP_FORMAT_CHANNELS = "format.channels"; - - public static final String PROP_FORMAT_RATE = "format.rate"; - - public static final String PROP_MEDIA_NAME = "media.name"; - - public static final String PROP_MEDIA_ROLE = "media.role"; - - public static final int SAMPLE_S16LE = 3; - - public static final int SEEK_RELATIVE = 0; - - public static final int STREAM_ADJUST_LATENCY = 0x2000; - - public static final int STREAM_FAILED = 3; - - public static final int STREAM_NOFLAGS = 0x0000; - - public static final int STREAM_READY = 2; - - public static final int STREAM_START_CORKED = 0x0001; - - public static final int STREAM_TERMINATED = 4; - - static - { - System.loadLibrary("jnpulseaudio"); - } - - public static native void buffer_attr_free(long attr); - - public static native long buffer_attr_new( - int maxlength, - int tlength, - int prebuf, - int minreq, - int fragsize); - - public static native int context_connect( - long c, - String server, - int flags, - long api); - - public static native void context_disconnect(long c); - - public static native long context_get_sink_info_list( - long c, - sink_info_cb_t cb); - - public static native long context_get_source_info_list( - long c, - source_info_cb_t cb); - - public static native int context_get_state(long c); - - public static native long context_new_with_proplist( - long mainloop, - String name, - long proplist); - - public static native long context_set_sink_input_volume( - long c, - int idx, - long volume, - context_success_cb_t cb); - - public static native long context_set_source_output_volume( - long c, - int idx, - long volume, - context_success_cb_t cb); - - public static native void context_set_state_callback(long c, Runnable cb); - - public static native void context_unref(long c); - - public static native void cvolume_free(long cv); - - public static native long cvolume_new(); - - public static native long cvolume_set(long cv, int channels, int v); - - public static native int format_info_get_encoding(long f); - - public static native long format_info_get_plist(long f); - - public static native int format_info_get_prop_int(long f, String key); - - public static native String get_library_version(); - - public static native int operation_get_state(long o); - - public static native void operation_unref(long o); - - public static native void proplist_free(long p); - - public static native long proplist_new(); - - public static native int proplist_sets(long p, String key, String value); - - public static native void sample_spec_free(long ss); - - public static native long sample_spec_new( - int format, - int rate, - int channels); - - public static native String sink_info_get_description(long i); - - public static native long[] sink_info_get_formats(long i); - - public static native int sink_info_get_index(long i); - - public static native int sink_info_get_monitor_source(long i); - - public static native String sink_info_get_monitor_source_name(long i); - - public static native String sink_info_get_name(long i); - - public static native int sink_info_get_sample_spec_channels(long i); - - public static native int sink_info_get_sample_spec_format(long i); - - public static native int sink_info_get_sample_spec_rate(long i); - - public static native String source_info_get_description(long i); - - public static native long[] source_info_get_formats(long i); - - public static native int source_info_get_index(long i); - - public static native int source_info_get_monitor_of_sink(long i); - - public static native String source_info_get_name(long i); - - public static native int source_info_get_sample_spec_channels(long i); - - public static native int source_info_get_sample_spec_format(long i); - - public static native int source_info_get_sample_spec_rate(long i); - - public static native int stream_connect_playback( - long s, - String dev, - long attr, - int flags, - long volume, - long syncStream); - - public static native int stream_connect_record( - long s, - String dev, - long attr, - int flags); - - public static native long stream_cork( - long s, - boolean b, - stream_success_cb_t cb); - - public static native int stream_disconnect(long s); - - public static native int stream_drop(long s); - - public static native int stream_get_index(long s); - - public static native int stream_get_state(long s); - - public static native long stream_new_with_proplist( - long c, - String name, - long ss, - long map, - long p); - - public static native int stream_peek(long s, byte[] data, int dataOffset); - - public static native int stream_readable_size(long s); - - public static native void stream_set_read_callback( - long s, - stream_request_cb_t cb); - - public static native void stream_set_state_callback(long s, Runnable cb); - - public static native void stream_set_write_callback( - long s, - stream_request_cb_t cb); - - public static native void stream_unref(long s); - - public static native int stream_writable_size(long s); - - public static native int stream_write( - long s, - byte[] data, - int dataOffset, - int dataLength, - Runnable freeCb, - long offset, - int seek); - - public static native int sw_volume_from_linear(double v); - - public static native void threaded_mainloop_free(long m); - - public static native long threaded_mainloop_get_api(long m); - - public static native void threaded_mainloop_lock(long m); - - public static native long threaded_mainloop_new(); - - public static native void threaded_mainloop_signal( - long m, - boolean waitForAccept); - - public static native int threaded_mainloop_start(long m); - - public static native void threaded_mainloop_stop(long m); - - public static native void threaded_mainloop_unlock(long m); - - public static native void threaded_mainloop_wait(long m); - - /** Prevents the initialization of PA instances. */ - private PA() - { - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/CVImageBuffer.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/CVImageBuffer.java deleted file mode 100644 index 21fb32b31..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/CVImageBuffer.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -/** - * Represents a CoreVideo CVImageBufferRef. - * - * @author Lyubomir Marinov - */ -public class CVImageBuffer -{ - static - { - System.loadLibrary("jnquicktime"); - } - - /** - * The CoreVideo CVImageBufferRef represented by this instance. - */ - private long ptr; - - /** - * Initializes a new CVImageBuffer instance which is to represent - * a specific CoreVideo CVImageBufferRef. - * - * @param ptr the CoreVideo CVImageBufferRef to be represented by - * the new instance - */ - public CVImageBuffer(long ptr) - { - setPtr(ptr); - } - - /** - * Gets the CoreVideo CVImageBufferRef represented by this - * instance. - * - * @return the CoreVideo CVImageBufferRef represented by this - * instance - */ - protected long getPtr() - { - return ptr; - } - - /** - * Sets the CoreVideo CVImageBufferRef represented by this - * instance. - * - * @param ptr the CoreVideo CVImageBufferRef to be represented by - * this instance - */ - protected void setPtr(long ptr) - { - if (ptr == 0) - throw new IllegalArgumentException("ptr"); - - this.ptr = ptr; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/CVPixelBuffer.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/CVPixelBuffer.java deleted file mode 100644 index ee6fa7cfc..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/CVPixelBuffer.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -/** - * Represents a CoreVideo CVPixelBufferRef. - * - * @author Lubomir Marinov - */ -public class CVPixelBuffer - extends CVImageBuffer -{ - - /** - * Initializes a new CVPixelBuffer instance which is to represent - * a specific CoreVideo CVPixelBufferRef. - * - * @param ptr the CoreVideo CVPixelBufferRef to be represented by - * the new instance - */ - public CVPixelBuffer(long ptr) - { - super(ptr); - } - - /** - * Gets the number of bytes which represent the pixels of the associated - * CoreVideo CVPixelBufferRef. - * - * @return the number of bytes which represent the pixels of the associated - * CoreVideo CVPixelBufferRef - */ - public int getByteCount() - { - return getByteCount(getPtr()); - } - - /** - * Gets the number of bytes which represent the pixels of a specific - * CoreVideo CVPixelBufferRef. - * - * @param ptr the CVPixelBufferRef to get the number of bytes which - * represent its pixels of - * @return the number of bytes which represent the pixels of the specified - * CoreVideo CVPixelBufferRef - */ - private static native int getByteCount(long ptr); - - /** - * Gets a byte array which represents the pixels of the associated - * CoreVideo CVPixelBufferRef. - * - * @return a byte array which represents the pixels of the - * associated CoreVideo CVPixelBufferRef - */ - public byte[] getBytes() - { - return getBytes(getPtr()); - } - - /** - * Gets a byte array which represents the pixels of a specific - * CoreVideo CVPixelBufferRef. - * - * @param ptr the CVPixelBufferRef to get the pixel bytes of - * @return a byte array which represents the pixels of the - * specified CoreVideo CVPixelBufferRef - */ - private static native byte[] getBytes(long ptr); - - /** - * Gets the bytes which represent the pixels of the associated - * CVPixelBufferRef into a specific native byte buffer with a - * specific capacity. - * - * @param buf the native byte buffer to return the bytes into - * @param bufLength the capacity in bytes of buf - * @return the number of bytes written into buf - */ - public int getBytes(long buf, int bufLength) - { - return getBytes(getPtr(), buf, bufLength); - } - - /** - * Gets the bytes which represent the pixels of a specific - * CVPixelBufferRef into a specific native byte buffer with a - * specific capacity. - * - * @param ptr the CVPixelBufferRef to get the bytes of - * @param buf the native byte buffer to return the bytes into - * @param bufLength the capacity in bytes of buf - * @return the number of bytes written into buf - */ - private static native int getBytes(long ptr, long buf, int bufLength); - - /** - * Gets the height in pixels of this CVPixelBuffer. - * - * @return the height in pixels of this CVPixelBuffer - */ - public int getHeight() - { - return getHeight(getPtr()); - } - - /** - * Gets the height in pixels of a specific CoreVideo - * CVPixelBufferRef. - * - * @param ptr the CoreVideo CVPixelBufferRef to get the height in - * pixels of - * @return the height in pixels of the specified CoreVideo - * CVPixelBufferRef - */ - private static native int getHeight(long ptr); - - /** - * Gets the width in pixels of this CVPixelBuffer. - * - * @return the width in pixels of this CVPixelBuffer - */ - public int getWidth() - { - return getWidth(getPtr()); - } - - /** - * Gets the width in pixels of a specific CoreVideo - * CVPixelBufferRef. - * - * @param ptr the CoreVideo CVPixelBufferRef to get the width in - * pixels of - * @return the width in pixels of the specified CoreVideo - * CVPixelBufferRef - */ - private static native int getWidth(long ptr); - - /** - * Native copy from native pointer src to byte array dst. - * @param dst destination array - * @param dstOffset offset of dst to copy data to - * @param dstLength length of dst - * @param src native pointer source - */ - public static native void memcpy( - byte[] dst, int dstOffset, int dstLength, - long src); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/CVPixelBufferAttributeKey.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/CVPixelBufferAttributeKey.java deleted file mode 100644 index 8ae76e9d6..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/CVPixelBufferAttributeKey.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -/** - * @author Lyubomir Marinov - */ -public final class CVPixelBufferAttributeKey -{ - public static final long kCVPixelBufferHeightKey; - - public static final long kCVPixelBufferPixelFormatTypeKey; - - public static final long kCVPixelBufferWidthKey; - - static - { - System.loadLibrary("jnquicktime"); - - kCVPixelBufferHeightKey = kCVPixelBufferHeightKey(); - kCVPixelBufferPixelFormatTypeKey = kCVPixelBufferPixelFormatTypeKey(); - kCVPixelBufferWidthKey = kCVPixelBufferWidthKey(); - } - - /** - * Prevents the initialization of CVPixelBufferAttributeKey - * instances. - */ - private CVPixelBufferAttributeKey() - { - } - - private static native long kCVPixelBufferHeightKey(); - - private static native long kCVPixelBufferPixelFormatTypeKey(); - - private static native long kCVPixelBufferWidthKey(); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/CVPixelFormatType.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/CVPixelFormatType.java deleted file mode 100644 index 11dca5338..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/CVPixelFormatType.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -/** - * Defines the types of CVPixelBuffers to be output by - * QTCaptureDecompressedVideoOutput. - * - * @author Lubomir Marinov - */ -public final class CVPixelFormatType -{ - - /** 24 bit RGB */ - public static final int kCVPixelFormatType_24RGB = 0x00000018; - - /** 32 bit ARGB */ - public static final int kCVPixelFormatType_32ARGB = 0x00000020; - - /** Planar Component Y'CbCr 8-bit 4:2:0. */ - public static final int kCVPixelFormatType_420YpCbCr8Planar = 0x79343230; - - /** - * Prevents the initialization of CVPixelFormatType instances. - */ - private CVPixelFormatType() - { - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/NSDictionary.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/NSDictionary.java deleted file mode 100644 index 44749f71e..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/NSDictionary.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -/** - * Represents an Objective-C NSDictionary object. - * - * @author Lubomir Marinov - */ -public class NSDictionary - extends NSObject -{ - - /** - * Initializes a new NSDictionary instance which is to represent a - * specific Objective-C NSDictionary object. - * - * @param ptr the pointer to the Objective-C NSDictionary object to - * be represented by the new instance - */ - public NSDictionary(long ptr) - { - super(ptr); - } - - /** - * Called by the garbage collector to release system resources and perform - * other cleanup. - * - * @see Object#finalize() - */ - @Override - protected void finalize() - { - release(); - } - - public int intForKey(long key) - { - return intForKey(getPtr(), key); - } - - private static native int intForKey(long ptr, long key); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/NSError.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/NSError.java deleted file mode 100644 index bf95f9760..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/NSError.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -/** - * Represents an Objective-C NSError object. - * - * @author Lubomir Marinov - */ -public class NSError - extends NSObject -{ - /** - * Initializes a new NSError instance which is to represent a - * specific Objective-C NSError object. - * - * @param ptr the pointer to the Objective-C NSError object to be - * represented by the new instance - */ - public NSError(long ptr) - { - super(ptr); - } - - /** - * Called by the garbage collector to release system resources and perform - * other cleanup. - * - * @see Object#finalize() - */ - @Override - protected void finalize() - { - release(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/NSErrorException.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/NSErrorException.java deleted file mode 100644 index 70df5fda2..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/NSErrorException.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -/** - * Defines an Exception which reports an NSError. - * - * @author Lubomir Marinov - */ -public class NSErrorException - extends Exception -{ - - /** - * The NSError reported by this instance. - */ - private final NSError error; - - /** - * Initializes a new NSErrorException instance which is to report a - * specific Objective-C NSError. - * - * @param errorPtr the pointer to the Objective-C NSError object to - * be reported by the new instance - */ - public NSErrorException(long errorPtr) - { - this(new NSError(errorPtr)); - } - - /** - * Initializes a new NSErrorException instance which is to report a - * specific NSError. - * - * @param error the NSError to be reported by the new instance - */ - public NSErrorException(NSError error) - { - this.error = error; - } - - /** - * Gets the NSError reported by this instance. - * - * @return the NSError reported by this instance - */ - public NSError getError() - { - return error; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/NSMutableDictionary.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/NSMutableDictionary.java deleted file mode 100644 index 73f9bbfe0..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/NSMutableDictionary.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -/** - * Represents an Objective-C NSMutableDictionary object. - * - * @author Lubomir Marinov - */ -public class NSMutableDictionary - extends NSDictionary -{ - - /** - * Initializes a new NSMutableDictionary instance which is to - * represent a new Objective-C NSMutableDictionary object. - */ - public NSMutableDictionary() - { - this(allocAndInit()); - } - - /** - * Initializes a new NSMutableDictionary instance which is to - * represent a specific Objective-C NSMutableDictionary object. - * - * @param ptr the pointer to the Objective-C NSMutableDictionary - * object to be represented by the new instance - */ - public NSMutableDictionary(long ptr) - { - super(ptr); - } - - private static native long allocAndInit(); - - public void setIntForKey(int value, long key) - { - setIntForKey(getPtr(), value, key); - } - - private static native void setIntForKey(long ptr, int value, long key); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/NSObject.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/NSObject.java deleted file mode 100644 index 9b1631757..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/NSObject.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -/** - * Represents the root of most Objective-C class hierarchies which which objects - * inherit a basic interface to the runtime system and the ability to behave as - * Objective-C objects. - * - * @author Lyubomir Marinov - */ -public class NSObject -{ - static - { - System.loadLibrary("jnquicktime"); - } - - /** - * The pointer to the Objective-C object represented by this instance. - */ - private long ptr; - - /** - * Initializes a new NSObject instance which is to represent a - * specific Objective-C object. - * - * @param ptr the pointer to the Objective-C object to be represented by the - * new instance - */ - public NSObject(long ptr) - { - setPtr(ptr); - } - - /** - * Gets the pointer to the Objective-C object represented by this instance. - * - * @return the pointer to the Objective-C object represented by this - * instance - */ - protected long getPtr() - { - return ptr; - } - - /** - * Decrements the reference count of the Objective-C object represented by - * this instance. It is sent a dealloc message when its reference - * count reaches 0. - */ - public void release() - { - release(ptr); - } - - /** - * Decrements the reference count of a specific Objective-C object. It is - * sent a dealloc message when its reference count reaches - * 0. - * - * @param ptr the pointer to the Objective-C object to decrement the - * reference count of - */ - static native void release(long ptr); - - /** - * Increments the reference count of the Objective-C object represented by - * this instance. - */ - public void retain() - { - retain(ptr); - } - - /** - * Increments the reference count of a specific Objective-C object. - * - * @param ptr the pointer to be Objective-C object to increment the - * reference count of - */ - static native void retain(long ptr); - - /** - * Sets the pointer to the Objective-C object represented by this instance. - * - * @param ptr the pointer to the Objective-C object to be represented by - * this instance - */ - protected void setPtr(long ptr) - { - if (ptr == 0) - throw new IllegalArgumentException("ptr"); - - this.ptr = ptr; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureDecompressedVideoOutput.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureDecompressedVideoOutput.java deleted file mode 100644 index 06a99a5fc..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureDecompressedVideoOutput.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -/** - * Represents a QTKit QTCaptureDecompressedVideoOutput object. - * - * @author Lyubomir Marinov - */ -public class QTCaptureDecompressedVideoOutput - extends QTCaptureOutput -{ - - /** - * Initializes a new QTCaptureDecompressedVideoOutput which - * represents a new QTKit QTCaptureDecompressedVideoOutput object. - */ - public QTCaptureDecompressedVideoOutput() - { - this(allocAndInit()); - } - - /** - * Initializes a new QTCaptureDecompressedVideoOutput which is to - * represent a new QTKit QTCaptureDecompressedVideoOutput object. - * - * @param ptr the pointer to the QTKit - * QTCaptureDecompressedVideoOutput object to be represented by the - * new instance - */ - public QTCaptureDecompressedVideoOutput(long ptr) - { - super(ptr); - } - - private static native long allocAndInit(); - - /** - * Called by the garbage collector to release system resources and perform - * other cleanup. - * - * @see Object#finalize() - */ - @Override - protected void finalize() - { - release(); - } - - /** - * Gets the minimum time interval between which this - * QTCaptureDecompressedVideoOutput will output consecutive video - * frames. - * - * @return the minimum time interval between which this - * QTCaptureDecompressedVideoOutput will output consecutive video - * frames. It is equivalent to the inverse of the maximum frame rate. The - * value of 0 indicates an unlimited maximum frame rate. - */ - public double minimumVideoFrameInterval() - { - return minimumVideoFrameInterval(getPtr()); - } - - /** - * Gets the minimum time interval between which a specific - * QTCaptureDecompressedVideoOutput instance will output - * consecutive video frames. - * - * @param ptr a pointer to the QTCaptureDecompressedVideoOutput - * instance to get the minimum time interval between consecutive video frame - * output of - * @return the minimum time interval between which a specific - * QTCaptureDecompressedVideoOutput instance will output - * consecutive video frames. It is equivalent to the inverse of the maximum - * frame rate. The value of 0 indicates an unlimited maximum frame - * rate. - */ - private static native double minimumVideoFrameInterval(long ptr); - - public NSDictionary pixelBufferAttributes() - { - long pixelBufferAttributesPtr = pixelBufferAttributes(getPtr()); - - return - (pixelBufferAttributesPtr == 0) - ? null - : new NSDictionary(pixelBufferAttributesPtr); - } - - private static native long pixelBufferAttributes(long ptr); - - public boolean setAutomaticallyDropsLateVideoFrames( - boolean automaticallyDropsLateVideoFrames) - { - return - setAutomaticallyDropsLateVideoFrames( - getPtr(), - automaticallyDropsLateVideoFrames); - } - - private static native boolean setAutomaticallyDropsLateVideoFrames( - long ptr, - boolean automaticallyDropsLateVideoFrames); - - public void setDelegate(Delegate delegate) - { - setDelegate(getPtr(), delegate); - } - - private static native void setDelegate(long ptr, Delegate delegate); - - /** - * Sets the minimum time interval between which this - * QTCaptureDecompressedVideoOutput is to output consecutive video - * frames. - * - * @param minimumVideoFrameInterval the minimum time interval between which - * this QTCaptureDecompressedVideoOutput is to output consecutive - * video frames. It is equivalent to the inverse of the maximum frame rate. - * The value of 0 indicates an unlimited frame rate. - */ - public void setMinimumVideoFrameInterval(double minimumVideoFrameInterval) - { - setMinimumVideoFrameInterval(getPtr(), minimumVideoFrameInterval); - } - - /** - * Sets the minimum time interval between which a specific - * QTCaptureDecompressedVideoOutput instance is to output - * consecutive video frames. - * - * @param ptr a pointer to the QTCaptureDecompressedVideoOutput - * instance to set the minimum time interval between consecutive video frame - * output on - * @param minimumVideoFrameInterval the minimum time interval between which - * a specific QTCaptureDecompressedVideoOutput instance is to - * output consecutive video frames. It is equivalent to the inverse of the - * maximum frame rate. The value of 0 indicates an unlimited frame - * rate. - */ - private static native void setMinimumVideoFrameInterval( - long ptr, - double minimumVideoFrameInterval); - - public void setPixelBufferAttributes(NSDictionary pixelBufferAttributes) - { - setPixelBufferAttributes(getPtr(), pixelBufferAttributes.getPtr()); - } - - private static native void setPixelBufferAttributes( - long ptr, - long pixelBufferAttributesPtr); - - /** - * Represents the receiver of CVImageBuffer video frames and their - * associated QTSampleBuffers captured by a - * QTCaptureDecompressedVideoOutput. - */ - public static abstract class Delegate - { - private MutableQTSampleBuffer sampleBuffer; - - private MutableCVPixelBuffer videoFrame; - - /** - * Notifies this Delegate that the QTCaptureOutput to - * which it is set has output a specific CVImageBuffer - * representing a video frame with a specific QTSampleBuffer. - * - * @param videoFrame the CVImageBuffer which represents the - * output video frame - * @param sampleBuffer the QTSampleBuffer which represents - * additional details about the output video samples - */ - public abstract void outputVideoFrameWithSampleBuffer( - CVImageBuffer videoFrame, - QTSampleBuffer sampleBuffer); - - void outputVideoFrameWithSampleBuffer( - long videoFramePtr, - long sampleBufferPtr) - { - if (videoFrame == null) - videoFrame = new MutableCVPixelBuffer(videoFramePtr); - else - videoFrame.setPtr(videoFramePtr); - - if (sampleBuffer == null) - sampleBuffer = new MutableQTSampleBuffer(sampleBufferPtr); - else - sampleBuffer.setPtr(sampleBufferPtr); - - outputVideoFrameWithSampleBuffer(videoFrame, sampleBuffer); - } - } - - /** - * Represents a CVPixelBuffer which allows public changing of the - * CoreVideo CVPixelBufferRef it represents. - */ - private static class MutableCVPixelBuffer - extends CVPixelBuffer - { - /** - * Initializes a new MutableCVPixelBuffer which is to represent - * a specific CoreVideo CVPixelBufferRef. - * - * @param ptr the CoreVideo CVPixelBufferRef to be represented - * by the new instance - */ - private MutableCVPixelBuffer(long ptr) - { - super(ptr); - } - - /** - * Sets the CoreVideo CVImageBufferRef represented by this - * instance. - * - * @param ptr the CoreVideo CVImageBufferRef to be represented - * by this instance - * @see CVPixelBuffer#setPtr(long) - */ - @Override - public void setPtr(long ptr) - { - super.setPtr(ptr); - } - } - - /** - * Represents a QTSampleBuffer which allows public changing of the - * QTKit QTSampleBuffer object it represents. - */ - private static class MutableQTSampleBuffer - extends QTSampleBuffer - { - /** - * Initializes a new MutableQTSampleBuffer instance which is to - * represent a specific QTKit QTSampleBuffer object. - * - * @param ptr the pointer to the QTKit QTSampleBuffer object to - * be represented by the new instance - */ - private MutableQTSampleBuffer(long ptr) - { - super(ptr); - } - - /** - * Sets the pointer to the Objective-C object represented by this - * instance. - * - * @param ptr the pointer to the Objective-C object to be represented by - * this instance - * @see QTSampleBuffer#setPtr(long) - */ - @Override - public void setPtr(long ptr) - { - super.setPtr(ptr); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureDevice.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureDevice.java deleted file mode 100644 index cd076fb28..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureDevice.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -import java.util.*; - -/** - * Represents a QTKit capture device which is connected or has been previously - * connected to the user's computer during the lifetime of the application. - * - * @author Lubomir Marinov - */ -public class QTCaptureDevice - extends NSObject -{ - - /** - * The cached QTCaptureDevice instances previously returned by the - * last call to {@link #inputDevicesWithMediaType(QTMediaType)}. - */ - private static final Map> inputDevices - = new HashMap>(); - - /** - * The constant which represents an empty array with - * QTFormatDescription element type. Explicitly defined in order to - * avoid unnecessary allocations. - */ - private static final QTFormatDescription[] NO_FORMAT_DESCRIPTIONS - = new QTFormatDescription[0]; - - /** - * The constant which represents an empty array with - * QTCaptureDevice element type. Explicitly defined in order to - * avoid unnecessary allocations. - */ - private static final QTCaptureDevice[] NO_INPUT_DEVICES - = new QTCaptureDevice[0]; - - /** - * Initializes a new QTCaptureDevice instance which is to represent - * a specific QTKit QTCaptureDevice object. - * - * @param ptr the pointer to the QTKit QTCaptureDevice object which - * is to be represented by the new instance - */ - public QTCaptureDevice(long ptr) - { - super(ptr); - } - - /** - * Releases application control over this device acquired in the - * {@link #open()} method. - */ - public void close() - { - close(getPtr()); - } - - /** - * Releases application control over a specific QTKit - * QTCaptureDevice object acquired in the {@link #open(long)} - * method. - * - * @param ptr the pointer to the QTKit QTCaptureDevice object to - * close - */ - private static native void close(long ptr); - - /** - * Gets the QTCaptureDevice with a specific unique identifier. - * - * @param deviceUID the unique identifier of the QTCaptureDevice to - * be retrieved - * @return the QTCaptureDevice with the specified unique identifier - * if such a QTCaptureDevice exists; otherwise, null - */ - public static QTCaptureDevice deviceWithUniqueID(String deviceUID) - { - QTCaptureDevice[] inputDevices - = inputDevicesWithMediaType(QTMediaType.Video); - QTCaptureDevice deviceWithUniqueID - = deviceWithUniqueID(deviceUID, inputDevices); - - if (deviceWithUniqueID == null) - { - inputDevices = inputDevicesWithMediaType(QTMediaType.Sound); - deviceWithUniqueID = deviceWithUniqueID(deviceUID, inputDevices); - } - return deviceWithUniqueID; - } - - private static QTCaptureDevice deviceWithUniqueID( - String deviceUID, - QTCaptureDevice[] inputDevices) - { - if (inputDevices != null) - for (QTCaptureDevice inputDevice : inputDevices) - if (deviceUID.equals(inputDevice.uniqueID())) - return inputDevice; - return null; - } - - /** - * Called by the garbage collector to release system resources and perform - * other cleanup. - * - * @see Object#finalize() - */ - @Override - protected void finalize() - { - release(); - } - - public QTFormatDescription[] formatDescriptions() - { - long[] formatDescriptionPtrs = formatDescriptions(getPtr()); - QTFormatDescription[] formatDescriptions; - - if (formatDescriptionPtrs == null) - formatDescriptions = NO_FORMAT_DESCRIPTIONS; - else - { - int formatDescriptionCount = formatDescriptionPtrs.length; - - if (formatDescriptionCount == 0) - formatDescriptions = NO_FORMAT_DESCRIPTIONS; - else - { - formatDescriptions - = new QTFormatDescription[formatDescriptionCount]; - for (int i = 0; i < formatDescriptionCount; i++) - formatDescriptions[i] - = new QTFormatDescription(formatDescriptionPtrs[i]); - } - } - return formatDescriptions; - } - - private static native long[] formatDescriptions(long ptr); - - public static QTCaptureDevice[] inputDevicesWithMediaType( - QTMediaType mediaType) - { - long[] inputDevicePtrs = inputDevicesWithMediaType(mediaType.name()); - int inputDeviceCount - = (inputDevicePtrs == null) ? 0 : inputDevicePtrs.length; - QTCaptureDevice[] inputDevicesWithMediaType; - - if (inputDeviceCount == 0) - { - inputDevicesWithMediaType = NO_INPUT_DEVICES; - inputDevices.remove(mediaType); - } - else - { - inputDevicesWithMediaType = new QTCaptureDevice[inputDeviceCount]; - - List cachedInputDevicesWithMediaType - = inputDevices.get(mediaType); - - if (cachedInputDevicesWithMediaType == null) - { - cachedInputDevicesWithMediaType - = new LinkedList(); - inputDevices.put(mediaType, cachedInputDevicesWithMediaType); - } - for (int i = 0; i < inputDeviceCount; i++) - { - long inputDevicePtr = inputDevicePtrs[i]; - QTCaptureDevice inputDevice = null; - - for (QTCaptureDevice cachedInputDevice - : cachedInputDevicesWithMediaType) - if (inputDevicePtr == cachedInputDevice.getPtr()) - { - inputDevice = cachedInputDevice; - break; - } - if (inputDevice == null) - { - inputDevice = new QTCaptureDevice(inputDevicePtr); - cachedInputDevicesWithMediaType.add(inputDevice); - } - else - NSObject.release(inputDevicePtr); - inputDevicesWithMediaType[i] = inputDevice; - } - - Iterator cachedInputDeviceIter - = cachedInputDevicesWithMediaType.iterator(); - - while (cachedInputDeviceIter.hasNext()) - { - long cachedInputDevicePtr - = cachedInputDeviceIter.next().getPtr(); - boolean remove = true; - - for (long inputDevicePtr : inputDevicePtrs) - if (cachedInputDevicePtr == inputDevicePtr) - { - remove = false; - break; - } - if (remove) - cachedInputDeviceIter.remove(); - } - } - return inputDevicesWithMediaType; - } - - private static native long[] inputDevicesWithMediaType(String mediaType); - - /** - * Gets the indicator which determines whether this QTCaptureDevice - * is connected and available to applications. - * - * @return true if this QTCaptureDevice is connected and - * available to applications; otherwise, false - */ - public boolean isConnected() - { - return isConnected(getPtr()); - } - - /** - * Gets the indicator which determines whether a specific QTKit - * QTCaptureDevice object is connected and available to - * applications. - * - * @param ptr the pointer to the QTKit QTCaptureDevice object which - * is to get the indicator for - * @return true if the specified QTKit QTCaptureDevice - * object is connected and available to applications; otherwise, - * false - */ - private static native boolean isConnected(long ptr); - - /** - * Gets the localized human-readable name of this QTCaptureDevice. - * - * @return the localized human-readable name of this - * QTCaptureDevice - */ - public String localizedDisplayName() - { - return localizedDisplayName(getPtr()); - } - - /** - * Gets the localized human-readable name of a specific QTKit - * QTCaptureDevice object. - * - * @param ptr the pointer to the QTKit QTCaptureDevice object to - * get the localized human-readable name of - * @return the localized human-readable name of the specified QTKit - * QTCaptureDevice object - */ - private static native String localizedDisplayName(long ptr); - - /** - * Attempts to give the application control over this - * QTCaptureDevice so that it can be used for capture. - * - * @return true if this device was opened successfully; otherwise, - * false - * @throws NSErrorException if this device was not opened successfully and - * carries an NSError describing why this device could not be - * opened - */ - public boolean open() - throws NSErrorException - { - return open(getPtr()); - } - - /** - * Attempts to give the application control over a specific QTKit - * QTCaptureDevice object so that it can be used for capture. - * - * @param ptr the pointer to the QTKit QTCaptureDevice to be opened - * @return true if the device was opened successfully; otherwise, - * false - * @throws NSErrorException if the device was not opened successfully and - * carries an NSError describing why the device could not be opened - */ - private static native boolean open(long ptr) throws NSErrorException; - - /** - * Gets the unique identifier of this QTCaptureDevice. - * - * @return the unique identifier of this QTCaptureDevice - */ - public String uniqueID() - { - return uniqueID(getPtr()); - } - - /** - * Gets the unique identifier of a specific QTKit QTCaptureDevice - * object. - * - * @param ptr the pointer to the QTKit QTCaptureDevice object to - * get the unique identifier of - * @return the unique identifier of the specified QTKit - * QTCaptureDevice object - */ - private static native String uniqueID(long ptr); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureDeviceInput.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureDeviceInput.java deleted file mode 100644 index 71d432a11..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureDeviceInput.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -/** - * Represents a QTKit QTCaptureDeviceInput object. - * - * @author Lubomir Marinov - */ -public class QTCaptureDeviceInput - extends QTCaptureInput -{ - - /** - * Initializes a new QTCaptureDeviceInput which is to represent a - * specific QTKit QTCaptureDeviceInput object. - * - * @param ptr the pointer to the QTKit QTCaptureDeviceInput object - * to be represented by the new instance - */ - public QTCaptureDeviceInput(long ptr) - { - super(ptr); - } - - public static QTCaptureDeviceInput deviceInputWithDevice( - QTCaptureDevice device) - throws IllegalArgumentException - { - return new QTCaptureDeviceInput(deviceInputWithDevice(device.getPtr())); - } - - private static native long deviceInputWithDevice(long devicePtr) - throws IllegalArgumentException; - - /** - * Called by the garbage collector to release system resources and perform - * other cleanup. - * - * @see Object#finalize() - */ - @Override - protected void finalize() - { - release(); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureInput.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureInput.java deleted file mode 100644 index 3955cd067..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureInput.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -/** - * Represents a QTKit QTCaptureInput object. - * - * @author Lubomir Marinov - */ -public class QTCaptureInput - extends NSObject -{ - - /** - * Initializes a new QTCaptureInput instance which is to represent - * a specific QTKit QTCaptureInput object. - * - * @param ptr the pointer to the QTKit QTCaptureInput object to be - * represented by the new instance - */ - public QTCaptureInput(long ptr) - { - super(ptr); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureOutput.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureOutput.java deleted file mode 100644 index 8d405897e..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureOutput.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -/** - * Represents a QTKit QTCaptureOutput object. - * - * @author Lubomir Marinov - */ -public class QTCaptureOutput - extends NSObject -{ - - /** - * Initializes a new QTCaptureOutput instance which is to represent - * a specific QTKit QTCaptureOutput object. - * - * @param ptr the pointer to the QTKit QTCaptureOutput object to be - * represented by the new instance - */ - public QTCaptureOutput(long ptr) - { - super(ptr); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureSession.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureSession.java deleted file mode 100644 index e3c1a5158..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTCaptureSession.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -/** - * Represents a QTKit QTCaptureSession object. - * - * @author Lubomir Marinov - */ -public class QTCaptureSession - extends NSObject -{ - private boolean closed = false; - - /** - * Initializes a new QTCaptureSession instance which represents a - * new QTKit QTCaptureSession object. - */ - public QTCaptureSession() - { - this(allocAndInit()); - } - - /** - * Initializes a new QTCaptureSession instance which is to - * represent a specific QTKit QTCaptureSession object. - * - * @param ptr the pointer to the QTKit QTCaptureSession object to - * be represented by the new instance - */ - public QTCaptureSession(long ptr) - { - super(ptr); - } - - public boolean addInput(QTCaptureInput input) - throws NSErrorException - { - return addInput(getPtr(), input.getPtr()); - } - - private static native boolean addInput(long ptr, long inputPtr) - throws NSErrorException; - - public boolean addOutput(QTCaptureOutput output) - throws NSErrorException - { - return addOutput(getPtr(), output.getPtr()); - } - - private static native boolean addOutput(long ptr, long outputPtr) - throws NSErrorException; - - private static native long allocAndInit(); - - /** - * Releases the resources used by this instance throughout its existence and - * makes it available for garbage collection. This instance is considered - * unusable after closing. - */ - public synchronized void close() - { - if (!closed) - { - stopRunning(); - release(); - closed = true; - } - } - - /** - * Called by the garbage collector to release system resources and perform - * other cleanup. - * - * @see Object#finalize() - */ - @Override - protected void finalize() - { - close(); - } - - public void startRunning() - { - startRunning(getPtr()); - } - - private static native void startRunning(long ptr); - - public void stopRunning() - { - stopRunning(getPtr()); - } - - private static native void stopRunning(long ptr); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTFormatDescription.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/QTFormatDescription.java deleted file mode 100644 index 006d0dfc3..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTFormatDescription.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -import java.awt.*; - -/** - * Describes the media format of media samples and of media sources, such as - * devices and capture connections. Includes basic information about the media, - * such as media type and format type (or codec type), as well as extended - * information specific to each media type. - * - * @author Lubomir Marinov - */ -public class QTFormatDescription - extends NSObject -{ - public static final String VideoEncodedPixelsSizeAttribute; - - static - { - VideoEncodedPixelsSizeAttribute = VideoEncodedPixelsSizeAttribute(); - } - - /** - * Initializes a new QTFormatDescription instance which is to - * represent a specific QTKit QTFormatDescription object. - * - * @param ptr the pointer to the QTKit QTFormatDescription object - * which is to be represented by the new instance - */ - public QTFormatDescription(long ptr) - { - super(ptr); - } - - /** - * Called by the garbage collector to release system resources and perform - * other cleanup. - * - * @see Object#finalize() - */ - @Override - protected void finalize() - { - release(); - } - - public Dimension sizeForKey(String key) - { - return sizeForKey(getPtr(), key); - } - - private static native Dimension sizeForKey(long ptr, String key); - - private static native String VideoEncodedPixelsSizeAttribute(); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTMediaType.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/QTMediaType.java deleted file mode 100644 index 3159858ea..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTMediaType.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -/** - * Enumerates the QTKit media types. - * - * @author Lubomir Marinov - */ -public enum QTMediaType -{ - - /** - * The QTKit type of multiplexed media which may contain audio, video, and - * other data in a single stream. - */ - Muxed, - - /** - * The QTKit type of media which contains only audio frames. - */ - Sound, - - /** - * The QTKit type of media which contains only video frames. - */ - Video -} diff --git a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTSampleBuffer.java b/src/net/java/sip/communicator/impl/neomedia/quicktime/QTSampleBuffer.java deleted file mode 100644 index 8c7425ac6..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/quicktime/QTSampleBuffer.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.quicktime; - -/** - * Represents a QuickTime/QTKit QTSampleBuffer object. - * - * @author Lubomir Marinov - */ -public class QTSampleBuffer - extends NSObject -{ - - /** - * Initializes a new QTSampleBuffer which is to represent a - * specific QuickTime/QTKit QTSampleBuffer object. - * - * @param ptr the pointer to the QuickTime/QTKit QTSampleBuffer - * object to be represented by the new instance - */ - public QTSampleBuffer(long ptr) - { - super(ptr); - } - - public byte[] bytesForAllSamples() - { - return bytesForAllSamples(getPtr()); - } - - private static native byte[] bytesForAllSamples(long ptr); - - public QTFormatDescription formatDescription() - { - long formatDescriptionPtr = formatDescription(getPtr()); - - return - (formatDescriptionPtr == 0) - ? null - : new QTFormatDescription(formatDescriptionPtr); - } - - private static native long formatDescription(long ptr); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/ControlTransformInputStream.java b/src/net/java/sip/communicator/impl/neomedia/transform/ControlTransformInputStream.java deleted file mode 100644 index 00ec7c856..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/ControlTransformInputStream.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform; - -import java.io.*; -import java.net.*; -import java.util.*; - -import net.java.sip.communicator.service.neomedia.event.*; - -/** - * Implement control channel (RTCP) for TransformInputStream - * which notify listeners when RTCP feedback messages are received. - * - * @author Bing SU (nova.su@gmail.com) - * @author Lyubomir Marinov - * @author Sebastien Vincent - */ -public class ControlTransformInputStream - extends TransformUDPInputStream -{ - /** - * The list of RTCPFeedbackListener. - */ - private final List listeners - = new LinkedList(); - - /** - * Initializes a new ControlTransformInputStream which is to - * receive packet data from a specific UDP socket. - * - * @param socket the UDP socket the new instance is to receive data from - */ - public ControlTransformInputStream(DatagramSocket socket) - { - super(socket); - } - - /** - * Adds an RTCPFeedbackListener. - * - * @param listener the RTCPFeedbackListener to add - */ - public void addRTCPFeedbackListener(RTCPFeedbackListener listener) - { - if (listener == null) - throw new NullPointerException("listener"); - if(!listeners.contains(listener)) - listeners.add(listener); - } - - /** - * Removes an RTCPFeedbackListener. - * - * @param listener the RTCPFeedbackListener to remove - */ - public void removeRTCPFeedbackListener(RTCPFeedbackListener listener) - { - listeners.remove(listener); - } - - /** - * Copies the content of the most recently received packet into - * inBuffer. - * - * @param inBuffer the byte[] that we'd like to copy the content - * of the packet to. - * @param offset the position where we are supposed to start writing in - * inBuffer. - * @param length the number of bytes available for writing in - * inBuffer. - * - * @return the number of bytes read - * - * @throws IOException if length is less than the size of the - * packet. - */ - public int read(byte[] inBuffer, int offset, int length) - throws IOException - { - if (ioError) - return -1; - - int pktLength = pkt.getLength(); - - if (length < pktLength) - throw new IOException( - "Input buffer not big enough for " + pktLength); - - /* check if RTCP feedback message */ - - /* Feedback message size is minimum 12 bytes: - * Version/Padding/Feedback message type: 1 byte - * Payload type: 1 byte - * Length: 2 bytes - * SSRC of packet sender: 4 bytes - * SSRC of media source: 4 bytes - */ - if ((pktLength >= 12) && !listeners.isEmpty()) - { - byte data[] = pkt.getBuffer(); - int fmt = 0; - int pt = 0; - - /* get FMT field (last 5 bits of first byte) */ - fmt = (data[0] & 0x1F); - pt |= (data[1] & 0xFF); - - RTCPFeedbackEvent evt = new RTCPFeedbackEvent(this, fmt, pt); - - /* notify feedback listeners */ - for(RTCPFeedbackListener l : listeners) - l.feedbackReceived(evt); - } - - System.arraycopy( - pkt.getBuffer(), pkt.getOffset(), - inBuffer, offset, - pktLength); - - return pktLength; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/PacketTransformer.java b/src/net/java/sip/communicator/impl/neomedia/transform/PacketTransformer.java deleted file mode 100755 index dc3abb400..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/PacketTransformer.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform; - -import net.java.sip.communicator.impl.neomedia.*; - -/** - * Encapsulate the concept of packet transformation. Given a packet, - * PacketTransformer can either transform it or reverse the - * transformation. - * - * @author Bing SU (nova.su@gmail.com) - */ -public interface PacketTransformer -{ - /** - * Transforms a specific packet. - * - * @param pkt the packet to be transformed - * @return the transformed packet - */ - public RawPacket transform(RawPacket pkt); - - /** - * Reverse-transforms a specific packet (i.e. transforms a transformed - * packet back). - * - * @param pkt the transformed packet to be restored - * @return the restored packet - */ - public RawPacket reverseTransform(RawPacket pkt); - - /** - * Closes this PacketTransformer i.e. releases the resources - * allocated by it and prepares it for garbage collection. - */ - public void close(); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/RTPTransformTCPConnector.java b/src/net/java/sip/communicator/impl/neomedia/transform/RTPTransformTCPConnector.java deleted file mode 100644 index 904732731..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/RTPTransformTCPConnector.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform; - -import java.io.*; - -import javax.media.rtp.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.util.*; - -/** - * TransformConnector implements the RTPConnector interface. RTPConnector - * is originally designed for programmers to abstract the underlying transport - * mechanism for RTP control and data from the RTPManager. However, it provides - * the possibility to modify / transform the RTP and RTCP packets before - * they are sent to network, or after the have been received from the network. - * - * The RTPConnector interface is very powerful. But just to perform packets - * transformation, we do not need all the flexibility. So, we designed this - * TransformConnector, which uses UDP to transfer RTP/RTCP packets just like - * normal RTP stack, and then provides the TransformInputStream interface for - * people to define their own transformation. - * - * With TransformConnector, people can implement RTP/RTCP packets transformation - * and/or manipulation by implementing the TransformEngine interface. - * - * @see TransformEngine - * @see RTPConnector - * @see RTPManager - * - * @author Bing SU (nova.su@gmail.com) - * @author Lubomir Marinov - */ -public class RTPTransformTCPConnector - extends RTPConnectorTCPImpl -{ - /** - * The Logger used by the TransformConnector class and its - * instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(RTPTransformUDPConnector.class); - - /** - * The customized TransformEngine which contains the concrete - * transform logic. - */ - private TransformEngine engine; - - /** - * Initializes a new TransformConnector which is to use a given - * pair of datagram sockets for RTP and RTCP traffic specified in the form - * of a StreamConnector. - * - * @param connector the pair of datagram sockets for RTP and RTCP traffic - * the new instance is to use - */ - public RTPTransformTCPConnector(StreamConnector connector) - { - super(connector); - } - - /** - * Overrides RTPConnectorImpl#createControlInputStream() to use - * TransformInputStream. - */ - @Override - protected TransformTCPInputStream createControlInputStream() - throws IOException - { - TransformTCPInputStream controlInputStream - = new TransformTCPInputStream(getControlSocket()); - - controlInputStream.setTransformer(getRTCPTransformer()); - return controlInputStream; - } - - /** - * Overrides RTPConnectorImpl#createControlOutputStream() to use - * TransformOutputStream. - */ - @Override - protected TransformTCPOutputStream createControlOutputStream() - throws IOException - { - TransformTCPOutputStream controlOutputStream - = new TransformTCPOutputStream(getControlSocket()); - - controlOutputStream.setTransformer(getRTCPTransformer()); - return controlOutputStream; - } - - /** - * Overrides RTPConnectorImpl#createDataInputStream() to use - * TransformInputStream. - */ - @Override - protected TransformTCPInputStream createDataInputStream() - throws IOException - { - TransformTCPInputStream dataInputStream - = new TransformTCPInputStream(getDataSocket()); - - dataInputStream.setTransformer(getRTPTransformer()); - return dataInputStream; - } - - /** - * Overrides RTPConnectorImpl#createDataOutputStream() to use - * TransformOutputStream. - */ - @Override - protected TransformTCPOutputStream createDataOutputStream() - throws IOException - { - TransformTCPOutputStream dataOutputStream - = new TransformTCPOutputStream(getDataSocket()); - - dataOutputStream.setTransformer(getRTPTransformer()); - return dataOutputStream; - } - - /** - * Gets the customized TransformEngine which contains the concrete - * transform logic. - * - * @return the TransformEngine which contains the concrete - * transform logic - */ - public TransformEngine getEngine() - { - return engine; - } - - /** - * Gets the PacketTransformer specified by the current - * TransformerEngine which is used to transform and - * reverse-transform RTCP packets. - * - * @return the PacketTransformer specified by the current - * TransformEngine which is used to transform and reverse-transform - * RTCP packets if there is currently a TransformEngine and it - * specifies a TransformEngine for RTCP data; otherwise, - * null - */ - private PacketTransformer getRTCPTransformer() - { - TransformEngine engine = getEngine(); - - return (engine == null) ? null : engine.getRTCPTransformer(); - } - - /** - * Gets the PacketTransformer specified by the current - * TransformerEngine which is used to transform and - * reverse-transform RTP packets. - * - * @return the PacketTransformer specified by the current - * TransformEngine which is used to transform and reverse-transform - * RTP packets if there is currently a TransformEngine and it - * specifies a TransformEngine for RTP data; otherwise, - * null - */ - private PacketTransformer getRTPTransformer() - { - TransformEngine engine = getEngine(); - - return (engine == null) ? null : engine.getRTPTransformer(); - } - - /** - * Sets the customized TransformEngine which contains the concrete - * transform logic. - * - * @param engine the TransformEngine which contains the concrete - * transform logic - */ - public void setEngine(TransformEngine engine) - { - if (this.engine != engine) - { - this.engine = engine; - - /* - * Deliver the new PacketTransformers defined by the new - * TransformEngine to the respective streams. - */ - TransformTCPInputStream controlInputStream; - try - { - controlInputStream - = (TransformTCPInputStream) getControlInputStream(false); - } - catch (IOException ioex) - { - logger.error("The impossible happened", ioex); - controlInputStream = null; - } - if (controlInputStream != null) - controlInputStream.setTransformer(getRTCPTransformer()); - TransformTCPOutputStream controlOutputStream; - try - { - controlOutputStream - = (TransformTCPOutputStream) getControlOutputStream(false); - } - catch (IOException ioex) - { - logger.error("The impossible happened", ioex); - controlOutputStream = null; - } - if (controlOutputStream != null) - controlOutputStream.setTransformer(getRTCPTransformer()); - TransformTCPInputStream dataInputStream; - try - { - dataInputStream - = (TransformTCPInputStream) getDataInputStream(false); - } - catch (IOException ioex) - { - logger.error("The impossible happened", ioex); - dataInputStream = null; - } - if (dataInputStream != null) - dataInputStream.setTransformer(getRTPTransformer()); - TransformTCPOutputStream dataOutputStream; - try - { - dataOutputStream - = (TransformTCPOutputStream) getDataOutputStream(false); - } - catch (IOException ioex) - { - logger.error("The impossible happened", ioex); - dataOutputStream = null; - } - if (dataOutputStream != null) - dataOutputStream.setTransformer(getRTPTransformer()); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/RTPTransformUDPConnector.java b/src/net/java/sip/communicator/impl/neomedia/transform/RTPTransformUDPConnector.java deleted file mode 100644 index c70de5ac9..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/RTPTransformUDPConnector.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform; - -import java.io.*; - -import javax.media.rtp.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.util.*; - -/** - * TransformConnector implements the RTPConnector interface. RTPConnector - * is originally designed for programmers to abstract the underlying transport - * mechanism for RTP control and data from the RTPManager. However, it provides - * the possibility to modify / transform the RTP and RTCP packets before - * they are sent to network, or after the have been received from the network. - * - * The RTPConnector interface is very powerful. But just to perform packets - * transformation, we do not need all the flexibility. So, we designed this - * TransformConnector, which uses UDP to transfer RTP/RTCP packets just like - * normal RTP stack, and then provides the TransformInputStream interface for - * people to define their own transformation. - * - * With TransformConnector, people can implement RTP/RTCP packets transformation - * and/or manipulation by implementing the TransformEngine interface. - * - * @see TransformEngine - * @see RTPConnector - * @see RTPManager - * - * @author Bing SU (nova.su@gmail.com) - * @author Lubomir Marinov - */ -public class RTPTransformUDPConnector - extends RTPConnectorUDPImpl -{ - /** - * The Logger used by the TransformConnector class and its - * instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(RTPTransformUDPConnector.class); - - /** - * The customized TransformEngine which contains the concrete - * transform logic. - */ - private TransformEngine engine; - - /** - * Initializes a new TransformConnector which is to use a given - * pair of datagram sockets for RTP and RTCP traffic specified in the form - * of a StreamConnector. - * - * @param connector the pair of datagram sockets for RTP and RTCP traffic - * the new instance is to use - */ - public RTPTransformUDPConnector(StreamConnector connector) - { - super(connector); - } - - /** - * Overrides RTPConnectorImpl#createControlInputStream() to use - * TransformInputStream. - */ - @Override - protected TransformUDPInputStream createControlInputStream() - throws IOException - { - TransformUDPInputStream controlInputStream - = new ControlTransformInputStream(getControlSocket()); - - controlInputStream.setTransformer(getRTCPTransformer()); - return controlInputStream; - } - - /** - * Overrides RTPConnectorImpl#createControlOutputStream() to use - * TransformOutputStream. - */ - @Override - protected TransformUDPOutputStream createControlOutputStream() - throws IOException - { - TransformUDPOutputStream controlOutputStream - = new TransformUDPOutputStream(getControlSocket()); - - controlOutputStream.setTransformer(getRTCPTransformer()); - return controlOutputStream; - } - - /** - * Overrides RTPConnectorImpl#createDataInputStream() to use - * TransformInputStream. - */ - @Override - protected TransformUDPInputStream createDataInputStream() - throws IOException - { - TransformUDPInputStream dataInputStream - = new TransformUDPInputStream(getDataSocket()); - - dataInputStream.setTransformer(getRTPTransformer()); - return dataInputStream; - } - - /** - * Overrides RTPConnectorImpl#createDataOutputStream() to use - * TransformOutputStream. - */ - @Override - protected TransformUDPOutputStream createDataOutputStream() - throws IOException - { - TransformUDPOutputStream dataOutputStream - = new TransformUDPOutputStream(getDataSocket()); - - dataOutputStream.setTransformer(getRTPTransformer()); - return dataOutputStream; - } - - /** - * Gets the customized TransformEngine which contains the concrete - * transform logic. - * - * @return the TransformEngine which contains the concrete - * transform logic - */ - public TransformEngine getEngine() - { - return engine; - } - - /** - * Gets the PacketTransformer specified by the current - * TransformerEngine which is used to transform and - * reverse-transform RTCP packets. - * - * @return the PacketTransformer specified by the current - * TransformEngine which is used to transform and reverse-transform - * RTCP packets if there is currently a TransformEngine and it - * specifies a TransformEngine for RTCP data; otherwise, - * null - */ - private PacketTransformer getRTCPTransformer() - { - TransformEngine engine = getEngine(); - - return (engine == null) ? null : engine.getRTCPTransformer(); - } - - /** - * Gets the PacketTransformer specified by the current - * TransformerEngine which is used to transform and - * reverse-transform RTP packets. - * - * @return the PacketTransformer specified by the current - * TransformEngine which is used to transform and reverse-transform - * RTP packets if there is currently a TransformEngine and it - * specifies a TransformEngine for RTP data; otherwise, - * null - */ - private PacketTransformer getRTPTransformer() - { - TransformEngine engine = getEngine(); - - return (engine == null) ? null : engine.getRTPTransformer(); - } - - /** - * Sets the customized TransformEngine which contains the concrete - * transform logic. - * - * @param engine the TransformEngine which contains the concrete - * transform logic - */ - public void setEngine(TransformEngine engine) - { - if (this.engine != engine) - { - this.engine = engine; - - /* - * Deliver the new PacketTransformers defined by the new - * TransformEngine to the respective streams. - */ - TransformUDPInputStream controlInputStream; - try - { - controlInputStream - = (TransformUDPInputStream) getControlInputStream(false); - } - catch (IOException ioex) - { - logger.error("The impossible happened", ioex); - controlInputStream = null; - } - if (controlInputStream != null) - controlInputStream.setTransformer(getRTCPTransformer()); - TransformUDPOutputStream controlOutputStream; - try - { - controlOutputStream - = (TransformUDPOutputStream) getControlOutputStream(false); - } - catch (IOException ioex) - { - logger.error("The impossible happened", ioex); - controlOutputStream = null; - } - if (controlOutputStream != null) - controlOutputStream.setTransformer(getRTCPTransformer()); - TransformUDPInputStream dataInputStream; - try - { - dataInputStream - = (TransformUDPInputStream) getDataInputStream(false); - } - catch (IOException ioex) - { - logger.error("The impossible happened", ioex); - dataInputStream = null; - } - if (dataInputStream != null) - dataInputStream.setTransformer(getRTPTransformer()); - TransformUDPOutputStream dataOutputStream; - try - { - dataOutputStream - = (TransformUDPOutputStream) getDataOutputStream(false); - } - catch (IOException ioex) - { - logger.error("The impossible happened", ioex); - dataOutputStream = null; - } - if (dataOutputStream != null) - dataOutputStream.setTransformer(getRTPTransformer()); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/TransformEngine.java b/src/net/java/sip/communicator/impl/neomedia/transform/TransformEngine.java deleted file mode 100755 index f72aa8de4..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/TransformEngine.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform; - -/** - * Defines how to get PacketTransformers for RTP and RTCP packets. A - * single PacketTransformer can be used for both RTP and RTCP packets - * or there can be two separate PacketTransformers. - * - * @author Bing SU (nova.su@gmail.com) - */ -public interface TransformEngine -{ - /** - * Gets the PacketTransformer for RTP packets. - * - * @return the PacketTransformer for RTP packets - */ - public PacketTransformer getRTPTransformer(); - - /** - * Gets the PacketTransformer for RTCP packets. - * - * @return the PacketTransformer for RTCP packets - */ - public PacketTransformer getRTCPTransformer(); -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/TransformEngineChain.java b/src/net/java/sip/communicator/impl/neomedia/transform/TransformEngineChain.java deleted file mode 100644 index b99315605..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/TransformEngineChain.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform; - -import net.java.sip.communicator.impl.neomedia.*; - -/** - * The engine chain allows using numerous TransformEngines on a single - * stream. - * - * @author Emil Ivov - * @author Lubomir Marinov - */ -public class TransformEngineChain - implements TransformEngine -{ - - /** - * The sequence of TransformEngines whose - * PacketTransformers that this engine chain will be applying to - * RTP and RTCP packets. - */ - private final TransformEngine[] engineChain; - - /** - * The sequence of PacketTransformers that this engine chain will - * be applying to RTP packets. - */ - private final PacketTransformerChain rtpTransformChain; - - /** - * The sequence of PacketTransformers that this engine chain will - * be applying to RTCP packets. - */ - private final PacketTransformerChain rtcpTransformChain; - - /** - * Creates a new TransformEngineChain using the - * engineChain array. Engines will be applied in the order - * specified by the engineChain array for outgoing packets - * and in the reverse order for incoming packets. - * - * @param engineChain an array containing TransformEngines in the - * order that they are to be applied on outgoing packets. - */ - public TransformEngineChain(TransformEngine[] engineChain) - { - this.engineChain = engineChain.clone(); - - rtpTransformChain = new PacketTransformerChain(true); - rtcpTransformChain = new PacketTransformerChain(false); - } - - /** - * Returns the meta PacketTransformer that will be applying - * RTCP transformations from all engines registered in this - * TransformEngineChain. - * - * @return a PacketTransformerChain over all RTP transformers in - * this engine chain. - */ - public PacketTransformer getRTPTransformer() - { - return rtpTransformChain; - } - - /** - * Returns the meta PacketTransformer that will be applying - * RTCP transformations from all engines registered in this - * TransformEngineChain. - * - * @return a PacketTransformerChain over all RTCP transformers in - * this engine chain. - */ - public PacketTransformer getRTCPTransformer() - { - return rtcpTransformChain; - } - - /** - * A PacketTransformerChain is a meta PacketTransformer - * that applies all transformers present in this engine chain. The class - * respects the order of the engine chain for outgoing packets and reverses - * it for incoming packets. - */ - private class PacketTransformerChain - implements PacketTransformer - { - /** - * Indicates whether this transformer will be dealing with RTP or, - * in other words, whether it will transform packets via the RTP - * transformers in this chain rather than the RTCP ones. - */ - private final boolean isRtp; - - /** - * Creates an instance of this packet transformer and prepares it to - * deal with RTP or RTCP according to the isRtp arg. - * - * @param isRtp true if this transformer will be dealing with - * RTP (i.e. will transform packets via the RTP transformers in this - * chain rather than the RTCP ones) and false otherwise. - */ - public PacketTransformerChain(boolean isRtp) - { - this.isRtp = isRtp; - } - - /** - * Close the transformer and underlying transform engines. - * - * Propagate the close to all transformers in chain. - */ - public void close() - { - for (TransformEngine engine : engineChain) - { - PacketTransformer pTransformer - = isRtp - ? engine.getRTPTransformer() - : engine.getRTCPTransformer(); - - //the packet transformer may be null if for example the engine - //only does RTP transformations and this is an RTCP transformer. - if( pTransformer != null) - pTransformer.close(); - } - } - - /** - * Transforms a specific packet. - * - * @param pkt the packet to be transformed - * @return the transformed packet - */ - public RawPacket transform(RawPacket pkt) - { - for (TransformEngine engine : engineChain) - { - PacketTransformer pTransformer - = isRtp - ? engine.getRTPTransformer() - : engine.getRTCPTransformer(); - - //the packet transformer may be null if for example the engine - //only does RTP transformations and this is an RTCP transformer. - if( pTransformer != null) - pkt = pTransformer.transform(pkt); - } - - return pkt; - } - - /** - * Reverse-transforms a specific packet (i.e. transforms a transformed - * packet back). - * - * @param pkt the transformed packet to be restored - * @return the restored packet - */ - public RawPacket reverseTransform(RawPacket pkt) - { - for (int i = engineChain.length - 1 ; i >= 0; i--) - { - TransformEngine engine = engineChain[i]; - PacketTransformer pTransformer - = isRtp - ? engine.getRTPTransformer() - : engine.getRTCPTransformer(); - - //the packet transformer may be null if for example the engine - //only does RTP transformations and this is an RTCP transformer. - if( pTransformer != null) - { - pkt = pTransformer.reverseTransform(pkt); - if (pkt == null) - return null; - } - } - - return pkt; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/TransformTCPInputStream.java b/src/net/java/sip/communicator/impl/neomedia/transform/TransformTCPInputStream.java deleted file mode 100644 index ca23b2288..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/TransformTCPInputStream.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform; - -import java.net.*; - -import net.java.sip.communicator.impl.neomedia.*; - -/** - * Extends RTPConnectorInputStream with transform logic for TCP. - * - * In this implementation, we use TCP sockets to receive RTP/RTCP. We listen on - * the address / port specified by local session address. When one packet is - * received, it is first reverse transformed through PacketTransformer defined - * by user. And then returned as normal RTP/RTCP packets to RTPManager. - * - * @author Bing SU (nova.su@gmail.com) - * @author Lubomir Marinov - */ -public class TransformTCPInputStream - extends RTPConnectorTCPInputStream -{ - /** - * The user defined PacketTransformer which is used to reverse - * transform packets. - */ - private PacketTransformer transformer; - - /** - * Initializes a new TransformInputStream which is to receive - * packet data from a specific TCP socket. - * - * @param socket the UDP socket the new instance is to receive data from - */ - public TransformTCPInputStream(Socket socket) - { - super(socket); - } - - /** - * Creates a new RawPacket from a specific DatagramPacket - * in order to have this instance receive its packet data through its - * {@link #read(byte[], int, int)} method. Reverse-transforms the received - * packet. - * - * @param datagramPacket the DatagramPacket containing the packet - * data - * @return a new RawPacket containing the packet data of the - * specified DatagramPacket or possibly its modification; - * null to ignore the packet data of the specified - * DatagramPacket and not make it available to this instance - * through its {@link #read(byte[], int, int)} method - * @see RTPConnectorInputStream#createRawPacket(DatagramPacket) - */ - @Override - protected RawPacket createRawPacket(DatagramPacket datagramPacket) - { - PacketTransformer transformer = getTransformer(); - RawPacket pkt = super.createRawPacket(datagramPacket); - - return (transformer == null) ? pkt : transformer.reverseTransform(pkt); - } - - /** - * Gets the PacketTransformer which is used to reverse-transform - * packets. - * - * @return the PacketTransformer which is used to reverse-transform - * packets - */ - public PacketTransformer getTransformer() - { - return transformer; - } - - /** - * Sets the PacketTransformer which is to be used to - * reverse-transform packets. - * - * @param transformer the PacketTransformer which is to be used to - * reverse-transform packets - */ - public void setTransformer(PacketTransformer transformer) - { - this.transformer = transformer; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/TransformTCPOutputStream.java b/src/net/java/sip/communicator/impl/neomedia/transform/TransformTCPOutputStream.java deleted file mode 100644 index a59a723d8..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/TransformTCPOutputStream.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform; - -import java.net.*; - -import net.java.sip.communicator.impl.neomedia.*; - -/** - * Extends RTPConnectorOutputStream with transform logic for TCP. - * - * In this implementation, TCP socket is used to send the data out. When a - * normal RTP/RTCP packet is passed down from RTPManager, we first transform - * the packet using user define PacketTransformer and then send it out through - * network to all the stream targets. - * - * @author Bing SU (nova.su@gmail.com) - * @author Lubomir Marinov - */ -public class TransformTCPOutputStream - extends RTPConnectorTCPOutputStream -{ - /** - * The PacketTransformer used to transform RTP/RTCP packets. - */ - private PacketTransformer transformer; - - /** - * Initializes a new TransformOutputStream which is to send packet - * data out through a specific TCP socket. - * - * @param socket the TCP socket used to send packet data out - */ - public TransformTCPOutputStream(Socket socket) - { - super(socket); - } - - /** - * Creates a new RawPacket from a specific byte[] buffer - * in order to have this instance send its packet data through its - * {@link #write(byte[], int, int)} method. Transforms the packet to be - * sent. - * - * @param buffer the packet data to be sent to the targets of this instance - * @param offset the offset of the packet data in buffer - * @param length the length of the packet data in buffer - * @return a new RawPacket containing the packet data of the - * specified byte[] buffer or possibly its modification; - * null to ignore the packet data of the specified byte[] - * buffer and not send it to the targets of this instance through its - * {@link #write(byte[], int, int)} method - * @see RTPConnectorOutputStream#createRawPacket(byte[], int, int) - */ - @Override - protected RawPacket createRawPacket(byte[] buffer, int offset, int length) - { - RawPacket pkt = super.createRawPacket(buffer, offset, length); - PacketTransformer transformer = getTransformer(); - - if (transformer != null) - { - pkt = transformer.transform(pkt); - - /* - * This is for the case when the ZRTP engine stops the media stream - * allowing only ZRTP packets. - */ - // TODO Comment in order to use the GoClear feature. - if ((pkt == null) && (targets.size() > 0)) - throw new NullPointerException("pkt"); - } - return pkt; - } - - /** - * Gets the PacketTransformer which is used to transform packets. - * - * @return the PacketTransformer which is used to transform packets - */ - public PacketTransformer getTransformer() - { - return transformer; - } - - /** - * Sets the PacketTransformer which is to be used to transform - * packets. - * - * @param transformer the PacketTransformer which is to be used to - * transform packets - */ - public void setTransformer(PacketTransformer transformer) - { - this.transformer = transformer; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/TransformUDPInputStream.java b/src/net/java/sip/communicator/impl/neomedia/transform/TransformUDPInputStream.java deleted file mode 100644 index 0e3a89fd8..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/TransformUDPInputStream.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform; - -import java.net.*; - -import net.java.sip.communicator.impl.neomedia.*; - -/** - * Extends RTPConnectorInputStream with transform logic for UDP. - * - * In this implementation, we use UDP sockets to receive RTP/RTCP. We listen on - * the address / port specified by local session address. When one packet is - * received, it is first reverse transformed through PacketTransformer defined - * by user. And then returned as normal RTP/RTCP packets to RTPManager. - * - * @author Bing SU (nova.su@gmail.com) - * @author Lubomir Marinov - */ -public class TransformUDPInputStream - extends RTPConnectorUDPInputStream -{ - /** - * The user defined PacketTransformer which is used to reverse - * transform packets. - */ - private PacketTransformer transformer; - - /** - * Initializes a new TransformInputStream which is to receive - * packet data from a specific UDP socket. - * - * @param socket the UDP socket the new instance is to receive data from - */ - public TransformUDPInputStream(DatagramSocket socket) - { - super(socket); - } - - /** - * Creates a new RawPacket from a specific DatagramPacket - * in order to have this instance receive its packet data through its - * {@link #read(byte[], int, int)} method. Reverse-transforms the received - * packet. - * - * @param datagramPacket the DatagramPacket containing the packet - * data - * @return a new RawPacket containing the packet data of the - * specified DatagramPacket or possibly its modification; - * null to ignore the packet data of the specified - * DatagramPacket and not make it available to this instance - * through its {@link #read(byte[], int, int)} method - * @see RTPConnectorInputStream#createRawPacket(DatagramPacket) - */ - @Override - protected RawPacket createRawPacket(DatagramPacket datagramPacket) - { - PacketTransformer transformer = getTransformer(); - RawPacket pkt = super.createRawPacket(datagramPacket); - - return (transformer == null) ? pkt : transformer.reverseTransform(pkt); - } - - /** - * Gets the PacketTransformer which is used to reverse-transform - * packets. - * - * @return the PacketTransformer which is used to reverse-transform - * packets - */ - public PacketTransformer getTransformer() - { - return transformer; - } - - /** - * Sets the PacketTransformer which is to be used to - * reverse-transform packets. - * - * @param transformer the PacketTransformer which is to be used to - * reverse-transform packets - */ - public void setTransformer(PacketTransformer transformer) - { - this.transformer = transformer; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/TransformUDPOutputStream.java b/src/net/java/sip/communicator/impl/neomedia/transform/TransformUDPOutputStream.java deleted file mode 100644 index 0b5a7fb43..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/TransformUDPOutputStream.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform; - -import java.net.*; - -import net.java.sip.communicator.impl.neomedia.*; - -/** - * Extends RTPConnectorOutputStream with transform logic for UDP. - * - * In this implementation, UDP socket is used to send the data out. When a - * normal RTP/RTCP packet is passed down from RTPManager, we first transform - * the packet using user define PacketTransformer and then send it out through - * network to all the stream targets. - * - * @author Bing SU (nova.su@gmail.com) - * @author Lubomir Marinov - */ -public class TransformUDPOutputStream - extends RTPConnectorUDPOutputStream -{ - /** - * The PacketTransformer used to transform RTP/RTCP packets. - */ - private PacketTransformer transformer; - - /** - * Initializes a new TransformOutputStream which is to send packet - * data out through a specific UDP socket. - * - * @param socket the UDP socket used to send packet data out - */ - public TransformUDPOutputStream(DatagramSocket socket) - { - super(socket); - } - - /** - * Creates a new RawPacket from a specific byte[] buffer - * in order to have this instance send its packet data through its - * {@link #write(byte[], int, int)} method. Transforms the packet to be - * sent. - * - * @param buffer the packet data to be sent to the targets of this instance - * @param offset the offset of the packet data in buffer - * @param length the length of the packet data in buffer - * @return a new RawPacket containing the packet data of the - * specified byte[] buffer or possibly its modification; - * null to ignore the packet data of the specified byte[] - * buffer and not send it to the targets of this instance through its - * {@link #write(byte[], int, int)} method - * @see RTPConnectorOutputStream#createRawPacket(byte[], int, int) - */ - @Override - protected RawPacket createRawPacket(byte[] buffer, int offset, int length) - { - RawPacket pkt = super.createRawPacket(buffer, offset, length); - PacketTransformer transformer = getTransformer(); - - if (transformer != null) - { - pkt = transformer.transform(pkt); - - /* - * This is for the case when the ZRTP engine stops the media stream - * allowing only ZRTP packets. - */ - // TODO Comment in order to use the GoClear feature. - if ((pkt == null) && (targets.size() > 0)) - throw new NullPointerException("pkt"); - } - return pkt; - } - - /** - * Gets the PacketTransformer which is used to transform packets. - * - * @return the PacketTransformer which is used to transform packets - */ - public PacketTransformer getTransformer() - { - return transformer; - } - - /** - * Sets the PacketTransformer which is to be used to transform - * packets. - * - * @param transformer the PacketTransformer which is to be used to - * transform packets - */ - public void setTransformer(PacketTransformer transformer) - { - this.transformer = transformer; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/csrc/CsrcTransformEngine.java b/src/net/java/sip/communicator/impl/neomedia/transform/csrc/CsrcTransformEngine.java deleted file mode 100644 index 42565f1c9..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/csrc/CsrcTransformEngine.java +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform.csrc; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.transform.*; -import net.java.sip.communicator.service.neomedia.*; - -/** - * We use this engine to add the list of CSRC identifiers in RTP packets that - * we send to conference participants during calls where we are the mixer. - * - * @author Emil Ivov - */ -public class CsrcTransformEngine - implements TransformEngine, - PacketTransformer -{ - /** - * The MediaStreamImpl that this transform engine was created to - * transform packets for. - */ - private final MediaStreamImpl mediaStream; - - /** - * The number currently assigned to CSRC audio level extensions or - * -1 if no such ID has been set and audio level extensions should - * not be transmitted. - */ - private byte csrcAudioLevelExtID = -1; - - /** - * The buffer that we use to encode the csrc audio level extensions. - */ - private byte[] extensionBuff = null; - - /** - * Indicates the length that we are currently using in the - * extensionBuff buffer. - */ - private int extensionBuffLen = 0; - - /** - * The dispatcher that is delivering audio levels to the media steam. - */ - private CsrcAudioLevelDispatcher csrcLevelDispatcher = null; - - /** - * The direction that we are supposed to handle audio levels in. - */ - private MediaDirection audioLevelDirection = MediaDirection.INACTIVE; - - /** - * Creates an engine instance that will be adding CSRC lists to the - * specified stream. - * - * @param stream that MediaStream whose RTP packets we are going - * to be adding CSRC lists. to - */ - public CsrcTransformEngine(MediaStreamImpl stream) - { - this.mediaStream = stream; - } - - /** - * Closes this PacketTransformer i.e. releases the resources - * allocated by it and prepares it for garbage collection. - */ - public void close() - { - if (csrcLevelDispatcher != null) - csrcLevelDispatcher.stop(); - } - - /** - * Always returns null since this engine does not require any - * RTCP transformations. - * - * @return null since this engine does not require any - * RTCP transformations. - */ - public PacketTransformer getRTCPTransformer() - { - return null; - } - - /** - * Returns a reference to this class since it is performing RTP - * transformations in here. - * - * @return a reference to this instance of the - * CsrcTransformEngine. - */ - public PacketTransformer getRTPTransformer() - { - return this; - } - - /** - * Extracts the list of CSRC identifiers and passes it to the - * MediaStream associated with this engine. Other than that the - * method does not do any transformations since CSRC lists are part of - * RFC 3550 and they shouldn't be disrupting the rest of the application. - * - * @param pkt the RTP RawPacket that we are to extract a CSRC list - * from. - * - * @return the same RawPacket that was received as a parameter - * since we don't need to worry about hiding the CSRC list from the rest - * of the RTP stack. - */ - public RawPacket reverseTransform(RawPacket pkt) - { - if ((csrcAudioLevelExtID > 0) && audioLevelDirection.allowsReceiving()) - { - //extract the audio levels and send them to the dispatcher. - long[] levels = pkt.extractCsrcLevels(csrcAudioLevelExtID); - - if(levels != null) - { - if (csrcLevelDispatcher == null) - { - csrcLevelDispatcher = new CsrcAudioLevelDispatcher(); - new Thread(csrcLevelDispatcher).start(); - } - - csrcLevelDispatcher.addLevels(levels); - } - } - return pkt; - } - - /** - * Extracts the list of CSRC identifiers representing participants currently - * contributing to the media being sent by the MediaStream - * associated with this engine and (unless the list is empty) encodes them - * into the RawPacket. - * - * @param pkt the RTP RawPacket that we need to add a CSRC list to. - * - * @return the updated RawPacket instance containing the list of - * CSRC identifiers. - */ - public synchronized RawPacket transform(RawPacket pkt) - { - // if somebody has modified the packet and added an extension - // don't process it. As ZRTP creates special RTP packets carrying no - // RTP data and those packets are used only by ZRTP we don't use them. - if(pkt.getExtensionBit()) - return pkt; - - long[] csrcList = mediaStream.getLocalContributingSourceIDs(); - - if(csrcList == null || csrcList.length == 0) - { - //nothing to do. - return pkt; - } - - pkt.setCsrcList( csrcList); - - //attach audio levels if we are expected to do so. - if ((this.csrcAudioLevelExtID > 0) - && audioLevelDirection.allowsSending() - && (mediaStream instanceof AudioMediaStreamImpl)) - { - byte[] levelsExt = createLevelExtensionBuffer(csrcList); - - pkt.addExtension(levelsExt, extensionBuffLen); - } - - return pkt; - } - - /** - * Sets the ID that this transformer should be using for audio level - * extensions or disables audio level extensions if extID is - * -1. - * - * @param extID ID that this transformer should be using for audio level - * extensions or -1 if audio level extensions should be disabled - * @param dir the direction that we are expected to hand this extension in. - * - */ - public void setCsrcAudioLevelAudioLevelExtensionID(byte extID, - MediaDirection dir) - { - this.csrcAudioLevelExtID = extID; - this.audioLevelDirection = dir; - } - - /** - * Creates a audio level extension buffer containing the level extension - * header and the audio levels corresponding to (and in the same order as) - * the CSRC IDs in the csrcList - * - * @param csrcList the list of CSRC IDs whose level we'd like the extension - * to contain. - * @return the extension buffer in the form that it should be added to the - * RTP packet. - */ - private byte[] createLevelExtensionBuffer(long[] csrcList) - { - int buffLen = 1 + //CSRC one byte extension hdr - csrcList.length; - - // calculate extension padding - int padLen = 4 - buffLen%4; - - if(padLen == 4) - padLen = 0; - - buffLen += padLen; - - byte[] extensionBuff = getExtensionBuff(buffLen); - - extensionBuff[0] - = (byte)((csrcAudioLevelExtID << 4) | (csrcList.length - 1)); - - int csrcOffset = 1; // initial offset is equal to ext hdr size - - for(long csrc : csrcList) - { - byte level - = (byte) - ((AudioMediaStreamImpl)mediaStream) - .getLastMeasuredAudioLevel(csrc); - - extensionBuff[csrcOffset] = level; - csrcOffset ++; - } - - return extensionBuff; - } - - /** - * Returns a reusable byte array which is guaranteed to have the requested - * ensureCapacity length and sets our internal length keeping - * var. - * - * @param ensureCapacity the minimum length that we need the returned buffer - * to have. - * @return a reusable byte[] array guaranteed to have a length - * equal to or greater than ensureCapacity. - */ - private byte[] getExtensionBuff(int ensureCapacity) - { - if ((extensionBuff == null) || (extensionBuff.length < ensureCapacity)) - extensionBuff = new byte[ensureCapacity]; - - extensionBuffLen = ensureCapacity; - return extensionBuff; - } - - /** - * A simple thread that waits for new levels to be reported from incoming - * RTP packets and then delivers them to the AudioMediaStream - * associated with this engine. The reason we need to do this in a separate - * thread is, of course, the time sensitive nature of incoming RTP packets. - */ - private class CsrcAudioLevelDispatcher - implements Runnable - { - /** Indicates whether this thread is supposed to be running */ - private boolean isRunning = false; - - /** The levels that we last received from the reverseTransform thread*/ - private long[] lastReportedLevels = null; - - /** - * Waits for new levels to be reported via the addLevels() - * method and then delivers them to the AudioMediaStream that - * we are associated with. - */ - public void run() - { - isRunning = true; - - //no point in listening if our stream is not an audio one. - if(!(mediaStream instanceof AudioMediaStreamImpl)) - return; - - long[] temp = null; - - while(isRunning) - { - synchronized(this) - { - if(lastReportedLevels == null) - { - try - { - wait(); - } - catch (InterruptedException ie) {} - } - - temp = lastReportedLevels; - // make lastReportedLevels to null - // so we will wait for the next level on next iteration - lastReportedLevels = null; - } - - if(temp != null) - { - //now notify our listener - if (mediaStream != null) - { - ((AudioMediaStreamImpl)mediaStream) - .fireConferenceAudioLevelEvent(temp); - } - } - } - } - - /** - * A level matrix that we should deliver to our media stream and - * its listeners in a separate thread. - * - * @param levels the levels that we'd like to queue for processing. - */ - public void addLevels(long[] levels) - { - synchronized(this) - { - this.lastReportedLevels = levels; - - notifyAll(); - } - } - - /** - * Causes our run method to exit so that this thread would stop - * handling levels. - */ - public void stop() - { - synchronized(this) - { - this.lastReportedLevels = null; - isRunning = false; - - notifyAll(); - } - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/dtmf/DtmfRawPacket.java b/src/net/java/sip/communicator/impl/neomedia/transform/dtmf/DtmfRawPacket.java deleted file mode 100644 index 29ae76e72..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/dtmf/DtmfRawPacket.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform.dtmf; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.util.*; - -/** - * DtmfRawPacket represent an RTP Packet. - * You create your DtmfRawPacket by calling the constructor. - * You specify the DTMF attributes : code=9, end=false, marker=true ... - * Then you fill the packet using init( ... dtmf attributes ... ); - * - * @author Romain Philibert - * @author Emil Ivov - * @author Damian Minkov - */ -public class DtmfRawPacket - extends RawPacket -{ - /** - * Our class logger. - */ - private static final Logger logger - = Logger.getLogger(DtmfRawPacket.class); - - /** - * The fixed size of a DTMF packet. - */ - public static final int DTMF_PACKET_SIZE = 16; - - /** - * The event code to send. - */ - private int code; - - /** - * Is this an end packet. - */ - private boolean end; - - /** - * The duration of the current packet. - */ - private int duration; - - /** - * Creates a DtmfRawPacket using the specified buffer. - * - * @param buffer the byte array that we should use to store packet - * content - * @param offset the index where we should start using the buffer. - * @param payload the payload that has been negotiated for telephone events - * by our signaling modules. - */ - public DtmfRawPacket(byte[] buffer, int offset, byte payload) - { - super (buffer, offset, DTMF_PACKET_SIZE); - - setPayload(payload); - } - - /** - * Used for incoming DTMF packets, creating DtmfRawPacket - * from RTP one. - * @param pkt the RTP packet. - */ - public DtmfRawPacket(RawPacket pkt) - { - super(pkt.getBuffer(), pkt.getOffset(), pkt.getLength()); - - int at = getHeaderLength(); - - code = readByte(at++); - end = (readByte(at++) & 0x80) != 0; - - duration = ((readByte(at++) & 0xFF) << 8) | (readByte(at++) & 0xFF); - } - - /** - * Initializes DTMF specific values in this packet. - * - * @param code the DTMF code representing the digit. - * @param end the DTMF End flag - * @param marker the RTP Marker flag - * @param duration the DTMF duration - * @param timestamp the RTP timestamp - */ - public void init(int code, - boolean end, - boolean marker, - int duration, - long timestamp) - { - if(logger.isTraceEnabled()) - { - logger.trace("DTMF send on RTP, code : " + code + - " duration = "+duration +" timestamps = "+timestamp + - " Marker = " + marker + " End = " + end); - } - - // Set the payload type and the marker - setMarker(marker); - - // set the Timestamp - setTimestamp(timestamp); - - // Create the RTP data - setDtmfPayload(code, end, duration); - } - - /** - * Initializes the a DTMF raw data using event, E and duration field. - * Event : the digits to transmit (0-15). - * E : End field, used to mark the two last packets. - * R always = 0. - * Volume always = 0. - * Duration : duration increments for each dtmf sending updates, - * stay unchanged at the end for the 3 last packets. - *
-     *  0                   1                   2                   3
-     *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-     *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     *  |     event     |E R| volume    |          duration             |
-     *  |       ?       |? 0|    0      |              ?                |
-     *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     * 
- * - * @param code the digit to transmit 0-15 - * @param end boolean used to mark the two last packets - * @param duration int increments for each dtmf sending - * updates, stay unchanged at the end for the 2 last packets. - */ - private void setDtmfPayload(int code, boolean end, int duration) - { - this.code = code; - this.end = end; - this.duration = duration; - - int at = getHeaderLength(); - - writeByte(at++, (byte)code); - writeByte(at++, end ? (byte)0x80 : (byte)0); - writeByte(at++, (byte)(duration >> 8)); - writeByte(at++, (byte)duration); - } - - /** - * The event code of the current packet. - * @return the code - */ - public int getCode() - { - return code; - } - - /** - * Is this an end packet. - * @return the end - */ - public boolean isEnd() - { - return end; - } - - /** - * The duration of the current event. - * @return the duration - */ - public int getDuration() - { - return duration; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/dtmf/DtmfTransformEngine.java b/src/net/java/sip/communicator/impl/neomedia/transform/dtmf/DtmfTransformEngine.java deleted file mode 100644 index 712469a0c..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/dtmf/DtmfTransformEngine.java +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform.dtmf; - -import javax.media.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.impl.neomedia.transform.*; -import net.java.sip.communicator.service.neomedia.*; - -/** - * The class is responsible for sending DTMF tones in an RTP audio stream as - * described by RFC4733. - * - * @author Emil Ivov - * @author Romain Philibert - * @author Damian Minkov - */ -public class DtmfTransformEngine - implements TransformEngine, - PacketTransformer -{ - - /** - * The AudioMediaStreamImpl that this transform engine was created - * by and that it's going to deliver DTMF packets for. - */ - private final AudioMediaStreamImpl mediaStream; - - /** - * The enumeration contains a set of states that reflect the progress of - */ - private enum ToneTransmissionState - { - /** - * Indicates that this engine is not currently sending DTMF. - */ - IDLE, - - /** - * Indicates that the user has just called the {@link - * #startSending(DTMFRtpTone)} method and we haven't yet sent any of the - * packets corresponding to that particular tone. - */ - SEND_PENDING, - - /** - * Indicates that we are currently in the process of sending a DTMF - * tone, and we have already sent at least one packet. - */ - SENDING, - - /** - * Indicates that the user has requested that DTMF transmission be - * stopped but we haven't acted upon that request yet (i.e. we have yet - * to send a single retransmission) - */ - END_REQUESTED, - - /** - * Indicates that the user has requested that DTMF transmission be - * stopped we have already sent a retransmission of the final packet. - */ - END_SEQUENCE_INITIATED - }; - - /** - * Array of all supported tones. - */ - private static final DTMFRtpTone[] supportedTones = - new DTMFRtpTone[] - {DTMFRtpTone.DTMF_0, DTMFRtpTone.DTMF_1, DTMFRtpTone.DTMF_2, - DTMFRtpTone.DTMF_3, DTMFRtpTone.DTMF_4, DTMFRtpTone.DTMF_5, - DTMFRtpTone.DTMF_6, DTMFRtpTone.DTMF_7, DTMFRtpTone.DTMF_8, - DTMFRtpTone.DTMF_9, DTMFRtpTone.DTMF_A, DTMFRtpTone.DTMF_B, - DTMFRtpTone.DTMF_C, DTMFRtpTone.DTMF_D, DTMFRtpTone.DTMF_SHARP, - DTMFRtpTone.DTMF_STAR}; - - /** - * The dispatcher that is delivering tones to the media steam. - */ - private DTMFDispatcher dtmfDispatcher = null; - - /** - * The status that this engine is currently in. - */ - private ToneTransmissionState toneTransmissionState - = ToneTransmissionState.IDLE; - - /** - * The tone that we are supposed to be currently transmitting. - */ - private DTMFRtpTone currentTone = null; - - /** - * The duration (in timestamp units or in other words ms*8) that we have - * transmitted the current tone for. - */ - private int currentDuration = 0; - - /** - * The current transmitting timestamp. - */ - private long currentTimestamp = 0; - - /** - * We send 3 end packets and this is the counter of remaining packets. - */ - private int remainingsEndPackets = 0; - - /** - * Current duration of every event we send. - */ - private int currentSpacingDuration = Format.NOT_SPECIFIED; - - /** - * Creates an engine instance that will be replacing audio packets - * with DTMF ones upon request. - * - * @param stream the AudioMediaStream whose RTP packets we are - * going to be replacing with DTMF. - */ - public DtmfTransformEngine(AudioMediaStreamImpl stream) - { - this.mediaStream = stream; - } - - /** - * Close the transformer and underlying transform engine. - * - * Nothing to do here. - */ - public void close() - { - } - - /** - * Gets the current duration of every event we send. - * - * @return the current duration of every event we send - */ - private int getCurrentSpacingDuration() - { - if (currentSpacingDuration == Format.NOT_SPECIFIED) - { - // the default is 50 ms. RECOMMENDED in rfc4733. - currentSpacingDuration - = (int) mediaStream.getFormat().getClockRate()/50; - } - return currentSpacingDuration; - } - /** - * Always returns null since this engine does not require any - * RTCP transformations. - * - * @return null since this engine does not require any - * RTCP transformations. - */ - public PacketTransformer getRTCPTransformer() - { - return null; - } - - /** - * Returns a reference to this class since it is performing RTP - * transformations in here. - * - * @return a reference to this instance of the - * DtmfTransformEngine. - */ - public PacketTransformer getRTPTransformer() - { - return this; - } - - /** - * A stub meant to handle incoming DTMF packets. - * - * @param pkt an incoming packet that we need to parse and handle in case - * we determine it to be DTMF. - * - * @return the pkt if it is not a DTMF tone and null - * otherwise since we will be handling the packet ourselves and their's - * no point in feeding it to the application. - */ - public RawPacket reverseTransform(RawPacket pkt) - { - byte currentDtmfPayload = mediaStream.getDynamicRTPPayloadType( - Constants.TELEPHONE_EVENT); - - if(currentDtmfPayload == pkt.getPayloadType()) - { - DtmfRawPacket p = new DtmfRawPacket(pkt); - - if (dtmfDispatcher == null) - { - dtmfDispatcher = new DTMFDispatcher(); - new Thread(dtmfDispatcher).start(); - } - dtmfDispatcher.addTonePacket(p); - - // ignore received dtmf packets - // if jmf receive change in rtp payload stops reception - return null; - } - - return pkt; - } - - /** - * Replaces pkt with a DTMF packet if this engine is in a DTMF - * transmission mode or returns it unchanged otherwise. - * - * @param pkt the audio packet that we may want to replace with a DTMF one. - * - * @return pkt with a DTMF packet if this engine is in a DTMF - * transmission mode or returns it unchanged otherwise. - */ - public RawPacket transform(RawPacket pkt) - { - if (this.toneTransmissionState.equals(ToneTransmissionState.IDLE) - || currentTone == null) - { - return pkt; - } - - byte currentDtmfPayload = mediaStream.getDynamicRTPPayloadType( - Constants.TELEPHONE_EVENT); - - if ( currentDtmfPayload == -1 ) - throw new IllegalStateException("Can't send DTMF when no payload " - +"type has been negotiated for DTMF events."); - - DtmfRawPacket dtmfPkt = new DtmfRawPacket(pkt.getBuffer(), - pkt.getOffset(), currentDtmfPayload); - - long audioPacketTimestamp = dtmfPkt.getTimestamp(); - boolean pktEnd = false; - boolean pktMarker = false; - int pktDuration = 0; - - if(toneTransmissionState == ToneTransmissionState.SEND_PENDING) - { - currentDuration = 0; - currentDuration += getCurrentSpacingDuration(); - pktDuration = currentDuration; - - pktMarker = true; - currentTimestamp = audioPacketTimestamp; - - toneTransmissionState = ToneTransmissionState.SENDING; - } - else if(toneTransmissionState == ToneTransmissionState.SENDING) - { - currentDuration += getCurrentSpacingDuration(); - pktDuration = currentDuration; - // Check for long state event - if (currentDuration > 0xFFFF) - { - // When duration > 0xFFFF we first send a packet with - // duration = 0xFFFF. For the next packet, the duration - // start from begining but the audioPacketTimestamp is set to the - // time when the long duration event occurs. - pktDuration = 0xFFFF; - currentDuration = 0; - currentTimestamp = audioPacketTimestamp; - } - } - else if(toneTransmissionState == ToneTransmissionState.END_REQUESTED) - { - // The first ending packet do have the End flag set. - // But the 2 next will have the End flag set. - // - // The audioPacketTimestamp and the duration field stay unchanged for - // the 3 last packets - currentDuration += getCurrentSpacingDuration(); - pktDuration = currentDuration; - - pktEnd = true; - remainingsEndPackets = 2; - - toneTransmissionState = ToneTransmissionState.END_SEQUENCE_INITIATED; - } - else if(toneTransmissionState == ToneTransmissionState.END_SEQUENCE_INITIATED) - { - pktEnd = true; - pktDuration = currentDuration; - remainingsEndPackets--; - - if(remainingsEndPackets == 0) - toneTransmissionState = ToneTransmissionState.IDLE; - } - - dtmfPkt.init( - currentTone.getCode(), - pktEnd, - pktMarker, - pktDuration, - currentTimestamp); - pkt = dtmfPkt; - - return pkt; - } - - - /** - * DTMF sending stub: this is where we should set the transformer in the - * proper state so that it would start replacing packets with dtmf codes. - * - * @param tone the tone that we'd like to start sending. - */ - public void startSending(DTMFRtpTone tone) - { - if(toneTransmissionState != ToneTransmissionState.IDLE) - throw new IllegalStateException( - "Calling start before stopping previous transmission"); - - currentTone = tone; - toneTransmissionState = ToneTransmissionState.SEND_PENDING; - } - - /** - * Interrupts transmission of a DTMFRtpTone started with the - * startSendingDTMF() method. Has no effect if no tone is currently - * being sent. - * - * @see AudioMediaStream#stopSendingDTMF(DTMFMethod dtmfMethod) - */ - public void stopSendingDTMF() - { - toneTransmissionState = ToneTransmissionState.END_REQUESTED; - } - - /** - * Stops threads that this transform engine is using for even delivery. - */ - public void stop() - { - if(dtmfDispatcher != null) - dtmfDispatcher.stop(); - } - - /** - * A simple thread that waits for new tones to be reported from incoming - * RTP packets and then delivers them to the AudioMediaStream - * associated with this engine. The reason we need to do this in a separate - * thread is of course the time sensitive nature of incoming RTP packets. - */ - private class DTMFDispatcher - implements Runnable - { - /** Indicates whether this thread is supposed to be running */ - private boolean isRunning = false; - - /** The tone that we last received from the reverseTransform thread*/ - private DTMFRtpTone lastReceivedTone = null; - - /** The tone that we last received from the reverseTransform thread*/ - private DTMFRtpTone lastReportedTone = null; - - /** - * Have we received end of the currently started tone. - */ - private boolean toEnd = false; - - /** - * Waits for new tone to be reported via the addTonePacket() - * method and then delivers them to the AudioMediaStream that - * we are associated with. - */ - public void run() - { - isRunning = true; - - DTMFRtpTone temp = null; - - while(isRunning) - { - synchronized(this) - { - if(lastReceivedTone == null) - { - try - { - wait(); - } - catch (InterruptedException ie) {} - } - - temp = lastReceivedTone; - // make lastReportedLevels to null - // so we will wait for the next tone on next iteration - lastReceivedTone = null; - } - - if(temp != null - && ((lastReportedTone == null && !toEnd) - || (lastReportedTone != null && toEnd))) - { - //now notify our listener - if (mediaStream != null) - { - mediaStream.fireDTMFEvent(temp, toEnd); - if(toEnd) - lastReportedTone = null; - else - lastReportedTone = temp; - toEnd = false; - } - } - } - } - - /** - * A packet that we should convert to tone and deliver - * to our media stream and its listeners in a separate thread. - * - * @param p the packet we will convert and deliver. - */ - public void addTonePacket(DtmfRawPacket p) - { - synchronized(this) - { - this.lastReceivedTone = getToneFromPacket(p); - this.toEnd = p.isEnd(); - - notifyAll(); - } - } - - /** - * Causes our run method to exit so that this thread would stop - * handling levels. - */ - public void stop() - { - synchronized(this) - { - this.lastReceivedTone = null; - isRunning = false; - - notifyAll(); - } - } - - /** - * Maps DTMF packet codes to our DTMFRtpTone objects. - * @param p the packet - * @return the corresponding tone. - */ - private DTMFRtpTone getToneFromPacket(DtmfRawPacket p) - { - for (int i = 0; i < supportedTones.length; i++) - { - DTMFRtpTone t = supportedTones[i]; - if(t.getCode() == p.getCode()) - return t; - } - - return null; - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/rtcp/StatisticsEngine.java b/src/net/java/sip/communicator/impl/neomedia/transform/rtcp/StatisticsEngine.java deleted file mode 100644 index f9d02615c..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/rtcp/StatisticsEngine.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform.rtcp; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.transform.*; -import net.java.sip.communicator.service.neomedia.format.*; -import net.java.sip.communicator.util.*; -import net.sf.fmj.media.rtp.*; - -/** - * Engine which don't transform packets, just listens for outgoing - * RTCP Packets and logs and stores statistical data for the stream. - * - * @author Damian Minkov - */ -public class StatisticsEngine - implements TransformEngine, - PacketTransformer -{ - /** - * The Logger used by the StatisticsEngine class - * and its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(StatisticsEngine.class); - - /** - * The rtp statistics prefix we use for every log. - * Simplifies parsing and searching for statistics info in log files. - */ - public static final String RTP_STAT_PREFIX = "rtpstat:"; - - /** - * Number of sender reports send. - * Used only for logging and debug purposes. - */ - private long numberOfSenderReports = 0; - - /** - * The minimum inter arrival jitter value we have reported. - */ - private long maxInterArrivalJitter = 0; - - /** - * The minimum inter arrival jitter value we have reported. - */ - private long minInterArrivalJitter = -1; - - /** - * Number of lost packets reported. - */ - private long lost = 0; - - /** - * The stream created us. - */ - private MediaStreamImpl mediaStream; - - /** - * Creates Statistic engine. - * @param stream the stream creating us. - */ - public StatisticsEngine(MediaStreamImpl stream) - { - this.mediaStream = stream; - } - - /** - * Close the transformer and underlying transform engine. - * - * Nothing to do here. - */ - public void close() - { - } - - /** - * Transfers RTCP sender report feedback as new information about the - * download stream for the MediaStreamStats. - * Finds the info needed for statistics in the packet and stores it. - * Then returns the same packet as we are not modifying it. - * - * @param pkt the packet - * @return the packet - */ - public RawPacket transform(RawPacket pkt) - { - try - { - numberOfSenderReports++; - - byte[] data = pkt.getBuffer(); - int offset = pkt.getOffset(); - int length = pkt.getLength(); - - RTCPHeader header = new RTCPHeader( - data, offset, length); - if (header.getPacketType() == RTCPPacket.SR) - { - RTCPSenderReport report = new RTCPSenderReport( - data, offset, length); - - if(report.getFeedbackReports().size() > 0) - { - RTCPFeedback feedback = - (RTCPFeedback)report.getFeedbackReports().get(0); - - this.mediaStream.getMediaStreamStats() - .updateNewSentFeedback(feedback); - - // The rest of this function is only used for logging - // purpose. Thus, it is useless to continue if the - // logger is not at least in INFO mode. - if(!logger.isInfoEnabled()) - return pkt; - - long jitter = feedback.getJitter(); - - if(jitter < getMinInterArrivalJitter() - || getMinInterArrivalJitter() == -1) - minInterArrivalJitter = jitter; - - if(getMaxInterArrivalJitter() < jitter) - maxInterArrivalJitter = jitter; - - lost = feedback.getNumLost(); - - // As sender reports are sent on every 5 seconds, print - // every 4th packet, on every 20 seconds. - if(numberOfSenderReports % 4 != 1) - return pkt; - - StringBuilder buff = new StringBuilder(RTP_STAT_PREFIX); - MediaFormat mediaStreamFormat = mediaStream.getFormat(); - - buff.append("Sending a report for ") - .append(mediaStreamFormat != null - ? mediaStreamFormat.getMediaType() - : "") - .append(" stream SSRC:") - .append(feedback.getSSRC()) - .append(" [packet count:") - .append(report.getSenderPacketCount()) - .append(", bytes:").append(report.getSenderByteCount()) - .append(", interarrival jitter:") - .append(jitter) - .append(", lost packets:").append(feedback.getNumLost()) - .append(", time since previous report:") - .append((int) (feedback.getDLSR() / 65.536)) - .append("ms ]"); - logger.info(buff); - } - } - } - catch(Throwable t) - { - t.printStackTrace(); - } - - return pkt; - } - - /** - * Transfers RTCP sender report feedback as new information about the upload - * stream for the MediaStreamStats. - * Returns the packet as we are listening just for sending packages. - * - * @param pkt the packet without any change. - * @return the packet without any change. - */ - public RawPacket reverseTransform(RawPacket pkt) - { - try - { - byte[] data = pkt.getBuffer(); - int offset = pkt.getOffset(); - int length = pkt.getLength(); - - if(length - offset != 0) - { - RTCPHeader header = new RTCPHeader(data, offset, length); - if (header.getPacketType() == RTCPPacket.SR) - { - RTCPSenderReport report = new RTCPSenderReport( - data, offset, length); - - if(report.getFeedbackReports().size() > 0) - { - RTCPFeedback feedback = - (RTCPFeedback)report.getFeedbackReports().get(0); - - this.mediaStream.getMediaStreamStats() - .updateNewReceivedFeedback(feedback); - } - } - } - } - catch(Throwable t) - { - t.printStackTrace(); - } - return pkt; - } - - /** - * Always returns null since this engine does not require any - * RTP transformations. - * - * @return null since this engine does not require any - * RTP transformations. - */ - public PacketTransformer getRTPTransformer() - { - return null; - } - - /** - * Returns a reference to this class since it is performing RTP - * transformations in here. - * - * @return a reference to this instance of the - * StatisticsEngine. - */ - public PacketTransformer getRTCPTransformer() - { - return this; - } - - /** - * The minimum inter arrival jitter value we have reported. - * @return minimum inter arrival jitter value we have reported. - */ - public long getMaxInterArrivalJitter() - { - return maxInterArrivalJitter; - } - - /** - * The maximum inter arrival jitter value we have reported. - * @return maximum inter arrival jitter value we have reported. - */ - public long getMinInterArrivalJitter() - { - return minInterArrivalJitter; - } - - /** - * Number of lost packets reported. - * @return number of lost packets reported. - */ - public long getLost() - { - return lost; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/sdes/SDesControlImpl.java b/src/net/java/sip/communicator/impl/neomedia/transform/sdes/SDesControlImpl.java deleted file mode 100644 index 8c282e7ea..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/sdes/SDesControlImpl.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform.sdes; - -import gnu.java.zrtp.utils.ZrtpFortuna; - -import java.util.*; - -import ch.imvs.sdes4j.srtp.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.transform.*; -import net.java.sip.communicator.impl.neomedia.transform.zrtp.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.event.*; - -/** - * Default implementation of {@link SDesControl} that supports the crypto suites - * of the original RFC4568 and the KDR parameter, but nothing else. - * - * @author Ingo Bauersachs - */ -public class SDesControlImpl - implements SDesControl -{ - /** - * List of enabled crypto suites. - */ - private List enabledCryptoSuites = new ArrayList(3) - { - private static final long serialVersionUID = 0L; - - { - add(SrtpCryptoSuite.AES_CM_128_HMAC_SHA1_80); - add(SrtpCryptoSuite.AES_CM_128_HMAC_SHA1_32); - add(SrtpCryptoSuite.F8_128_HMAC_SHA1_80); - } - }; - - - /** - * List of supported crypto suites. - */ - private final List supportedCryptoSuites = new ArrayList(3) - { - private static final long serialVersionUID = 0L; - - { - add(SrtpCryptoSuite.AES_CM_128_HMAC_SHA1_80); - add(SrtpCryptoSuite.AES_CM_128_HMAC_SHA1_32); - add(SrtpCryptoSuite.F8_128_HMAC_SHA1_80); - } - }; - - private SrtpSDesFactory sdesFactory; - private SrtpCryptoAttribute[] attributes; - private SDesTransformEngine engine; - private SrtpCryptoAttribute selectedInAttribute; - private SrtpCryptoAttribute selectedOutAttribute; - private SrtpListener srtpListener; - - /** - * SDESControl - */ - public SDesControlImpl() - { - sdesFactory = new SrtpSDesFactory(); - Random r = new Random() - { - private static final long serialVersionUID = 0L; - - @Override - public void nextBytes(byte[] bytes) - { - ZrtpFortuna.getInstance().getFortuna().nextBytes(bytes); - } - }; - sdesFactory.setRandomGenerator(r); - } - - public void setEnabledCiphers(Iterable ciphers) - { - enabledCryptoSuites.clear(); - for(String c : ciphers) - enabledCryptoSuites.add(c); - } - - public Iterable getSupportedCryptoSuites() - { - return Collections.unmodifiableList(supportedCryptoSuites); - } - - public void cleanup() - { - if (engine != null) - { - engine.close(); - engine = null; - } - } - - public void setSrtpListener(SrtpListener srtpListener) - { - this.srtpListener = srtpListener; - } - - public SrtpListener getSrtpListener() - { - return srtpListener; - } - - public boolean getSecureCommunicationStatus() - { - return engine != null; - } - - /** - * Not used. - * @param masterSession not used. - */ - public void setMasterSession(boolean masterSession) - {} - - public void start(MediaType type) - { - // in srtp the started and security event is one after another - // in some other security mechanisms (e.g. zrtp) there can be started - // and no security one or security timeout event - srtpListener.securityNegotiationStarted( - type.equals(MediaType.AUDIO) ? - SecurityEventManager.AUDIO_SESSION - : SecurityEventManager.VIDEO_SESSION, - this); - - srtpListener.securityTurnedOn( - type.equals(MediaType.AUDIO) ? - SecurityEventManager.AUDIO_SESSION - : SecurityEventManager.VIDEO_SESSION, - selectedInAttribute.getCryptoSuite().encode(), this); - } - - public void setMultistream(SrtpControl master) - { - } - - public TransformEngine getTransformEngine() - { - if(engine == null) - engine = new SDesTransformEngine(this); - return engine; - } - - public String[] getInitiatorCryptoAttributes() - { - if(attributes == null) - { - attributes = new SrtpCryptoAttribute[enabledCryptoSuites.size()]; - for (int i = 0; i < attributes.length; i++) - { - attributes[i] = - sdesFactory.createCryptoAttribute(i + 1, - enabledCryptoSuites.get(i)); - } - } - String[] result = new String[attributes.length]; - for(int i = 0; i < attributes.length; i++) - result[i] = attributes[i].encode(); - return result; - } - - public String responderSelectAttribute(Iterable peerAttributes) - { - for (String suite : enabledCryptoSuites) - { - for (String ea : peerAttributes) - { - SrtpCryptoAttribute peerCA = SrtpCryptoAttribute.create(ea); - if (suite.equals(peerCA.getCryptoSuite().encode())) - { - selectedInAttribute = peerCA; - selectedOutAttribute = - sdesFactory.createCryptoAttribute(1, suite); - return selectedOutAttribute.encode(); - } - } - } - return null; - } - - public boolean initiatorSelectAttribute(Iterable peerAttributes) - { - for (SrtpCryptoAttribute localCA : attributes) - { - for (String ea : peerAttributes) - { - SrtpCryptoAttribute peerCA = SrtpCryptoAttribute.create(ea); - if (localCA.getCryptoSuite().equals(peerCA.getCryptoSuite())) - { - selectedInAttribute = peerCA; - selectedOutAttribute = localCA; - return true; - } - } - } - return false; - } - - public SrtpCryptoAttribute getInAttribute() - { - return selectedInAttribute; - } - - public SrtpCryptoAttribute getOutAttribute() - { - return selectedOutAttribute; - } - - public void setConnector(AbstractRTPConnector newValue) - { - } - - /** - * Returns true, SDES always requires the secure transport of its keys. - * - * @return true - */ - public boolean requiresSecureSignalingTransport() - { - return true; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/sdes/SDesTransformEngine.java b/src/net/java/sip/communicator/impl/neomedia/transform/sdes/SDesTransformEngine.java deleted file mode 100644 index 0263e64a9..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/sdes/SDesTransformEngine.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform.sdes; - -import ch.imvs.sdes4j.srtp.*; - -import net.java.sip.communicator.impl.neomedia.transform.srtp.*; - -/** - * PacketTransformer for SDES based SRTP encryption. - * - * @author Ingo Bauersachs - */ -public class SDesTransformEngine - extends AsymmetricSRTPTransformer -{ - /** - * Creates a new instance of this class. - * @param sDesControl The control that supplies the key material. - */ - public SDesTransformEngine(SDesControlImpl sDesControl) - { - super( - getTransformEngine(sDesControl.getOutAttribute()), - getTransformEngine(sDesControl.getInAttribute()) - ); - } - - private static SRTPTransformEngine getTransformEngine( - SrtpCryptoAttribute attribute) - { - if (attribute.getSessionParams() != null - && attribute.getSessionParams().length > 0) - { - throw new IllegalArgumentException( - "session parameters are not supported"); - } - - SrtpCryptoSuite cs = attribute.getCryptoSuite(); - return new SRTPTransformEngine( - getKey(attribute), - getSalt(attribute), - new SRTPPolicy( - getEncryptionCipher(cs), cs.getEncKeyLength() / 8, - getHashAlgorithm(cs), cs.getSrtpAuthKeyLength() / 8, - cs.getSrtpAuthTagLength() / 8, - cs.getSaltKeyLength() / 8 - ), - new SRTPPolicy( - getEncryptionCipher(cs), cs.getEncKeyLength() / 8, - getHashAlgorithm(cs), cs.getSrtcpAuthKeyLength() / 8, - cs.getSrtcpAuthTagLength() / 8, - cs.getSaltKeyLength() / 8 - ) - ); - } - -// /** -// * Get the key derivation parameter or the default from the SDES attribute. -// * @param attribute The negotiated SDES attribute for the stream. -// * @return The KDR parameter or 0 if not present. -// */ -// private static long getKdr(SrtpCryptoAttribute attribute) -// { -// if (attribute.getSessionParams() != null) -// { -// for (SrtpSessionParam param : attribute.getSessionParams()) -// { -// if (param instanceof KdrSessionParam) -// return ((KdrSessionParam) param) -// .getKeyDerivationRateExpanded(); -// } -// } -// return 0; -// } - - private static byte[] getKey(SrtpCryptoAttribute attribute) - { - int length = attribute.getCryptoSuite().getEncKeyLength() / 8; - byte[] key = new byte[length]; - System.arraycopy(attribute.getKeyParams()[0].getKey(), 0, key, 0, - length); - return key; - } - - private static byte[] getSalt(SrtpCryptoAttribute attribute) - { - int keyLength = attribute.getCryptoSuite().getEncKeyLength() / 8; - int saltLength = attribute.getCryptoSuite().getSaltKeyLength() / 8; - byte[] salt = new byte[keyLength]; - System.arraycopy(attribute.getKeyParams()[0].getKey(), keyLength, salt, - 0, saltLength); - return salt; - } - - private static int getEncryptionCipher(SrtpCryptoSuite cs) - { - switch (cs.getEncryptionAlgorithm()) - { - case SrtpCryptoSuite.ENCRYPTION_AES128_CM: - return SRTPPolicy.AESCM_ENCRYPTION; - case SrtpCryptoSuite.ENCRYPTION_AES128_F8: - return SRTPPolicy.AESF8_ENCRYPTION; - default: - throw new IllegalArgumentException("Unsupported cipher"); - } - } - - private static int getHashAlgorithm(SrtpCryptoSuite cs) - { - switch (cs.getHashAlgorithm()) - { - case SrtpCryptoSuite.HASH_HMAC_SHA1: - return SRTPPolicy.HMACSHA1_AUTHENTICATION; - default: - throw new IllegalArgumentException("Unsupported hash"); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/AsymmetricSRTPTransformer.java b/src/net/java/sip/communicator/impl/neomedia/transform/srtp/AsymmetricSRTPTransformer.java deleted file mode 100644 index 507915c11..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/AsymmetricSRTPTransformer.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform.srtp; - -import net.java.sip.communicator.impl.neomedia.transform.*; - -/** - * SRTP/SRTCP TransformEngine that uses different keys for forward and reverse - * transformations. - * - * @author Ingo Bauersachs - */ -public class AsymmetricSRTPTransformer - implements TransformEngine -{ - private SRTPTransformEngine forwardEngine; - private SRTPTransformEngine reverseEngine; - - public AsymmetricSRTPTransformer(SRTPTransformEngine forwardEngine, - SRTPTransformEngine reverseEngine) - { - this.forwardEngine = forwardEngine; - this.reverseEngine = reverseEngine; - } - - /** - * Close the transformer engine. - * - * The close functions closes all stored default crypto contexts. This - * deletes key data and forces a cleanup of the crypto contexts. - */ - public void close() - { - if (forwardEngine != null) - forwardEngine.close(); - if (reverseEngine != null) - reverseEngine.close(); - - forwardEngine = null; - reverseEngine = null; - } - /* - * (non-Javadoc) - * - * @see - * net.java.sip.communicator.impl.neomedia.transform.srtp.SRTPTransformEngine - * #getRTCPTransformer() - */ - public PacketTransformer getRTCPTransformer() - { - return new SRTCPTransformer(forwardEngine, reverseEngine); - } - - /* - * (non-Javadoc) - * - * @see - * net.java.sip.communicator.impl.neomedia.transform.srtp.SRTPTransformEngine - * #getRTPTransformer() - */ - public PacketTransformer getRTPTransformer() - { - return new SRTPTransformer(forwardEngine, reverseEngine); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTCPCryptoContext.java b/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTCPCryptoContext.java deleted file mode 100644 index 9edddce6b..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTCPCryptoContext.java +++ /dev/null @@ -1,710 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - * - * - * Some of the code in this class is derived from ccRtp's SRTP implementation, - * which has the following copyright notice: - * - Copyright (C) 2004-2006 the Minisip Team - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -package net.java.sip.communicator.impl.neomedia.transform.srtp; - -import java.util.Arrays; - -import net.java.sip.communicator.impl.neomedia.*; - -import org.bouncycastle.crypto.digests.SHA1Digest; -import org.bouncycastle.crypto.macs.*; -import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.crypto.params.ParametersForSkein; -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.Mac; - -import org.bouncycastle.crypto.engines.AESFastEngine; -import org.bouncycastle.crypto.engines.TwofishEngine; - - -/** - * SRTPCryptoContext class is the core class of SRTP implementation. - * There can be multiple SRTP sources in one SRTP session. And each SRTP stream - * has a corresponding SRTPCryptoContext object, identified by SSRC. In this - * way, different sources can be protected independently. - * - * SRTPCryptoContext class acts as a manager class and maintains all the - * information used in SRTP transformation. It is responsible for deriving - * encryption keys / salting keys / authentication keys from master keys. And - * it will invoke certain class to encrypt / decrypt (transform / reverse - * transform) RTP packets. It will hold a replay check db and do replay check - * against incoming packets. - * - * Refer to section 3.2 in RFC3711 for detailed description of cryptographic - * context. - * - * Cryptographic related parameters, i.e. encryption mode / authentication mode, - * master encryption key and master salt key are determined outside the scope - * of SRTP implementation. They can be assigned manually, or can be assigned - * automatically using some key management protocol, such as MIKEY (RFC3830) or - * Phil Zimmermann's ZRTP protocol. - * - * @author Bing SU (nova.su@gmail.com) - */ -public class SRTCPCryptoContext -{ - /** - * The replay check windows size - */ - private static final long REPLAY_WINDOW_SIZE = 64; - - /** - * RTCP SSRC of this cryptographic context - */ - private long ssrcCtx; - - /** - * Master key identifier - */ - private byte[] mki; - - /** - * Index received so far - */ - private int receivedIndex = 0; - - /** - * Index sent so far - */ - private int sentIndex = 0; - - /** - * Bit mask for replay check - */ - private long replayWindow; - - /** - * Master encryption key - */ - private byte[] masterKey; - - /** - * Master salting key - */ - private byte[] masterSalt; - - /** - * Derived session encryption key - */ - private byte[] encKey; - - /** - * Derived session authentication key - */ - private byte[] authKey; - - /** - * Derived session salting key - */ - private byte[] saltKey; - - /** - * Encryption / Authentication policy for this session - */ - private final SRTPPolicy policy; - - /** - * The HMAC object we used to do packet authentication - */ - private Mac mac; // used for various HMAC computations - - // The symmetric cipher engines we need here - private BlockCipher cipher = null; - private BlockCipher cipherF8 = null; // used inside F8 mode only - - // implements the counter cipher mode for RTP according to RFC 3711 - private final SRTPCipherCTR cipherCtr = new SRTPCipherCTR(); - - // Here some fields that a allocated here or in constructor. The methods - // use these fields to avoid too many new operations - - private final byte[] tagStore; - private final byte[] ivStore = new byte[16]; - private final byte[] rbStore = new byte[4]; - - // this is some working store, used by some methods to avoid new operations - // the methods must use this only to store some reults for immediate processing - private final byte[] tempStore = new byte[100]; - - /** - * Construct an empty SRTPCryptoContext using ssrc. - * The other parameters are set to default null value. - * - * @param ssrc SSRC of this SRTPCryptoContext - */ - public SRTCPCryptoContext(long ssrcIn) - { - ssrcCtx = ssrcIn; - mki = null; - masterKey = null; - masterSalt = null; - encKey = null; - authKey = null; - saltKey = null; - policy = null; - tagStore = null; - } - - /** - * Construct a normal SRTPCryptoContext based on the given parameters. - * - * @param ssrc - * the RTP SSRC that this SRTP cryptographic context protects. - * @param masterKey - * byte array holding the master key for this SRTP cryptographic - * context. Refer to chapter 3.2.1 of the RFC about the role of - * the master key. - * @param masterSalt - * byte array holding the master salt for this SRTP cryptographic - * context. It is used to computer the initialization vector that - * in turn is input to compute the session key, session - * authentication key and the session salt. - * @param policy - * SRTP policy for this SRTP cryptographic context, defined the - * encryption algorithm, the authentication algorithm, etc - */ - @SuppressWarnings("fallthrough") - public SRTCPCryptoContext(long ssrcIn, - byte[] masterK, byte[] masterS, SRTPPolicy policyIn) - { - ssrcCtx = ssrcIn; - mki = null; - - policy = policyIn; - - masterKey = new byte[policy.getEncKeyLength()]; - System.arraycopy(masterK, 0, masterKey, 0, policy - .getEncKeyLength()); - - masterSalt = new byte[policy.getSaltKeyLength()]; - System.arraycopy(masterS, 0, masterSalt, 0, policy - .getSaltKeyLength()); - - switch (policy.getEncType()) { - case SRTPPolicy.NULL_ENCRYPTION: - encKey = null; - saltKey = null; - break; - - case SRTPPolicy.AESF8_ENCRYPTION: - cipherF8 = new AESFastEngine(); - - case SRTPPolicy.AESCM_ENCRYPTION: - cipher = new AESFastEngine(); - encKey = new byte[this.policy.getEncKeyLength()]; - saltKey = new byte[this.policy.getSaltKeyLength()]; - break; - - case SRTPPolicy.TWOFISHF8_ENCRYPTION: - cipherF8 = new TwofishEngine(); - - case SRTPPolicy.TWOFISH_ENCRYPTION: - cipher = new TwofishEngine(); - encKey = new byte[this.policy.getEncKeyLength()]; - saltKey = new byte[this.policy.getSaltKeyLength()]; - break; - } - - switch (policy.getAuthType()) { - case SRTPPolicy.NULL_AUTHENTICATION: - authKey = null; - tagStore = null; - break; - - case SRTPPolicy.HMACSHA1_AUTHENTICATION: - mac = new HMac(new SHA1Digest()); - authKey = new byte[policy.getAuthKeyLength()]; - tagStore = new byte[mac.getMacSize()]; - break; - - case SRTPPolicy.SKEIN_AUTHENTICATION: - mac = new SkeinMac(); - authKey = new byte[policy.getAuthKeyLength()]; - tagStore = new byte[policy.getAuthTagLength()]; - break; - - default: - tagStore = null; - } - } - - /** - * Close the crypto context. - * - * The close functions deletes key data and performs a cleanup of the - * crypto context. - * - * Clean up key data, maybe this is the second time. However, sometimes - * we cannot know if the CryptoContext was used and the application called - * deriveSrtpKeys(...) tah would have cleaned the key data. - * - */ - public void close() - { - Arrays.fill(masterKey, (byte)0); - Arrays.fill(masterSalt, (byte)0); - } - - /** - * Get the authentication tag length of this SRTP cryptographic context - * - * @return the authentication tag length of this SRTP cryptographic context - */ - public int getAuthTagLength() - { - return policy.getAuthTagLength(); - } - - /** - * Get the MKI length of this SRTP cryptographic context - * - * @return the MKI length of this SRTP cryptographic context - */ - public int getMKILength() - { - if (mki != null) - return mki.length; - return 0; - } - - /** - * Get the SSRC of this SRTP cryptographic context - * - * @return the SSRC of this SRTP cryptographic context - */ - public long getSSRC() - { - return ssrcCtx; - } - - /** - * Transform a RTP packet into a SRTP packet. - * This method is called when a normal RTP packet ready to be sent. - * - * Operations done by the transformation may include: encryption, using - * either Counter Mode encryption, or F8 Mode encryption, adding - * authentication tag, currently HMC SHA1 method. - * - * Both encryption and authentication functionality can be turned off - * as long as the SRTPPolicy used in this SRTPCryptoContext is requires no - * encryption and no authentication. Then the packet will be sent out - * untouched. However this is not encouraged. If no SRTP feature is enabled, - * then we shall not use SRTP TransformConnector. We should use the original - * method (RTPManager managed transportation) instead. - * - * @param pkt the RTP packet that is going to be sent out - */ - public void transformPacket(RawPacket pkt) - { - boolean encrypt = false; - /* Encrypt the packet using Counter Mode encryption */ - if (policy.getEncType() == SRTPPolicy.AESCM_ENCRYPTION || - policy.getEncType() == SRTPPolicy.TWOFISH_ENCRYPTION) - { - processPacketAESCM(pkt, sentIndex); - encrypt = true; - } - - /* Encrypt the packet using F8 Mode encryption */ - else if (policy.getEncType() == SRTPPolicy.AESF8_ENCRYPTION || - policy.getEncType() == SRTPPolicy.TWOFISHF8_ENCRYPTION) - { - processPacketAESF8(pkt, sentIndex); - encrypt = true; - } - int index = 0; - if (encrypt) - index = sentIndex | 0x80000000; - - // Grow packet storage in one step - pkt.grow(4 + policy.getAuthTagLength()); - - // Authenticate the packet - // The authenticate method gets the index via parameter and stores - // it in network order in rbStore variable. - if (policy.getAuthType() != SRTPPolicy.NULL_AUTHENTICATION) - { - authenticatePacket(pkt, index); - pkt.append(rbStore, 4); - pkt.append(tagStore, policy.getAuthTagLength()); - } - sentIndex++; - sentIndex &= ~0x80000000; // clear possible overflow - } - - /** - * Transform a SRTCP packet into a RTCP packet. - * This method is called when a SRTCP packet was received. - * - * Operations done by the this operation include: - * Authentication check, Packet replay check and decryption. - * - * Both encryption and authentication functionality can be turned off - * as long as the SRTPPolicy used in this SRTPCryptoContext requires no - * encryption and no authentication. Then the packet will be sent out - * untouched. However this is not encouraged. If no SRTCP feature is enabled, - * then we shall not use SRTP TransformConnector. We should use the original - * method (RTPManager managed transportation) instead. - * - * @param pkt the received RTCP packet - * @return true if the packet can be accepted - * false if authentication or replay check failed - */ - public boolean reverseTransformPacket(RawPacket pkt) - { - boolean decrypt = false; - int tagLength = policy.getAuthTagLength(); - int indexEflag = pkt.getSRTCPIndex(tagLength); - - if ((indexEflag & 0x80000000) == 0x80000000) - decrypt = true; - - int index = indexEflag & ~0x80000000; - - /* Replay control */ - if (!checkReplay(index)) - { - return false; - } - - /* Authenticate the packet */ - if (policy.getAuthType() != SRTPPolicy.NULL_AUTHENTICATION) - { - // get original authentication data and store in tempStore - pkt.readRegionToBuff(pkt.getLength() - tagLength, tagLength, - tempStore); - - // Shrink packet to remove the authentication tag and index - // because this is part of authenicated data - pkt.shrink(tagLength + 4); - - // compute, then save authentication in tagStore - authenticatePacket(pkt, indexEflag); - - for (int i = 0; i < tagLength; i++) - { - if ((tempStore[i] & 0xff) == (tagStore[i] & 0xff)) - continue; - else - return false; - } - } - - if (decrypt) - { - /* Decrypt the packet using Counter Mode encryption */ - if (policy.getEncType() == SRTPPolicy.AESCM_ENCRYPTION - || policy.getEncType() == SRTPPolicy.TWOFISH_ENCRYPTION) - { - processPacketAESCM(pkt, index); - } - - /* Decrypt the packet using F8 Mode encryption */ - else if (policy.getEncType() == SRTPPolicy.AESF8_ENCRYPTION - || policy.getEncType() == SRTPPolicy.TWOFISHF8_ENCRYPTION) - { - processPacketAESF8(pkt, index); - } - } - update(index); - - return true; - } - - /** - * Perform Counter Mode AES encryption / decryption - * @param pkt the RTP packet to be encrypted / decrypted - */ - public void processPacketAESCM(RawPacket pkt, int index) - { - long ssrc = pkt.getRTCPSSRC(); - - /* Compute the CM IV (refer to chapter 4.1.1 in RFC 3711): - * - * k_s XX XX XX XX XX XX XX XX XX XX XX XX XX XX - * SSRC XX XX XX XX - * index XX XX XX XX - * ------------------------------------------------------XOR - * IV XX XX XX XX XX XX XX XX XX XX XX XX XX XX 00 00 - * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - */ - ivStore[0] = saltKey[0]; - ivStore[1] = saltKey[1]; - ivStore[2] = saltKey[2]; - ivStore[3] = saltKey[3]; - - // The shifts transform the ssrc and index into network order - ivStore[4] = (byte) (((ssrc >> 24) & 0xff) ^ this.saltKey[4]); - ivStore[5] = (byte) (((ssrc >> 16) & 0xff) ^ this.saltKey[5]); - ivStore[6] = (byte) (((ssrc >> 8) & 0xff) ^ this.saltKey[6]); - ivStore[7] = (byte) ((ssrc & 0xff) ^ this.saltKey[7]); - - ivStore[8] = saltKey[8]; - ivStore[9] = saltKey[9]; - - ivStore[10] = (byte) (((index >> 24) & 0xff) ^ this.saltKey[10]); - ivStore[11] = (byte) (((index >> 16) & 0xff) ^ this.saltKey[11]); - ivStore[12] = (byte) (((index >> 8) & 0xff) ^ this.saltKey[12]); - ivStore[13] = (byte) ((index & 0xff) ^ this.saltKey[13]); - - ivStore[14] = ivStore[15] = 0; - - // Encrypted part excludes fixed header (8 bytes) - final int payloadOffset = 8; - final int payloadLength = pkt.getLength() - payloadOffset; - - cipherCtr.process(cipher, pkt.getBuffer(), - pkt.getOffset() + payloadOffset, - payloadLength, ivStore); - } - - /** - * Perform F8 Mode AES encryption / decryption - * - * @param pkt the RTP packet to be encrypted / decrypted - */ - public void processPacketAESF8(RawPacket pkt, int index) - { - // byte[] iv = new byte[16]; - - // 4 bytes of the iv are zero - // the first byte of the RTP header is not used. - ivStore[0] = 0; - ivStore[1] = 0; - ivStore[2] = 0; - ivStore[3] = 0; - - // Need the encryption flag - index = index | 0x80000000; - - // set the index and the encrypt flag in network order into IV - ivStore[4] = (byte) (index >> 24); - ivStore[5] = (byte) (index >> 16); - ivStore[6] = (byte) (index >> 8); - ivStore[7] = (byte) index; - - // The fixed header follows and fills the rest of the IV - System.arraycopy(pkt.getBuffer(), pkt.getOffset(), ivStore, 8, 8); - - // Encrypted part excludes fixed header (8 bytes), index (4 bytes), and - // authentication tag (variable according to policy) - final int payloadOffset = 8; - final int payloadLength - = pkt.getLength() - (4 + policy.getAuthTagLength()); - - SRTPCipherF8.process(cipher, pkt.getBuffer(), - pkt.getOffset() + payloadOffset, - payloadLength, ivStore, cipherF8); - } - - /** - * Authenticate a packet. - * - * Calculated authentication tag is stored in tagStore area. - * - * @param pkt the RTP packet to be authenticated - */ - private void authenticatePacket(RawPacket pkt, int index) - { - mac.update(pkt.getBuffer(), 0, pkt.getLength()); - // byte[] rb = new byte[4]; - rbStore[0] = (byte) (index >> 24); - rbStore[1] = (byte) (index >> 16); - rbStore[2] = (byte) (index >> 8); - rbStore[3] = (byte) index; - mac.update(rbStore, 0, rbStore.length); - mac.doFinal(tagStore, 0); - } - - /** - * Checks if a packet is a replayed on based on its sequence number. - * - * This method supports a 64 packet history relative the the given - * sequence number. - * - * Sequence Number is guaranteed to be real (not faked) through - * authentication. - * - * @param index index number of the SRTCP packet - * @return true if this sequence number indicates the packet is not a - * replayed one, false if not - */ - boolean checkReplay(int index) - { - // compute the index of previously received packet and its - // delta to the new received packet - long delta = index - receivedIndex; - - if (delta > 0) - { - /* Packet not yet received */ - return true; - } - else - { - if (-delta > REPLAY_WINDOW_SIZE) - { - /* Packet too old */ - return false; - } - else - { - if (((this.replayWindow >> (-delta)) & 0x1) != 0) - { - /* Packet already received ! */ - return false; - } - else - { - /* Packet not yet received */ - return true; - } - } - } - } - - /** - * Compute the initialization vector, used later by encryption algorithms, - * based on the label. - * - * @param label label specified for each type of iv - */ - private void computeIv(byte label) - { - for (int i = 0; i < 14; i++) - { - ivStore[i] = masterSalt[i]; - } - ivStore[7] ^= label; - ivStore[14] = ivStore[15] = 0; - } - - /** - * Derives the srtcp session keys from the master key. - * - */ - public void deriveSrtcpKeys() - { - // compute the session encryption key - byte label = 3; - computeIv(label); - - KeyParameter encryptionKey = new KeyParameter(masterKey); - cipher.init(true, encryptionKey); - Arrays.fill(masterKey, (byte)0); - - cipherCtr.getCipherStream(cipher, encKey, policy.getEncKeyLength(), ivStore); - - if (authKey != null) - { - label = 4; - computeIv(label); - cipherCtr.getCipherStream(cipher, authKey, - policy.getAuthKeyLength(), ivStore); - - switch ((policy.getAuthType())) - { - case SRTPPolicy.HMACSHA1_AUTHENTICATION: - KeyParameter key = new KeyParameter(authKey); - mac.init(key); - break; - - case SRTPPolicy.SKEIN_AUTHENTICATION: - // Skein MAC uses number of bits as MAC size, not just bytes - ParametersForSkein pfs = new ParametersForSkein( - new KeyParameter(authKey), - ParametersForSkein.Skein512, tagStore.length * 8); - mac.init(pfs); - break; - } - } - Arrays.fill(authKey, (byte)0); - - // compute the session salt - label = 5; - computeIv(label); - cipherCtr.getCipherStream(cipher, saltKey, policy.getSaltKeyLength(), ivStore); - Arrays.fill(masterSalt, (byte)0); - - // As last step: initialize cipher with derived encryption key. - if (cipherF8 != null) - SRTPCipherF8.deriveForIV(cipherF8, encKey, saltKey); - encryptionKey = new KeyParameter(encKey); - cipher.init(true, encryptionKey); - Arrays.fill(encKey, (byte)0); - } - - - /** - * Update the SRTP packet index. - * - * This method is called after all checks were successful. - * - * @param index index number of the accepted packet - */ - private void update(int index) - { - int delta = receivedIndex - index; - - /* update the replay bit mask */ - if (delta > 0) - { - replayWindow = replayWindow << delta; - replayWindow |= 1; - } - else - { - replayWindow |= ( 1 << delta ); - } - - receivedIndex = index; - } - - /** - * Derive a new SRTPCryptoContext for use with a new SSRC - * - * This method returns a new SRTPCryptoContext initialized with the data of - * this SRTPCryptoContext. Replacing the SSRC, Roll-over-Counter, and the - * key derivation rate the application cab use this SRTPCryptoContext to - * encrypt / decrypt a new stream (Synchronization source) inside one RTP - * session. - * - * Before the application can use this SRTPCryptoContext it must call the - * deriveSrtpKeys method. - * - * @param ssrc - * The SSRC for this context - * @return a new SRTPCryptoContext with all relevant data set. - */ - public SRTCPCryptoContext deriveContext(long ssrc) - { - SRTCPCryptoContext pcc = null; - pcc = new SRTCPCryptoContext(ssrc, masterKey, - masterSalt, policy); - return pcc; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTCPTransformer.java b/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTCPTransformer.java deleted file mode 100644 index 13b7fec48..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTCPTransformer.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform.srtp; - -import java.util.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.transform.*; - -/** - * SRTCPTransformer implements PacketTransformer. - * It encapsulate the encryption / decryption logic for SRTCP packets - * - * @author Bing SU (nova.su@gmail.com) - * @author Werner Dittmann <Werner.Dittmann@t-online.de> - */ -public class SRTCPTransformer - implements PacketTransformer -{ - private final SRTPTransformEngine forwardEngine; - private final SRTPTransformEngine reverseEngine; - - /** - * All the known SSRC's corresponding SRTCPCryptoContexts - */ - private final Hashtable contexts; - - /** - * Constructs a SRTCPTransformer object. - * - * @param engine The associated SRTPTransformEngine object for both - * transform directions. - */ - public SRTCPTransformer(SRTPTransformEngine engine) - { - this(engine, engine); - } - - /** - * Constructs a SRTCPTransformer object. - * - * @param forwardEngine The associated SRTPTransformEngine object for - * forward transformations. - * @param reverseEngine The associated SRTPTransformEngine object for - * reverse transformations. - */ - public SRTCPTransformer( - SRTPTransformEngine forwardEngine, - SRTPTransformEngine reverseEngine) - { - this.forwardEngine = forwardEngine; - this.reverseEngine = reverseEngine; - this.contexts = new Hashtable(); - } - - /** - * Closes this SRTCPTransformer and the underlying transform - * engine. It closes all stored crypto contexts. It deletes key data and - * forces a cleanup of the crypto contexts. - */ - public void close() - { - synchronized (contexts) - { - forwardEngine.close(); - if (reverseEngine != forwardEngine) - reverseEngine.close(); - - Iterator> iter - = contexts.entrySet().iterator(); - - while (iter.hasNext()) - { - Map.Entry entry = iter.next(); - SRTCPCryptoContext context = entry.getValue(); - - iter.remove(); - if (context != null) - context.close(); - } - } - } - - private SRTCPCryptoContext getContext( - RawPacket pkt, - SRTPTransformEngine engine) - { - long ssrc = pkt.getRTCPSSRC(); - SRTCPCryptoContext context; - - synchronized (contexts) - { - context = contexts.get(ssrc); - if (context == null) - { - context = engine.getDefaultContextControl(); - if (context != null) - { - context = context.deriveContext(ssrc); - context.deriveSrtcpKeys(); - contexts.put(ssrc, context); - } - } - } - - return context; - } - - /** - * Decrypts a SRTCP packet - * - * @param pkt encrypted SRTCP packet to be decrypted - * @return decrypted SRTCP packet - */ - public RawPacket reverseTransform(RawPacket pkt) - { - SRTCPCryptoContext context = getContext(pkt, reverseEngine); - - return - ((context != null) && context.reverseTransformPacket(pkt)) - ? pkt - : null; - } - - /** - * Encrypts a SRTCP packet - * - * @param pkt plain SRTCP packet to be encrypted - * @return encrypted SRTCP packet - */ - public RawPacket transform(RawPacket pkt) - { - SRTCPCryptoContext context = getContext(pkt, forwardEngine); - - context.transformPacket(pkt); - return pkt; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCipherCTR.java b/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCipherCTR.java deleted file mode 100644 index fd75aa9a7..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCipherCTR.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - * - * Some of the code in this class is derived from ccRtp's SRTP implementation, - * which has the following copyright notice: - * - Copyright (C) 2004-2006 the Minisip Team - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -package net.java.sip.communicator.impl.neomedia.transform.srtp; - -import org.bouncycastle.crypto.BlockCipher; - -/** - * SRTPCipherCTR implements SRTP Counter Mode AES Encryption (AES-CM). - * Counter Mode AES Encryption algorithm is defined in RFC3711, section 4.1.1. - * - * Other than Null Cipher, RFC3711 defined two two encryption algorithms: - * Counter Mode AES Encryption and F8 Mode AES encryption. Both encryption - * algorithms are capable to encrypt / decrypt arbitrary length data, and the - * size of packet data is not required to be a multiple of the AES block - * size (128bit). So, no padding is needed. - * - * Please note: these two encryption algorithms are specially defined by SRTP. - * They are not common AES encryption modes, so you will not be able to find a - * replacement implementation in common cryptographic libraries. - * - * As defined by RFC3711: Counter Mode Encryption is mandatory.. - * - * mandatory to impl optional default - * ------------------------------------------------------------------------- - * encryption AES-CM, NULL AES-f8 AES-CM - * message integrity HMAC-SHA1 - HMAC-SHA1 - * key derivation (PRF) AES-CM - AES-CM - * - * We use AESCipher to handle basic AES encryption / decryption. - * - * @author Werner Dittmann (Werner.Dittmann@t-online.de) - * @author Bing SU (nova.su@gmail.com) - */ -public class SRTPCipherCTR -{ - - private final static int BLKLEN = 16; - private final static int MAX_BUFFER_LENGTH = 10*1024; - private final byte[] cipherInBlock = new byte[BLKLEN]; - private final byte[] tmpCipherBlock = new byte[BLKLEN]; - private byte[] streamBuf = new byte[1024]; - - public SRTPCipherCTR() - { - } - - public void process(BlockCipher cipher, byte[] data, int off, int len, - byte[] iv) - { - if (off + len > data.length) - return; - - // if data fits in inter buffer - use it. Otherwise allocate bigger - // buffer store it to use it for later processing - up to a defined - // maximum size. - byte[] cipherStream = null; - if (len > streamBuf.length) - { - cipherStream = new byte[len]; - if (cipherStream.length <= MAX_BUFFER_LENGTH) - { - streamBuf = cipherStream; - } - } - else - { - cipherStream = streamBuf; - } - - getCipherStream(cipher, cipherStream, len, iv); - for (int i = 0; i < len; i++) - data[i + off] ^= cipherStream[i]; - } - - /** - * Computes the cipher stream for AES CM mode. See section 4.1.1 in RFC3711 - * for detailed description. - * - * @param out - * byte array holding the output cipher stream - * @param length - * length of the cipher stream to produce, in bytes - * @param iv - * initialization vector used to generate this cipher stream - */ - public void getCipherStream(BlockCipher aesCipher, byte[] out, int length, - byte[] iv) - { - System.arraycopy(iv, 0, cipherInBlock, 0, 14); - - int ctr; - for (ctr = 0; ctr < length / BLKLEN; ctr++) - { - // compute the cipher stream - cipherInBlock[14] = (byte) ((ctr & 0xFF00) >> 8); - cipherInBlock[15] = (byte) ((ctr & 0x00FF)); - - aesCipher.processBlock(cipherInBlock, 0, out, ctr * BLKLEN); - } - - // Treat the last bytes: - cipherInBlock[14] = (byte) ((ctr & 0xFF00) >> 8); - cipherInBlock[15] = (byte) ((ctr & 0x00FF)); - - aesCipher.processBlock(cipherInBlock, 0, tmpCipherBlock, 0); - System.arraycopy(tmpCipherBlock, 0, out, ctr * BLKLEN, length % BLKLEN); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCipherF8.java b/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCipherF8.java deleted file mode 100644 index d72e9a1fc..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCipherF8.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - * - * Some of the code in this class is derived from ccRtp's SRTP implementation, - * which has the following copyright notice: - * - Copyright (C) 2004-2006 the Minisip Team - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -package net.java.sip.communicator.impl.neomedia.transform.srtp; - -import java.util.*; - -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.params.KeyParameter; - -/** - * SRTPCipherF8 implements SRTP F8 Mode AES Encryption (AES-f8). - * F8 Mode AES Encryption algorithm is defined in RFC3711, section 4.1.2. - * - * Other than Null Cipher, RFC3711 defined two two encryption algorithms: - * Counter Mode AES Encryption and F8 Mode AES encryption. Both encryption - * algorithms are capable to encrypt / decrypt arbitrary length data, and the - * size of packet data is not required to be a multiple of the AES block - * size (128bit). So, no padding is needed. - * - * Please note: these two encryption algorithms are specially defined by SRTP. - * They are not common AES encryption modes, so you will not be able to find a - * replacement implementation in common cryptographic libraries. - * - * As defined by RFC3711: F8 mode encryption is optional. - * - * mandatory to impl optional default - * ------------------------------------------------------------------------- - * encryption AES-CM, NULL AES-f8 AES-CM - * message integrity HMAC-SHA1 - HMAC-SHA1 - * key derivation (PRF) AES-CM - AES-CM - * - * We use AESCipher to handle basic AES encryption / decryption. - * - * @author Bing SU (nova.su@gmail.com) - * @author Werner Dittmann - */ -public class SRTPCipherF8 -{ - /** - * AES block size, just a short name. - */ - private final static int BLKLEN = 16; - - /** - * F8 mode encryption context, see RFC3711 section 4.1.2 for detailed - * description. - */ - class F8Context - { - public byte[] S; - public byte[] ivAccent; - long J; - } - - public static void deriveForIV(BlockCipher f8Cipher, byte[] key, byte[] salt) - { - /* - * Get memory for the special key. This is the key to compute the - * derived IV (IV'). - */ - byte[] saltMask = new byte[key.length]; - byte[] maskedKey = new byte[key.length]; - - /* - * First copy the salt into the mask field, then fill with 0x55 to get a - * full key. - */ - System.arraycopy(salt, 0, saltMask, 0, salt.length); - for (int i = salt.length; i < saltMask.length; ++i) - saltMask[i] = 0x55; - - /* - * XOR the original key with the above created mask to get the special - * key. - */ - for (int i = 0; i < key.length; i++) - maskedKey[i] = (byte) (key[i] ^ saltMask[i]); - - /* - * Prepare the f8Cipher with the special key to compute IV' - */ - KeyParameter encryptionKey = new KeyParameter(maskedKey); - f8Cipher.init(true, encryptionKey); - saltMask = null; - maskedKey = null; - } - - public static void process(BlockCipher cipher, byte[] data, int off, int len, - byte[] iv, BlockCipher f8Cipher) - { - F8Context f8ctx = new SRTPCipherF8().new F8Context(); - - /* - * Get memory for the derived IV (IV') - */ - f8ctx.ivAccent = new byte[BLKLEN]; - - /* - * Use the derived IV encryption setup to encrypt the original IV to produce IV'. - */ - f8Cipher.processBlock(iv, 0, f8ctx.ivAccent, 0); - - f8ctx.J = 0; // initialize the counter - f8ctx.S = new byte[BLKLEN]; // get the key stream buffer - - Arrays.fill(f8ctx.S, (byte) 0); - - int inLen = len; - - while (inLen >= BLKLEN) - { - processBlock(cipher, f8ctx, data, off, data, off, BLKLEN); - inLen -= BLKLEN; - off += BLKLEN; - } - - if (inLen > 0) - { - processBlock(cipher, f8ctx, data, off, data, off, inLen); - } - } - - /** - * Encrypt / Decrypt a block using F8 Mode AES algorithm, read len bytes - * data from in at inOff and write the output into out at outOff - * - * @param f8ctx - * F8 encryption context - * @param in - * byte array holding the data to be processed - * @param inOff - * start offset of the data to be processed inside in array - * @param out - * byte array that will hold the processed data - * @param outOff - * start offset of output data in out - * @param len - * length of the input data - */ - private static void processBlock(BlockCipher cipher, F8Context f8ctx, - byte[] in, int inOff, byte[] out, int outOff, int len) - { - /* - * XOR the previous key stream with IV' - * ( S(-1) xor IV' ) - */ - for (int i = 0; i < BLKLEN; i++) - f8ctx.S[i] ^= f8ctx.ivAccent[i]; - - /* - * Now XOR (S(n-1) xor IV') with the current counter, then increment - * the counter - */ - f8ctx.S[12] ^= f8ctx.J >> 24; - f8ctx.S[13] ^= f8ctx.J >> 16; - f8ctx.S[14] ^= f8ctx.J >> 8; - f8ctx.S[15] ^= f8ctx.J >> 0; - f8ctx.J++; - - /* - * Now compute the new key stream using AES encrypt - */ - cipher.processBlock(f8ctx.S, 0, f8ctx.S, 0); - - /* - * As the last step XOR the plain text with the key stream to produce - * the cipher text. - */ - for (int i = 0; i < len; i++) - out[outOff + i] = (byte) (in[inOff + i] ^ f8ctx.S[i]); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCryptoContext.java b/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCryptoContext.java deleted file mode 100644 index ef51ff5a2..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCryptoContext.java +++ /dev/null @@ -1,837 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - * - * - * Some of the code in this class is derived from ccRtp's SRTP implementation, - * which has the following copyright notice: - * - Copyright (C) 2004-2006 the Minisip Team - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -package net.java.sip.communicator.impl.neomedia.transform.srtp; - -import java.util.Arrays; - -import net.java.sip.communicator.impl.neomedia.*; - -import org.bouncycastle.crypto.*; -import org.bouncycastle.crypto.digests.*; -import org.bouncycastle.crypto.engines.*; -import org.bouncycastle.crypto.macs.*; -import org.bouncycastle.crypto.params.*; - -/** - * SRTPCryptoContext class is the core class of SRTP implementation. - * There can be multiple SRTP sources in one SRTP session. And each SRTP stream - * has a corresponding SRTPCryptoContext object, identified by SSRC. In this - * way, different sources can be protected independently. - * - * SRTPCryptoContext class acts as a manager class and maintains all the - * information used in SRTP transformation. It is responsible for deriving - * encryption keys / salting keys / authentication keys from master keys. And - * it will invoke certain class to encrypt / decrypt (transform / reverse - * transform) RTP packets. It will hold a replay check db and do replay check - * against incoming packets. - * - * Refer to section 3.2 in RFC3711 for detailed description of cryptographic - * context. - * - * Cryptographic related parameters, i.e. encryption mode / authentication mode, - * master encryption key and master salt key are determined outside the scope - * of SRTP implementation. They can be assigned manually, or can be assigned - * automatically using some key management protocol, such as MIKEY (RFC3830), - * SDES (RFC4568) or Phil Zimmermann's ZRTP protocol (RFC6189). - * - * @author Bing SU (nova.su@gmail.com) - */ -public class SRTPCryptoContext -{ - /** - * The replay check windows size - */ - private static final long REPLAY_WINDOW_SIZE = 64; - - /** - * RTP SSRC of this cryptographic context - */ - private long ssrcCtx; - - /** - * Master key identifier - */ - private byte[] mki; - - /** - * Roll-Over-Counter, see RFC3711 section 3.2.1 for detailed description - */ - private int roc; - - /** - * Roll-Over-Counter guessed from packet - */ - private int guessedROC; - - /** - * RTP sequence number of the packet current processing - */ - private int seqNum; - - /** - * Whether we have the sequence number of current packet - */ - private boolean seqNumSet; - - /** - * Key Derivation Rate, used to derive session keys from master keys - */ - private long keyDerivationRate; - - /** - * Bit mask for replay check - */ - private long replayWindow; - - /** - * Master encryption key - */ - private byte[] masterKey; - - /** - * Master salting key - */ - private byte[] masterSalt; - - /** - * Derived session encryption key - */ - private byte[] encKey; - - /** - * Derived session authentication key - */ - private byte[] authKey; - - /** - * Derived session salting key - */ - private byte[] saltKey; - - /** - * Encryption / Authentication policy for this session - */ - private final SRTPPolicy policy; - - /** - * The HMAC object we used to do packet authentication - */ - private Mac mac; // used for various HMAC computations - - /** - * The symmetric cipher engines we need here - */ - private BlockCipher cipher = null; - - /** - * Used inside F8 mode only - */ - private BlockCipher cipherF8 = null; - - /** - * implements the counter cipher mode for RTP according to RFC 3711 - */ - private final SRTPCipherCTR cipherCtr = new SRTPCipherCTR(); - - /** - * Temp store. - */ - private final byte[] tagStore; - - /** - * Temp store. - */ - private final byte[] ivStore = new byte[16]; - - /** - * Temp store. - */ - private final byte[] rbStore = new byte[4]; - - /** - * this is a working store, used by some methods to avoid new operations - * the methods must use this only to store results for immediate processing - */ - private final byte[] tempStore = new byte[100]; - - /** - * Construct an empty SRTPCryptoContext using ssrc. - * The other parameters are set to default null value. - * - * @param ssrcIn SSRC of this SRTPCryptoContext - */ - public SRTPCryptoContext(long ssrcIn) - { - ssrcCtx = ssrcIn; - mki = null; - roc = 0; - guessedROC = 0; - seqNum = 0; - keyDerivationRate = 0; - masterKey = null; - masterSalt = null; - encKey = null; - authKey = null; - saltKey = null; - seqNumSet = false; - policy = null; - tagStore = null; - } - - /** - * Construct a normal SRTPCryptoContext based on the given parameters. - * - * @param ssrcIn - * the RTP SSRC that this SRTP cryptographic context protects. - * @param rocIn - * the initial Roll-Over-Counter according to RFC 3711. These are - * the upper 32 bit of the overall 48 bit SRTP packet index. - * Refer to chapter 3.2.1 of the RFC. - * @param kdr - * the key derivation rate defines when to recompute the SRTP - * session keys. Refer to chapter 4.3.1 in the RFC. - * @param masterK - * byte array holding the master key for this SRTP cryptographic - * context. Refer to chapter 3.2.1 of the RFC about the role of - * the master key. - * @param masterS - * byte array holding the master salt for this SRTP cryptographic - * context. It is used to computer the initialization vector that - * in turn is input to compute the session key, session - * authentication key and the session salt. - * @param policyIn - * SRTP policy for this SRTP cryptographic context, defined the - * encryption algorithm, the authentication algorithm, etc - */ - @SuppressWarnings("fallthrough") - public SRTPCryptoContext(long ssrcIn, int rocIn, long kdr, - byte[] masterK, byte[] masterS, SRTPPolicy policyIn) - { - ssrcCtx = ssrcIn; - mki = null; - roc = rocIn; - guessedROC = 0; - seqNum = 0; - keyDerivationRate = kdr; - seqNumSet = false; - - policy = policyIn; - - masterKey = new byte[policy.getEncKeyLength()]; - System.arraycopy(masterK, 0, masterKey, 0, policy - .getEncKeyLength()); - - masterSalt = new byte[policy.getSaltKeyLength()]; - System.arraycopy(masterS, 0, masterSalt, 0, policy - .getSaltKeyLength()); - - mac = new HMac(new SHA1Digest()); - - switch (policy.getEncType()) - { - case SRTPPolicy.NULL_ENCRYPTION: - encKey = null; - saltKey = null; - break; - - case SRTPPolicy.AESF8_ENCRYPTION: - cipherF8 = new AESFastEngine(); - //$FALL-THROUGH$ - - case SRTPPolicy.AESCM_ENCRYPTION: - cipher = new AESFastEngine(); - encKey = new byte[policy.getEncKeyLength()]; - saltKey = new byte[policy.getSaltKeyLength()]; - break; - - case SRTPPolicy.TWOFISHF8_ENCRYPTION: - cipherF8 = new TwofishEngine(); - - case SRTPPolicy.TWOFISH_ENCRYPTION: - cipher = new TwofishEngine(); - encKey = new byte[this.policy.getEncKeyLength()]; - saltKey = new byte[this.policy.getSaltKeyLength()]; - break; - } - - switch (policy.getAuthType()) - { - case SRTPPolicy.NULL_AUTHENTICATION: - authKey = null; - tagStore = null; - break; - - case SRTPPolicy.HMACSHA1_AUTHENTICATION: - mac = new HMac(new SHA1Digest()); - authKey = new byte[policy.getAuthKeyLength()]; - tagStore = new byte[mac.getMacSize()]; - break; - - case SRTPPolicy.SKEIN_AUTHENTICATION: - mac = new SkeinMac(); - authKey = new byte[policy.getAuthKeyLength()]; - tagStore = new byte[policy.getAuthTagLength()]; - break; - - default: - tagStore = null; - } - } - - /** - * Close the crypto context. - * - * The close functions deletes key data and performs a cleanup of the - * crypto context. - * - * Clean up key data, maybe this is the second time however, sometimes - * we cannot know if the CryptoCOntext was used and the application called - * deriveSrtpKeys(...) . - * - */ - public void close() - { - Arrays.fill(masterKey, (byte)0); - Arrays.fill(masterSalt, (byte)0); - } - - /** - * Get the authentication tag length of this SRTP cryptographic context - * - * @return the authentication tag length of this SRTP cryptographic context - */ - public int getAuthTagLength() - { - return policy.getAuthTagLength(); - } - - /** - * Get the MKI length of this SRTP cryptographic context - * - * @return the MKI length of this SRTP cryptographic context - */ - public int getMKILength() - { - if (mki != null) - { - return mki.length; - } - else - { - return 0; - } - } - - /** - * Get the SSRC of this SRTP cryptographic context - * - * @return the SSRC of this SRTP cryptographic context - */ - public long getSSRC() - { - return ssrcCtx; - } - - /** - * Get the Roll-Over-Counter of this SRTP cryptographic context - * - * @return the Roll-Over-Counter of this SRTP cryptographic context - */ - public int getROC() - { - return roc; - } - - /** - * Set the Roll-Over-Counter of this SRTP cryptographic context - * - * @param rocIn the Roll-Over-Counter of this SRTP cryptographic context - */ - public void setROC(int rocIn) - { - roc = rocIn; - } - - /** - * Transform a RTP packet into a SRTP packet. - * This method is called when a normal RTP packet ready to be sent. - * - * Operations done by the transformation may include: encryption, using - * either Counter Mode encryption, or F8 Mode encryption, adding - * authentication tag, currently HMC SHA1 method. - * - * Both encryption and authentication functionality can be turned off - * as long as the SRTPPolicy used in this SRTPCryptoContext is requires no - * encryption and no authentication. Then the packet will be sent out - * untouched. However this is not encouraged. If no SRTP feature is enabled, - * then we shall not use SRTP TransformConnector. We should use the original - * method (RTPManager managed transportation) instead. - * - * @param pkt the RTP packet that is going to be sent out - */ - public void transformPacket(RawPacket pkt) - { - /* Encrypt the packet using Counter Mode encryption */ - if (policy.getEncType() == SRTPPolicy.AESCM_ENCRYPTION || - policy.getEncType() == SRTPPolicy.TWOFISH_ENCRYPTION) - { - processPacketAESCM(pkt); - } - else if (policy.getEncType() == SRTPPolicy.AESF8_ENCRYPTION || - policy.getEncType() == SRTPPolicy.TWOFISHF8_ENCRYPTION) - { - /* Encrypt the packet using F8 Mode encryption */ - processPacketAESF8(pkt); - } - - /* Authenticate the packet */ - if (policy.getAuthType() != SRTPPolicy.NULL_AUTHENTICATION) - { - authenticatePacketHMCSHA1(pkt, roc); - pkt.append(tagStore, policy.getAuthTagLength()); - } - - /* Update the ROC if necessary */ - int seqNo = pkt.getSequenceNumber(); - if (seqNo == 0xFFFF) - { - roc++; - } - } - - /** - * Transform a SRTP packet into a RTP packet. - * This method is called when a SRTP packet is received. - * - * Operations done by the this operation include: - * Authentication check, Packet replay check and decryption. - * - * Both encryption and authentication functionality can be turned off - * as long as the SRTPPolicy used in this SRTPCryptoContext is requires no - * encryption and no authentication. Then the packet will be sent out - * untouched. However this is not encouraged. If no SRTP feature is enabled, - * then we shall not use SRTP TransformConnector. We should use the original - * method (RTPManager managed transportation) instead. - * - * @param pkt the RTP packet that is just received - * @return true if the packet can be accepted - * false if the packet failed authentication or failed replay check - */ - public boolean reverseTransformPacket(RawPacket pkt) - { - int seqNo = pkt.getSequenceNumber(); - - if (!seqNumSet) - { - seqNumSet = true; - seqNum = seqNo; - } - // Guess the SRTP index (48 bit), see rFC 3711, 3.3.1 - // Stores the guessed roc in this.guessedROC - long guessedIndex = guessIndex(seqNo); - - /* Replay control */ - if (!checkReplay(seqNo, guessedIndex)) - { - return false; - } - /* Authenticate the packet */ - if (policy.getAuthType() != SRTPPolicy.NULL_AUTHENTICATION) - { - int tagLength = policy.getAuthTagLength(); - - // get original authentication and store in tempStore - pkt.readRegionToBuff(pkt.getLength() - tagLength, - tagLength, tempStore); - - pkt.shrink(tagLength); - - // save computed authentication in tagStore - authenticatePacketHMCSHA1(pkt, guessedROC); - - for (int i = 0; i < tagLength; i++) - { - if ((tempStore[i]&0xff) == (tagStore[i]&0xff)) - continue; - else - { - return false; - } - } - } - - /* Decrypt the packet using Counter Mode encryption*/ - if (policy.getEncType() == SRTPPolicy.AESCM_ENCRYPTION || - policy.getEncType() == SRTPPolicy.TWOFISH_ENCRYPTION) - { - processPacketAESCM(pkt); - } - - /* Decrypt the packet using F8 Mode encryption*/ - else if (policy.getEncType() == SRTPPolicy.AESF8_ENCRYPTION || - policy.getEncType() == SRTPPolicy.TWOFISHF8_ENCRYPTION) - { - processPacketAESF8(pkt); - } - - update(seqNo, guessedIndex); - - return true; - } - - /** - * Perform Counter Mode AES encryption / decryption - * @param pkt the RTP packet to be encrypted / decrypted - */ - public void processPacketAESCM(RawPacket pkt) - { - long ssrc = pkt.getSSRC(); - int seqNo = pkt.getSequenceNumber(); - long index = ((long) this.roc << 16) | seqNo; - - // byte[] iv = new byte[16]; - ivStore[0] = saltKey[0]; - ivStore[1] = saltKey[1]; - ivStore[2] = saltKey[2]; - ivStore[3] = saltKey[3]; - - int i; - for (i = 4; i < 8; i++) - { - ivStore[i] = (byte) - ( - (0xFF & (ssrc >> ((7 - i) * 8))) - ^ - this.saltKey[i] - ); - } - - for (i = 8; i < 14; i++) - { - ivStore[i] = (byte) - ( - (0xFF & (byte) (index >> ((13 - i) * 8))) - ^ - this.saltKey[i] - ); - } - - ivStore[14] = ivStore[15] = 0; - - final int payloadOffset = pkt.getHeaderLength(); - final int payloadLength = pkt.getPayloadLength(); - - cipherCtr.process(cipher, pkt.getBuffer(), pkt.getOffset() + - payloadOffset, payloadLength, ivStore); - } - - /** - * Perform F8 Mode AES encryption / decryption - * - * @param pkt the RTP packet to be encrypted / decrypted - */ - public void processPacketAESF8(RawPacket pkt) - { - // byte[] iv = new byte[16]; - - // 11 bytes of the RTP header are the 11 bytes of the iv - // the first byte of the RTP header is not used. - System.arraycopy(pkt.getBuffer(), pkt.getOffset(), ivStore, 0, 12); - ivStore[0] = 0; - - // set the ROC in network order into IV - ivStore[12] = (byte) (this.roc >> 24); - ivStore[13] = (byte) (this.roc >> 16); - ivStore[14] = (byte) (this.roc >> 8); - ivStore[15] = (byte) this.roc; - - final int payloadOffset = pkt.getHeaderLength(); - final int payloadLength = pkt.getPayloadLength(); - - SRTPCipherF8.process(cipher, pkt.getBuffer(), pkt.getOffset() + payloadOffset, - payloadLength, ivStore, cipherF8); - } - - /** - * Authenticate a packet. - * Calculated authentication tag is returned. - * - * @param pkt the RTP packet to be authenticated - * @param rocIn Roll-Over-Counter - */ - private void authenticatePacketHMCSHA1(RawPacket pkt, int rocIn) - { - mac.update(pkt.getBuffer(), pkt.getOffset(), pkt.getLength()); - // byte[] rb = new byte[4]; - rbStore[0] = (byte) (rocIn >> 24); - rbStore[1] = (byte) (rocIn >> 16); - rbStore[2] = (byte) (rocIn >> 8); - rbStore[3] = (byte) rocIn; - mac.update(rbStore, 0, rbStore.length); - mac.doFinal(tagStore, 0); - } - - /** - * Checks if a packet is a replayed on based on its sequence number. - * - * This method supports a 64 packet history relative the the given - * sequence number. - * - * Sequence Number is guaranteed to be real (not faked) through - * authentication. - * - * @param seqNo sequence number of the packet - * @param guessedIndex guessed roc - * @return true if this sequence number indicates the packet is not a - * replayed one, false if not - */ - boolean checkReplay(int seqNo, long guessedIndex) - { - // compute the index of previously received packet and its - // delta to the new received packet - long localIndex = (((long) this.roc) << 16) | this.seqNum; - long delta = guessedIndex - localIndex; - - if (delta > 0) - { - /* Packet not yet received */ - return true; - } - else - { - if (-delta > REPLAY_WINDOW_SIZE) { - /* Packet too old */ - return false; - } - else - { - if (((this.replayWindow >> (-delta)) & 0x1) != 0) - { - /* Packet already received ! */ - return false; - } - else - { - /* Packet not yet received */ - return true; - } - } - } - } - - /** - * Compute the initialization vector, used later by encryption algorithms, - * based on the lable, the packet index, key derivation rate and master - * salt key. - * - * @param label label specified for each type of iv - * @param index 48bit RTP packet index - */ - private void computeIv(long label, long index) - { - long key_id; - - if (keyDerivationRate == 0) - { - key_id = label << 48; - } - else - { - key_id = ((label << 48) | (index / keyDerivationRate)); - } - for (int i = 0; i < 7; i++) - { - ivStore[i] = masterSalt[i]; - } - for (int i = 7; i < 14; i++) - { - ivStore[i] = (byte) - ( - (byte) (0xFF & (key_id >> (8 * (13 - i)))) - ^ - masterSalt[i] - ); - } - ivStore[14] = ivStore[15] = 0; - } - - /** - * Derives the srtp session keys from the master key - * - * @param index - * the 48 bit SRTP packet index - */ - public void deriveSrtpKeys(long index) - { - // compute the session encryption key - long label = 0; - computeIv(label, index); - - KeyParameter encryptionKey = new KeyParameter(masterKey); - cipher.init(true, encryptionKey); - Arrays.fill(masterKey, (byte)0); - - cipherCtr.getCipherStream(cipher, encKey, policy.getEncKeyLength(), ivStore); - - // compute the session authentication key - if (authKey != null) - { - label = 0x01; - computeIv(label, index); - cipherCtr.getCipherStream(cipher, authKey, - policy.getAuthKeyLength(), ivStore); - - switch ((policy.getAuthType())) - { - case SRTPPolicy.HMACSHA1_AUTHENTICATION: - KeyParameter key = new KeyParameter(authKey); - mac.init(key); - break; - - case SRTPPolicy.SKEIN_AUTHENTICATION: - // Skein MAC uses number of bits as MAC size, not just bytes - ParametersForSkein pfs = new ParametersForSkein( - new KeyParameter(authKey), - ParametersForSkein.Skein512, tagStore.length*8); - mac.init(pfs); - break; - } - } - Arrays.fill(authKey, (byte)0); - - // compute the session salt - label = 0x02; - computeIv(label, index); - cipherCtr.getCipherStream(cipher, saltKey, policy.getSaltKeyLength(), ivStore); - Arrays.fill(masterSalt, (byte)0); - - // As last step: initialize cipher with derived encryption key. - if (cipherF8 != null) - SRTPCipherF8.deriveForIV(cipherF8, encKey, saltKey); - encryptionKey = new KeyParameter(encKey); - cipher.init(true, encryptionKey); - Arrays.fill(encKey, (byte)0); - } - - /** - * Compute (guess) the new SRTP index based on the sequence number of a - * received RTP packet. - * - * @param seqNo sequence number of the received RTP packet - * @return the new SRTP packet index - */ - private long guessIndex(int seqNo) - { - if (this.seqNum < 32768) - { - if (seqNo - this.seqNum > 32768) - { - guessedROC = roc - 1; - } - else - { - guessedROC = roc; - } - } - else - { - if (seqNum - 32768 > seqNo) - { - guessedROC = roc + 1; - } - else - { - guessedROC = roc; - } - } - - return ((long) guessedROC) << 16 | seqNo; - } - - /** - * Update the SRTP packet index. - * - * This method is called after all checks were successful. - * See section 3.3.1 in RFC3711 for detailed description. - * - * @param seqNo sequence number of the accepted packet - * @param guessedIndex guessed roc - */ - private void update(int seqNo, long guessedIndex) - { - long delta = guessedIndex - (((long) this.roc) << 16 | this.seqNum); - - /* update the replay bit mask */ - if( delta > 0 ) - { - replayWindow = replayWindow << delta; - replayWindow |= 1; - } - else - { - replayWindow |= ( 1 << delta ); - } - - if (seqNo > seqNum) - { - seqNum = seqNo & 0xffff; - } - if (this.guessedROC > this.roc) - { - roc = guessedROC; - seqNum = seqNo & 0xffff; - } - } - - /** - * Derive a new SRTPCryptoContext for use with a new SSRC - * - * This method returns a new SRTPCryptoContext initialized with the data of - * this SRTPCryptoContext. Replacing the SSRC, Roll-over-Counter, and the - * key derivation rate the application cab use this SRTPCryptoContext to - * encrypt / decrypt a new stream (Synchronization source) inside one RTP - * session. - * - * Before the application can use this SRTPCryptoContext it must call the - * deriveSrtpKeys method. - * - * @param ssrc - * The SSRC for this context - * @param roc - * The Roll-Over-Counter for this context - * @param deriveRate - * The key derivation rate for this context - * @return a new SRTPCryptoContext with all relevant data set. - */ - public SRTPCryptoContext deriveContext(long ssrc, int roc, long deriveRate) - { - SRTPCryptoContext pcc = null; - pcc = new SRTPCryptoContext(ssrc, roc, deriveRate, masterKey, - masterSalt, policy); - return pcc; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPPolicy.java b/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPPolicy.java deleted file mode 100644 index 99d3f2e79..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPPolicy.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform.srtp; - -/** - * SRTPPolicy holds the SRTP encryption / authentication policy of a SRTP - * session. - * - * @author Bing SU (nova.su@gmail.com) - */ -public class SRTPPolicy -{ - /** - * Null Cipher, does not change the content of RTP payload - */ - public final static int NULL_ENCRYPTION = 0; - - /** - * Counter Mode AES Cipher, defined in Section 4.1.1, RFC3711 - */ - public final static int AESCM_ENCRYPTION = 1; - - /** - * Counter Mode TwoFish Cipher - */ - public final static int TWOFISH_ENCRYPTION = 3; - - /** - * F8 mode AES Cipher, defined in Section 4.1.2, RFC 3711 - */ - public final static int AESF8_ENCRYPTION = 2; - - /** - * F8 Mode TwoFish Cipher - */ - public final static int TWOFISHF8_ENCRYPTION = 4; - /** - * Null Authentication, no authentication - */ - public final static int NULL_AUTHENTICATION = 0; - - /** - * HAMC SHA1 Authentication, defined in Section 4.2.1, RFC3711 - */ - public final static int HMACSHA1_AUTHENTICATION = 1; - - /** - * Skein Authentication - */ - public final static int SKEIN_AUTHENTICATION = 2; - - /** - * SRTP encryption type - */ - private int encType; - - /** - * SRTP encryption key length - */ - private int encKeyLength; - - /** - * SRTP authentication type - */ - private int authType; - - /** - * SRTP authentication key length - */ - private int authKeyLength; - - /** - * SRTP authentication tag length - */ - private int authTagLength; - - /** - * SRTP salt key length - */ - private int saltKeyLength; - - /** - * Construct a SRTPPolicy object based on given parameters. - * This class acts as a storage class, so all the parameters are passed in - * through this constructor. - * - * @param encType SRTP encryption type - * @param encKeyLength SRTP encryption key length - * @param authType SRTP authentication type - * @param authKeyLength SRTP authentication key length - * @param authTagLength SRTP authentication tag length - * @param saltKeyLength SRTP salt key length - */ - public SRTPPolicy(int encType, - int encKeyLength, - int authType, - int authKeyLength, - int authTagLength, - int saltKeyLength) - { - this.encType = encType; - this.encKeyLength = encKeyLength; - this.authType = authType; - this.authKeyLength = authKeyLength; - this.authTagLength = authTagLength; - this.saltKeyLength = saltKeyLength; - } - - /** - * Get the authentication key length - * - * @return the authentication key length - */ - public int getAuthKeyLength() - { - return this.authKeyLength; - } - - /** - * Set the authentication key length - * - * @param authKeyLength the authentication key length - */ - public void setAuthKeyLength(int authKeyLength) - { - this.authKeyLength = authKeyLength; - } - - /** - * Get the authentication tag length - * - * @return the authentication tag length - */ - public int getAuthTagLength() - { - return this.authTagLength; - } - - /** - * Set the authentication tag length - * - * @param authTagLength the authentication tag length - */ - public void setAuthTagLength(int authTagLength) - { - this.authTagLength = authTagLength; - } - - /** - * Get the authentication type - * - * @return the authentication type - */ - public int getAuthType() - { - return this.authType; - } - - /** - * Set the authentication type - * - * @param authType the authentication type - */ - public void setAuthType(int authType) - { - this.authType = authType; - } - - /** - * Get the encryption key length - * - * @return the encryption key length - */ - public int getEncKeyLength() - { - return this.encKeyLength; - } - - /** - * Set the encryption key length - * - * @param encKeyLength the encryption key length - */ - public void setEncKeyLength(int encKeyLength) - { - this.encKeyLength = encKeyLength; - } - - /** - * Get the encryption type - * - * @return the encryption type - */ - public int getEncType() - { - return this.encType; - } - - /** - * Set the encryption type - * - * @param encType encryption type - */ - public void setEncType(int encType) - { - this.encType = encType; - } - - /** - * Get the salt key length - * - * @return the salt key length - */ - public int getSaltKeyLength() - { - return this.saltKeyLength; - } - - /** - * Set the salt key length - * - * @param keyLength the salt key length - */ - public void setSaltKeyLength(int keyLength) - { - this.saltKeyLength = keyLength; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPTransformEngine.java b/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPTransformEngine.java deleted file mode 100644 index 90fe713ad..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPTransformEngine.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform.srtp; - -import net.java.sip.communicator.impl.neomedia.transform.*; - -/** - * SRTPTransformEngine class implements TransformEngine interface. - * It stores important information / objects regarding SRTP processing. - * Through SRTPTransformEngine, we can get the needed PacketTransformer, which - * will be used by abstract TransformConnector classes. - * - * @author Bing SU (nova.su@gmail.com) - * - */ -public class SRTPTransformEngine - implements TransformEngine -{ - /** - * The default SRTPCryptoContext, which will be used to derivate other - * contexts. - */ - private SRTPCryptoContext defaultContext; - - /** - * The default SRTPCryptoContext, which will be used to derive other - * contexts. - */ - private SRTCPCryptoContext defaultContextControl; - - /** - * Construct a SRTPTransformEngine based on given master encryption key, - * master salt key and SRTP/SRTCP policy. - * - * @param masterKey the master encryption key - * @param masterSalt the master salt key - * @param srtpPolicy SRTP policy - * @param srtcpPolicy SRTCP policy - */ - public SRTPTransformEngine(byte[] masterKey, byte[] masterSalt, - SRTPPolicy srtpPolicy, SRTPPolicy srtcpPolicy) - { - - defaultContext = new SRTPCryptoContext(0, 0, 0, - masterKey, - masterSalt, - srtpPolicy); - defaultContextControl = new SRTCPCryptoContext(0, - masterKey, - masterSalt, - srtcpPolicy); - } - - /** - * Close the transformer engine. - * - * The close functions closes all stored default crypto contexts. This - * deletes key data and forces a cleanup of the crypto contexts. - */ - public void close() - { - if (defaultContext != null) - defaultContext.close(); - if (defaultContextControl != null) - defaultContextControl.close(); - - defaultContext = null; - defaultContextControl = null; - } - - /** - * Gets the PacketTransformer for RTCP packets. - * - * @return the PacketTransformer for RTCP packets - */ - public PacketTransformer getRTCPTransformer() - { - return new SRTCPTransformer(this); - } - - /* - * (non-Javadoc) - * @see net.java.sip.communicator.impl.media.transform. - * TransformEngine#getRTPTransformer() - */ - public PacketTransformer getRTPTransformer() - { - return new SRTPTransformer(this); - } - - /** - * Get the default SRTPCryptoContext - * - * @return the default SRTPCryptoContext - */ - public SRTPCryptoContext getDefaultContext() - { - return this.defaultContext; - } - - /** - * Get the default SRTPCryptoContext - * - * @return the default SRTPCryptoContext - */ - public SRTCPCryptoContext getDefaultContextControl() - { - return this.defaultContextControl; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPTransformer.java b/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPTransformer.java deleted file mode 100644 index eddfda8f9..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPTransformer.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - * - * Some of the code in this class is derived from ccRtp's SRTP implementation, - * which has the following copyright notice: - * - Copyright (C) 2004-2006 the Minisip Team - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -package net.java.sip.communicator.impl.neomedia.transform.srtp; - -import java.util.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.transform.*; - -/** - * SRTPTransformer implements PacketTransformer and provides implementations - * for RTP packet to SRTP packet transformation and SRTP packet to RTP packet - * transformation logic. - * - * It will first find the corresponding SRTPCryptoContext for each packet based - * on their SSRC and then invoke the context object to perform the - * transformation and reverse transformation operation. - * - * @author Bing SU (nova.su@gmail.com) - */ -public class SRTPTransformer - implements PacketTransformer -{ - private final SRTPTransformEngine forwardEngine; - private final SRTPTransformEngine reverseEngine; - - /** - * All the known SSRC's corresponding SRTPCryptoContexts - */ - private final Hashtable contexts; - - /** - * Initializes a new SRTPTransformer instance. - * - * @param engine the SRTPTransformEngine to be used by the new - * instance for both directions - */ - public SRTPTransformer(SRTPTransformEngine engine) - { - this(engine, engine); - } - - /** - * Constructs a SRTPTransformer object. - * - * @param forwardEngine The associated SRTPTransformEngine object for - * forward transformations. - * @param reverseEngine The associated SRTPTransformEngine object for - * reverse transformations. - */ - public SRTPTransformer( - SRTPTransformEngine forwardEngine, - SRTPTransformEngine reverseEngine) - { - this.forwardEngine = forwardEngine; - this.reverseEngine = reverseEngine; - this.contexts = new Hashtable(); - } - - /** - * Closes this SRTPTransformer and the underlying transform - * engines.It closes all stored crypto contexts. It deletes key data and - * forces a cleanup of the crypto contexts. - */ - public void close() - { - synchronized (contexts) - { - forwardEngine.close(); - if (reverseEngine != forwardEngine) - reverseEngine.close(); - - Iterator> iter - = contexts.entrySet().iterator(); - - while (iter.hasNext()) - { - Map.Entry entry = iter.next(); - SRTPCryptoContext context = entry.getValue(); - - iter.remove(); - if (context != null) - context.close(); - } - } - } - - private SRTPCryptoContext getContext( - long ssrc, - SRTPTransformEngine engine, - int deriveSrtpKeysIndex) - { - SRTPCryptoContext context; - - synchronized (contexts) - { - context = contexts.get(ssrc); - if (context == null) - { - context = engine.getDefaultContext(); - if (context != null) - { - context = context.deriveContext(ssrc, 0, 0); - context.deriveSrtpKeys(deriveSrtpKeysIndex); - contexts.put(ssrc, context); - } - } - } - - return context; - } - - /** - * Reverse-transforms a specific packet (i.e. transforms a transformed - * packet back). - * - * @param pkt the transformed packet to be restored - * @return the restored packet - */ - public RawPacket reverseTransform(RawPacket pkt) - { - // only accept RTP version 2 (SNOM phones send weird packages when on - // hold, ignore them with this check (RTP Version must be equal to 2) - if((pkt.readByte(0) & 0xC0) != 0x80) - return null; - - SRTPCryptoContext context - = getContext(pkt.getSSRC(), reverseEngine, pkt.getSequenceNumber()); - - return - ((context != null) && context.reverseTransformPacket(pkt)) - ? pkt - : null; - } - - /** - * Transforms a specific packet. - * - * @param pkt the packet to be transformed - * @return the transformed packet - */ - public RawPacket transform(RawPacket pkt) - { - SRTPCryptoContext context = getContext(pkt.getSSRC(), forwardEngine, 0); - - context.transformPacket(pkt); - return pkt; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/SecurityEventManager.java b/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/SecurityEventManager.java deleted file mode 100644 index 71aa2a3d4..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/SecurityEventManager.java +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform.zrtp; - -import gnu.java.zrtp.*; - -import java.util.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.service.neomedia.event.*; -import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.service.resources.*; -import net.java.sip.communicator.util.*; - -/** - * The user callback class for ZRTP4J. - * - * This class constructs and sends events to the ZRTP GUI implementation. The - * showMessage() function implements a specific check to start - * associated ZRTP multi-stream sessions. - * - * Coordinate this callback class with the associated GUI implementation class - * - * @see net.java.sip.communicator.impl.gui.main.call.ZrtpSecurityPanel - * - * @author Emanuel Onica - * @author Werner Dittmann - * @author Yana Stamcheva - */ -public class SecurityEventManager extends ZrtpUserCallback -{ - /** - * Our class logger. - */ - private static final Logger logger - = Logger.getLogger(SecurityEventManager.class); - - /** - * A warning String that we display to the user. - */ - public static final String WARNING_NO_RS_MATCH = - getI18NString("impl.media.security.WARNING_NO_RS_MATCH", null); - - /** - * A warning String that we display to the user. - */ - public static final String WARNING_NO_EXPECTED_RS_MATCH = - getI18NString("impl.media.security.WARNING_NO_EXPECTED_RS_MATCH", null); - - /** - * Indicates an audio session type. - */ - public static final int AUDIO_SESSION = - CallPeerSecurityStatusEvent.AUDIO_SESSION; - - /** - * Indicates a video session type. - */ - public static final int VIDEO_SESSION = - CallPeerSecurityStatusEvent.VIDEO_SESSION; - - /** - * The zrtp control that this manager is associated with. - */ - private final ZrtpControlImpl zrtpControl; - - /** - * A callback to the instance that created us. - */ - private SrtpListener securityListener; - - /** - * Is this a ZRTP DH (Master) session? - */ - private boolean isDHSession = false; - - /** - * Type of session - */ - private int sessionType; - - /** - * SAS string. - */ - private String sas; - - /** - * Cipher. - */ - private String cipher; - - /** - * Indicates if the SAS has already been verified in a previous session. - */ - private boolean isSasVerified; - - /** - * The class constructor. - * - * @param zrtpControl that this manager is to be associated with. - */ - public SecurityEventManager(ZrtpControlImpl zrtpControl) - { - this.zrtpControl = zrtpControl; - this.securityListener = zrtpControl.getSrtpListener(); - } - - /** - * Set the type of this session. - * - * @param type the session type. The session type could be either - * AUDIO_SESSION or VIDEO_SESSION. - */ - public void setSessionType(int type) - { - sessionType = type; - } - - /** - * Set the DH session flag. - * - * @param isDHSession the DH session flag. - */ - public void setDHSession(boolean isDHSession) - { - this.isDHSession = isDHSession; - } - - /* - * The following methods implement the ZrtpUserCallback interface - */ - - /** - * Reports the security algorithm that the ZRTP protocol negotiated. - * - * @param cipher the cipher - */ - @Override - public void secureOn(String cipher) - { - if (logger.isDebugEnabled()) - logger.debug(sessionTypeToString(sessionType) - + ": cipher enabled: " + cipher); - - this.cipher = cipher; - } - - /** - * ZRTP computes the SAS string after nearly all the negotiation - * and computations are done internally. - * - * @param sas The string containing the SAS. - * @param isVerified is sas verified. - */ - @Override - public void showSAS(String sas, boolean isVerified) - { - if (logger.isDebugEnabled()) - logger.debug(sessionTypeToString(sessionType) + ": SAS is: " + sas); - - this.sas = sas; - this.isSasVerified = isVerified; - } - - /** - * Show some information to user. - * ZRTP calls this method to display some information to the user. - * Along with the message ZRTP provides a severity indicator that defines: - * Info, Warning, Error, and Alert. - * @param sev severity of the message. - * @param subCode the message code. - */ - @Override - public void showMessage(ZrtpCodes.MessageSeverity sev, - EnumSet subCode) - { - int multiStreams = 0; - - Iterator ii = subCode.iterator(); - Object msgCode = ii.next(); - - String message = null; - String i18nMessage = null; - int severity = 0; - - boolean sendEvent = true; - - if (msgCode instanceof ZrtpCodes.InfoCodes) - { - ZrtpCodes.InfoCodes inf = (ZrtpCodes.InfoCodes) msgCode; - - // Use the following fields if INFORMATION type messages shall be - // shown to the user via SecurityMessageEvent, i.e. if - // sendEvent is set to true - // severity = CallPeerSecurityMessageEvent.INFORMATION; - - // Don't spam user with info messages, only internal processing - // or logging. - sendEvent = false; - - // If the ZRTP Master session (DH mode) signals "security on" - // then start multi-stream sessions. - // Signal SAS to GUI only if this is a DH mode session. - // Multi-stream session don't have own SAS data - if (inf == ZrtpCodes.InfoCodes.InfoSecureStateOn) - { - if (isDHSession) - { - securityListener.securityTurnedOn( - sessionType, cipher, - zrtpControl); - } - else - { - securityListener.securityTurnedOn(sessionType, cipher, - zrtpControl); - } - } - } - else if (msgCode instanceof ZrtpCodes.WarningCodes) - { - // Warning codes usually do not affect encryption or security. Only - // in few cases inform the user and ask to verify SAS. - ZrtpCodes.WarningCodes warn = (ZrtpCodes.WarningCodes) msgCode; - severity = CallPeerSecurityMessageEvent.WARNING; - - if (warn == ZrtpCodes.WarningCodes.WarningNoRSMatch) - { - message = "No retained shared secret available."; - i18nMessage = WARNING_NO_RS_MATCH; - } - else if (warn == ZrtpCodes.WarningCodes.WarningNoExpectedRSMatch) - { - message = "An expected retained shared secret is missing."; - i18nMessage = WARNING_NO_EXPECTED_RS_MATCH; - } - else if (warn == ZrtpCodes.WarningCodes.WarningCRCmismatch) - { - message = "Internal ZRTP packet checksum mismatch."; - i18nMessage = getI18NString( - "impl.media.security.CHECKSUM_MISMATCH", null); - } - else - { - // Other warnings are internal only, no user action required - sendEvent = false; - } - } - else if (msgCode instanceof ZrtpCodes.SevereCodes) - { - ZrtpCodes.SevereCodes severe = (ZrtpCodes.SevereCodes) msgCode; - severity = CallPeerSecurityMessageEvent.SEVERE; - - if (severe == ZrtpCodes.SevereCodes.SevereCannotSend) - { - message = "Failed to send data." - + "Internet data connection or peer is down."; - i18nMessage =getI18NString( - "impl.media.security.DATA_SEND_FAILED", msgCode.toString()); - } - else if (severe == ZrtpCodes.SevereCodes.SevereTooMuchRetries) - { - message = "Too much retries during ZRTP negotiation."; - i18nMessage = getI18NString( - "impl.media.security.RETRY_RATE_EXCEEDED", - msgCode.toString()); - } - else if (severe == ZrtpCodes.SevereCodes.SevereProtocolError) - { - message = "Internal protocol error occured."; - i18nMessage = getI18NString( - "impl.media.security.INTERNAL_PROTOCOL_ERROR", - msgCode.toString()); - } - else - { - message = "General error has occurred."; - i18nMessage = getI18NString( - "impl.media.security.ZRTP_GENERIC_MSG", - msgCode.toString()); - } - } - else if (msgCode instanceof ZrtpCodes.ZrtpErrorCodes) - { - severity = CallPeerSecurityMessageEvent.ERROR; - - message = "Indicates compatibility problems like for example:" - + "unsupported protocol version, unsupported hash type," - + "cypher type, SAS scheme, etc."; - i18nMessage = getI18NString( - "impl.media.security.ZRTP_GENERIC_MSG", - msgCode.toString()); - } - else - { - // Other warnings are internal only, no user action required - sendEvent = false; - } - - if (sendEvent) - securityListener - .securityMessageReceived(message, i18nMessage, severity); - - if (logger.isDebugEnabled()) - logger.debug(sessionTypeToString(sessionType) + ": " - + "ZRTP message: severity: " + sev + ", sub code: " + msgCode - + ", DH session: " + isDHSession + ", multi: " + multiStreams); - } - - /** - * Negotiation has failed. - * - * @param severity of the message. - * @param subCode the message code. - */ - @Override - public void zrtpNegotiationFailed( ZrtpCodes.MessageSeverity severity, - EnumSet subCode) - { - Iterator ii = subCode.iterator(); - Object msgCode = ii.next(); - - if (logger.isDebugEnabled()) - logger.debug(sessionTypeToString(sessionType) - + ": ZRTP key negotiation failed, sub code: " + msgCode); - } - - /** - * Inform user interface that security is not active any more. - */ - @Override - public void secureOff() - { - if (logger.isDebugEnabled()) - logger.debug(sessionTypeToString(sessionType) + ": Security off"); - - securityListener.securityTurnedOff(sessionType); - } - - /** - * The other part does not support zrtp. - */ - @Override - public void zrtpNotSuppOther() - { - if (logger.isDebugEnabled()) - logger.debug(sessionTypeToString(sessionType) - + ": Other party does not support ZRTP key negotiation protocol," - + " no secure calls possible."); - - securityListener.securityTimeout(sessionType); - } - - /** - * Inform the user that ZRTP received "go clear" message from its peer. - */ - @Override - public void confirmGoClear() - { - if (logger.isDebugEnabled()) - logger.debug(sessionTypeToString(sessionType) - + ": GoClear confirmation requested."); - } - - /** - * Converts the sessionType into into a String. - * - * @param sessionType one of the - * CallPeerSecurityStatusEvent.XXX_SESSION fields - * - * @return a String representation of sessionType. - */ - private String sessionTypeToString(int sessionType) - { - switch (sessionType) - { - case AUDIO_SESSION: - return "AUDIO_SESSION"; - case VIDEO_SESSION: - return "VIDEO_SESSION"; - default: - throw new IllegalArgumentException("sessionType"); - } - } - - /** - * Gets the localized message and replace the param. If the param is null - * we ignore it. - * - * @param key the key for the localized message. - * @param param the param to replace. - * @return the i18n message. - */ - private static String getI18NString(String key, String param) - { - ResourceManagementService resources = NeomediaActivator.getResources(); - - if (resources == null) - return null; - else - { - String[] params = (param == null) ? null : new String[] { param }; - - return resources.getI18NString(key, params); - } - } - - /** - * Sets a new receiver of the security callback events. - * @param securityListener An object that receives the security events. - */ - public void setSrtpListener(SrtpListener securityListener) - { - this.securityListener = securityListener; - } - - /** - * Gets the SAS for the current media stream. - * - * @return the four character ZRTP SAS. - */ - public String getSecurityString() - { - return sas; - } - - /** - * Gets the cipher information for the current media stream. - * - * @return the cipher information string. - */ - public String getCipherString() - { - return cipher; - } - - /** - * Gets the status of the SAS verification. - * - * @return true when the SAS has been verified. - */ - public boolean isSecurityVerified() - { - return isSasVerified; - } - - /** - * Indicates that we started the process of securing the the connection. - */ - public void securityNegotiationStarted() - { - // make sure we don't throw any exception - try - { - this.securityListener - .securityNegotiationStarted(sessionType, zrtpControl); - } - catch(Throwable t) - { - logger.error("Error processing security started."); - } - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZRTCPTransformer.java b/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZRTCPTransformer.java deleted file mode 100644 index cb621ec6f..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZRTCPTransformer.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform.zrtp; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.transform.*; - -/** - * PacketTransformer that delegates the forward/reverse transformation of - * packets to different packet transformers. - * - * @author Werner Dittmann - */ -public class ZRTCPTransformer - implements PacketTransformer -{ - /** - * We support different SRTCP contexts for input and output traffic: - * - * Transform() uses the srtcpOut to perform encryption - * reverseTransform() uses srtcpIn to perform decryption - */ - private PacketTransformer srtcpIn = null; - private PacketTransformer srtcpOut = null; - - /** - * Close the transformer engine. - * - * The close functions closes all stored default crypto contexts. This deletes key data - * and forces a cleanup of the crypto contexts. - */ - public void close() - { - if (srtcpOut != null) - { - srtcpOut.close(); - srtcpOut = null; - } - if (srtcpIn != null) - { - srtcpIn.close(); - srtcpIn = null; - } - } - /** - * Encrypt a SRTCP packet - * - * Currently SRTCP packet encryption / decryption is not supported - * So this method does not change the packet content - * - * @param pkt plain SRTCP packet to be encrypted - * @return encrypted SRTCP packet - */ - public RawPacket transform(RawPacket pkt) - { - if (srtcpOut == null) - { - return pkt; - } - return srtcpOut.transform(pkt); - } - - /** - * Decrypt a SRTCP packet - * - * Currently SRTCP packet encryption / decryption is not supported - * So this method does not change the packet content - * - * @param pkt encrypted SRTCP packet to be decrypted - * @return decrypted SRTCP packet - */ - public RawPacket reverseTransform(RawPacket pkt) - { - if (srtcpIn == null) - { - return pkt; - } - return srtcpIn.reverseTransform(pkt); - } - - /** - * @param srtcpIn the srtcpIn to set - */ - public void setSrtcpIn(PacketTransformer srtcpIn) - { - this.srtcpIn = srtcpIn; - } - - /** - * @param srtcpOut the srtcpOut to set - */ - public void setSrtcpOut(PacketTransformer srtcpOut) - { - this.srtcpOut = srtcpOut; - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZRTPTransformEngine.java b/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZRTPTransformEngine.java deleted file mode 100644 index 0981397d8..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZRTPTransformEngine.java +++ /dev/null @@ -1,1482 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform.zrtp; - -import gnu.java.zrtp.*; -import gnu.java.zrtp.zidfile.*; - -import java.io.*; -import java.util.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.impl.neomedia.transform.*; -import net.java.sip.communicator.impl.neomedia.transform.srtp.*; -import net.java.sip.communicator.service.fileaccess.*; -import net.java.sip.communicator.util.*; - -/** - * JMF extension/connector to support GNU ZRTP4J. - * - * ZRTP was developed by Phil Zimmermann and provides functions to negotiate - * keys and other necessary data (crypto data) to set-up the Secure RTP (SRTP) - * crypto context. Refer to Phil's ZRTP specification at his - * Zfone project site to get more - * detailed information about the capabilities of ZRTP. - * - *

Short overview of the ZRTP4J implementation

- * - * ZRTP is a specific protocol to negotiate encryption algorithms and the - * required key material. ZRTP uses a RTP session to exchange its protocol - * messages. - * - * A complete GNU ZRTP4J implementation consists of two parts, the GNU ZRTP4J - * core and specific code that binds the GNU ZRTP core to the underlying - * RTP/SRTP stack and the operating system: - *
    - *
  • The GNU ZRTP core is independent of a specific RTP/SRTP stack and the - * operating system and consists of the ZRTP protocol state engine, the ZRTP - * protocol messages, and the GNU ZRTP4J engine. The GNU ZRTP4J engine provides - * methods to setup ZRTP message and to analyze received ZRTP messages, to - * compute the crypto data required for SRTP, and to maintain the required - * hashes and HMAC.
  • - *
  • The second part of an implementation is specific glue code - * the binds the GNU ZRTP core to the actual RTP/SRTP implementation and other - * operating system specific services such as timers.
  • - *
- * - * The GNU ZRTP4J core uses a callback interface class (refer to ZrtpCallback) - * to access RTP/SRTP or operating specific methods, for example to send data - * via the RTP/SRTP stack, to access timers, provide mutex handling, and to - * report events to the application. - * - *

The ZRTPTransformEngine

- * - * ZRTPTransformEngine implements code that is specific to the JMF - * implementation. - * - * To perform its tasks ZRTPTransformEngine - *
    - *
  • extends specific classes to hook into the JMF RTP methods and the - * RTP/SRTP send and receive queues
  • - *
  • implements the ZrtpCallback interface to provide to enable data send and - * receive other specific services (timer to GNU ZRTP4J
  • - *
  • provides ZRTP specific methods that applications may use to control and - * setup GNU ZRTP
  • - *
  • can register and use an application specific callback class (refer to - * ZrtpUserCallback)
  • - *
- * - * After instantiating a GNU ZRTP4J session (see below for a short example) - * applications may use the ZRTP specific methods of ZRTPTransformEngine to - * control and setup GNU ZRTP, for example enable or disable ZRTP processing or - * getting ZRTP status information. - * - * GNU ZRTP4J provides a ZrtpUserCallback class that an application may extend - * and register with ZRTPTransformEngine. GNU ZRTP4J and ZRTPTransformEngine use - * the ZrtpUserCallback methods to report ZRTP events to the application. The - * application may display this information to the user or act otherwise. - * - * The following figure depicts the relationships between ZRTPTransformEngine, - * JMF implementation, the GNU ZRTP4J core, and an application that provides an - * ZrtpUserCallback class. - * - *
- *
- *                  +---------------------------+
- *                  |  ZrtpTransformConnector   |
- *                  | extends TransformConnector|
- *                  | implements RTPConnector   |
- *                  +---------------------------+
- *                                |
- *                                | uses
- *                                |
- *  +----------------+      +-----+---------------+
- *  |  Application   |      |                     |      +----------------+
- *  |  instantiates  | uses | ZRTPTransformEngine | uses |                |
- *  | a ZRTP Session +------+    implements       +------+   GNU ZRTP4J   |
- *  |  and provides  |      |   ZrtpCallback      |      |      core      |
- *  |ZrtpUserCallback|      |                     |      | implementation |
- *  +----------------+      +---------------------+      |  (ZRtp et al)  |
- *                                                       |                |
- *                                                       +----------------+
- * 
- * - * The following short code snippets show how an application could instantiate a - * ZrtpTransformConnector, get the ZRTP4J engine and initialize it. Then the - * code get a RTP manager instance and initializes it with the - * ZRTPTransformConnector. Please note: setting the target must be done with the - * connector, not with the RTP manager. - * - *
- * ...
- *   transConnector = (ZrtpTransformConnector)TransformManager
- *                                                  .createZRTPConnector(sa);
- *   zrtpEngine = transConnector.getEngine();
- *   zrtpEngine.setUserCallback(new MyCallback());
- *   if (!zrtpEngine.initialize("test_t.zid"))
- *       System.out.println("iniatlize failed");
- *
- *   // initialize the RTPManager using the ZRTP connector
- *
- *   mgr = RTPManager.newInstance();
- *   mgr.initialize(transConnector);
- *
- *   mgr.addSessionListener(this);
- *   mgr.addReceiveStreamListener(this);
- *
- *   transConnector.addTarget(target);
- *   zrtpEngine.startZrtp();
- *
- *   ...
- * 
- * - * The demo folder contains a small example that shows how to use GNU - * ZRTP4J. - * - * This ZRTPTransformEngine documentation shows the ZRTP specific extensions and - * describes overloaded methods and a possible different behaviour. - * - * @author Werner Dittmann <Werner.Dittmann@t-online.de> - * - */ -public class ZRTPTransformEngine - implements TransformEngine, - PacketTransformer, - ZrtpCallback -{ - /** - * Very simple Timeout provider class. - * - * This very simple timeout provider can handle one timeout request at - * one time only. A second request would overwrite the first one and would - * lead to unexpected results. - * - * @author Werner Dittmann - */ - private class TimeoutProvider extends Thread - { - /** - * Constructs Timeout provider. - * @param name the name of the provider. - */ - public TimeoutProvider(String name) - { - super(name); - } - - /** - * The delay to wait before timeout. - */ - private long nextDelay = 0; - - /** - * Whether to execute the timeout if delay expires. - */ - private boolean newTask = false; - - /** - * Whether thread is stopped. - */ - private boolean stop = false; - - /** - * synchronizes delays and stop. - */ - private final Object sync = new Object(); - - /** - * Request timeout after the specified delay. - * @param delay the delay. - */ - public synchronized void requestTimeout(long delay) - { - synchronized (sync) - { - nextDelay = delay; - newTask = true; - sync.notifyAll(); - } - } - - /** - * Stops the thread. - */ - public void stopRun() - { - synchronized (sync) - { - stop = true; - sync.notifyAll(); - } - } - - /** - * Cancels the last request. - */ - public void cancelRequest() - { - synchronized (sync) - { - newTask = false; - sync.notifyAll(); - } - } - - /** - * The running part of the thread. - */ - @Override - public void run() - { - while (!stop) - { - synchronized (sync) - { - while (!newTask && !stop) - { - try - { - sync.wait(); - } - catch (InterruptedException e) - { - // e.printStackTrace(); - } - } - } - long currentTime = System.currentTimeMillis(); - long endTime = currentTime + nextDelay; - synchronized (sync) { - while ((currentTime < endTime) && newTask && !stop) - { - try - { - sync.wait(endTime - currentTime); - } - catch (InterruptedException e) - { - //e.printStackTrace(); - } - currentTime = System.currentTimeMillis(); - } - } - if (newTask && !stop) - { - newTask = false; - ZRTPTransformEngine.this.handleTimeout(); - } - } - } - } - - /** - * The logger. - */ - private static final Logger logger - = Logger.getLogger(ZRTPTransformEngine.class); - - /** - * Each ZRTP packet has a fixed header of 12 bytes. - */ - protected static final int ZRTP_PACKET_HEADER = 12; - - /** - * This is the connector, required to send ZRTP packets - * via the DatagramSocket. - */ - private AbstractRTPConnector zrtpConnector = null; - - /** - * We need Out SRTPTransformer to transform RTP to SRTP. - */ - private PacketTransformer srtpOutTransformer = null; - - /** - * We need In SRTPTransformer to transform SRTP to RTP. - */ - private PacketTransformer srtpInTransformer = null; - - /** - * User callback class. - */ - private SecurityEventManager securityEventManager = null; - - /** - * The ZRTP engine. - */ - private ZRtp zrtpEngine = null; - - /** - * ZRTP engine enable flag (used for auto-enable at initialization) - */ - private boolean enableZrtp = false; - - /** - * Client ID string initialized with the name of the ZRTP4j library - */ - private String clientIdString = ZrtpConstants.clientId; - - /** - * SSRC identifier for the ZRTP packets - */ - private int ownSSRC = 0; - - /** - * ZRTP packet sequence number - */ - private short senderZrtpSeqNo = 0; - - /** - * The timeout provider instance - * This is used for handling the ZRTP timers - */ - private TimeoutProvider timeoutProvider = null; - - /** - * The current condition of the ZRTP engine - */ - private boolean started = false; - - /** - * Sometimes we need to start muted so we will discard any packets during - * some time after the start of the transformer. This is needed when for - * this time we can receive encrypted packets but we hadn't established - * a secure communication. This happens when a secure stream is recreated. - */ - private boolean muted = false; - - private boolean mitmMode = false; - - /** - * Enable or disable paranoid mode. - * - * The Paranoid mode controls the behaviour and handling of the SAS verify - * flag. If Panaoid mode is set to flase then ZRtp applies the normal - * handling. If Paranoid mode is set to true then the handling is: - * - *
    - *
  • Force the SAS verify flag to be false at srtpSecretsOn() callback. - * This gives the user interface (UI) the indication to handle the SAS - * as not verified. See implementation note below.
  • - *
  • Don't set the SAS verify flag in the Confirm packets, - * thus the other also must report the SAS as not verified.
  • - *
  • ignore the SASVerified() function, thus do not set the - * SAS to verified in the ZRTP cache.
  • - *
  • Disable the Trusted PBX MitM feature. Just send the - * SASRelay packet but do not process the relayed data. - * This protects the user from a malicious "trusted PBX".
  • - *
- * ZRtp performs alls other steps during the ZRTP negotiations as usual, in - * particular it computes, compares, uses, and stores the retained secrets. - * This avoids unnecessary warning messages. The user may enable or disable - * the Paranoid mode on a call-by-call basis without breaking the key - * continuity data. - * - * Implementation note:
- * An application shall always display the SAS code if the SAS verify flag - * is false. The application shall also use mechanisms to - * remind the user to compare the SAS code, for example useing larger fonts, - * different colours and other display features. - */ - private boolean enableParanoidMode = false; - - private ZRTCPTransformer zrtcpTransformer = null; - - /** - * Construct a ZRTPTransformEngine. - * - */ - public ZRTPTransformEngine() - { - senderZrtpSeqNo = 1; // should be a random number - } - - /** - * Returns an instance of ZRTPCTransformer. - * - * @see TransformEngine#getRTCPTransformer() - */ - public ZRTCPTransformer getRTCPTransformer() - { - if(zrtcpTransformer == null) - zrtcpTransformer = new ZRTCPTransformer(); - return zrtcpTransformer; - } - - /** - * Returns this RTPTransformer. - * - * @see TransformEngine#getRTPTransformer() - */ - public PacketTransformer getRTPTransformer() - { - return this; - } - - /** - * Engine initialization method. - * Calling this for engine initialization and start it with auto-sensing - * and a given configuration setting. - * - * @param zidFilename The ZID file name - * @param config The configuration data - * @return true if initialization fails, false if succeeds - */ - public boolean initialize(String zidFilename, ZrtpConfigure config) - { - return initialize(zidFilename, true, config); - } - - /** - * Engine initialization method. - * Calling this for engine initialization and start it with defined - * auto-sensing and a default configuration setting. - * - * @param zidFilename The ZID file name - * @param autoEnable If true start with auto-sensing mode. - * @return true if initialization fails, false if succeeds - */ - public boolean initialize(String zidFilename, boolean autoEnable) - { - return initialize(zidFilename, autoEnable, null); - } - - /** - * Default engine initialization method. - * - * Calling this for engine initialization and start it with auto-sensing - * and default configuration setting. - * - * @param zidFilename The ZID file name - * @return true if initialization fails, false if succeeds - */ - public boolean initialize(String zidFilename) - { - return initialize(zidFilename, true, null); - } - - /** - * Custom engine initialization method. - * This allows to explicit specify if the engine starts with auto-sensing - * or not. - * - * @param zidFilename The ZID file name - * @param autoEnable Set this true to start with auto-sensing and false to - * disable it. - * @param config the zrtp config to use - * @return true if initialization fails, false if succeeds - */ - public synchronized boolean initialize( - String zidFilename, - boolean autoEnable, - ZrtpConfigure config) - { - // Try to get the ZidFile path through the FileAccessService. - File file = null; - FileAccessService faService = NeomediaActivator.getFileAccessService(); - - if (faService != null) - { - try - { - // Create the zid file - file = faService.getPrivatePersistentFile(zidFilename); - } - catch (Exception e) - { - logger.warn("Failed to create the zid file."); - } - } - - // The ZidFile path should be absolute. - String zidFilePath = null; - - try - { - if (file != null) - zidFilePath = file.getAbsolutePath(); - } - catch (SecurityException e) - { - if (logger.isDebugEnabled()) - { - logger.debug( - "Failed to obtain the absolute path of the zid file.", - e); - } - } - - ZidFile zf = ZidFile.getInstance(); - - if (!zf.isOpen()) - { - if (zidFilePath == null) - { - String home = System.getenv("HOME"); - String baseDir - = ((home == null) || (home.length() < 1)) - ? "" - : (home + "/"); - - zidFilePath = baseDir + ".GNUZRTP4J.zid"; - } - if (zf.open(zidFilePath) < 0) - return false; - } - - if (config == null) - { - config = new ZrtpConfigure(); - config.setStandardConfig(); - } - if (enableParanoidMode) - config.setParanoidMode(enableParanoidMode); - - zrtpEngine - = new ZRtp(zf.getZid(), this, clientIdString, config, mitmMode); - - if (timeoutProvider == null) - { - timeoutProvider = new TimeoutProvider("ZRTP"); - // XXX Daemon only if timeoutProvider is a global singleton. - // timeoutProvider.setDaemon(true); - timeoutProvider.start(); - } - - enableZrtp = autoEnable; - return true; - } - - /** - * - * @param startMuted whether to be started as muted if no secure - * communication is established - */ - public void setStartMuted(boolean startMuted) - { - muted = startMuted; - if(startMuted) - { - // make sure we don't mute for long time as secure communication - // may fail. - new Timer().schedule(new TimerTask() - { - public void run() - { - ZRTPTransformEngine.this.muted = false; - } - }, 1500); - } - } - - /** - * Method for getting the default secure status value for communication - * - * @return the default enabled/disabled status value for secure - * communication - */ - public boolean getSecureCommunicationStatus() - { - return srtpInTransformer != null || srtpOutTransformer != null; - } - - /** - * Start the ZRTP stack immediately, not autosensing mode. - */ - public void startZrtp() - { - if (zrtpEngine != null) - { - zrtpEngine.startZrtpEngine(); - started = true; - - securityEventManager.securityNegotiationStarted(); - } - } - - /** - * Close the transformer and underlying transform engine. - * - * The close functions closes all stored crypto contexts. This deletes key data - * and forces a cleanup of the crypto contexts. - */ - public void close() - { - stopZrtp(); - } - - /** - * Stop ZRTP engine. - */ - public void stopZrtp() - { - if (zrtpEngine != null) - { - zrtpEngine.stopZrtp(); - zrtpEngine = null; - started = false; - } - // The SRTP transformer are usually already closed durin security-off - // processing. Check here again just in case ... - if (srtpOutTransformer != null) - { - srtpOutTransformer.close(); - srtpOutTransformer = null; - } - if (srtpInTransformer != null) - { - srtpInTransformer.close(); - srtpOutTransformer = null; - } - if (zrtcpTransformer != null) - { - zrtcpTransformer.close(); - zrtcpTransformer = null; - } - } - - /** - * Cleanup function for any remaining timers - */ - public void cleanup() - { - if (timeoutProvider != null) - { - timeoutProvider.stopRun(); - timeoutProvider = null; - } - } - - /** - * Set the SSRC of the RTP transmitter stream. - * - * ZRTP fills the SSRC in the ZRTP messages. - * - * @param ssrc SSRC to set - */ - public void setOwnSSRC(long ssrc) - { - ownSSRC = (int)(ssrc & 0xffffffff); - } - - /** - * The data output stream calls this method to transform outgoing - * packets. - * - * @see PacketTransformer#transform(RawPacket) - */ - public RawPacket transform(RawPacket pkt) - { - /* - * Never transform outgoing ZRTP (invalid RTP) packets. - */ - if (ZrtpRawPacket.isZrtpData(pkt)) - { - return pkt; - } - - // ZRTP needs the SSRC of the sending stream. - if (enableZrtp && ownSSRC == 0) - { - ownSSRC = pkt.getSSRC(); - } - - // If SRTP is active then srtpTransformer is set, use it. - if (srtpOutTransformer == null) - { - return pkt; - } - - return srtpOutTransformer.transform(pkt); - } - - /** - * The input data stream calls this method to transform - * incoming packets. - * - * @see PacketTransformer#reverseTransform(RawPacket) - */ - public RawPacket reverseTransform(RawPacket pkt) - { - // Check if we need to start ZRTP - if (!started && enableZrtp && ownSSRC != 0) - startZrtp(); - - /* - * Check if incoming packet is a ZRTP packet, if not treat - * it as normal RTP packet and handle it accordingly. - */ - if (!ZrtpRawPacket.isZrtpData(pkt)) - { - if (srtpInTransformer == null) - { - if(muted) - { - return null; - } - else - return pkt; - } - - RawPacket pkt2 = srtpInTransformer.reverseTransform(pkt); - // if packet was valid (i.e. not null) and ZRTP engine started and - // in Wait for Confirm2 Ack then emulate a Conf2Ack packet. - // See ZRTP specification chap. 5.6 - if ((pkt2 != null) - && started - && zrtpEngine - .inState(ZrtpStateClass.ZrtpStates.WaitConfAck)) - { - zrtpEngine.conf2AckSecure(); - } - - return pkt2; - } - - /* - * If ZRTP is enabled process it. - * - * In any case return null because ZRTP packets must never reach - * the application. - */ - if (enableZrtp && started) - { - ZrtpRawPacket zPkt = new ZrtpRawPacket(pkt); - if (!zPkt.checkCrc()) - { - securityEventManager - .showMessage( - ZrtpCodes.MessageSeverity.Warning, - EnumSet.of(ZrtpCodes.WarningCodes.WarningCRCmismatch)); - } - // Check if it is really a ZRTP packet, if not don't process it - else if (zPkt.hasMagic()) - { - int extHeaderOffset = zPkt.getHeaderLength() - - zPkt.getExtensionLength() - RawPacket.EXT_HEADER_SIZE; - // zrtp engine need a "pointer" to the extension header, so - // we give him the extension header and the payload data - byte[] extHeader = zPkt.readRegion( - extHeaderOffset, - RawPacket.EXT_HEADER_SIZE + - zPkt.getExtensionLength() + zPkt.getPayloadLength()); - zrtpEngine.processZrtpMessage(extHeader, zPkt.getSSRC()); - } - } - - return null; - } - - /** - * The callback method required by the ZRTP implementation. - * First allocate space to hold the complete ZRTP packet, copy - * the message part in its place, the initalize the header, counter, - * SSRC and crc. - * - * @param data The ZRTP packet data - * @return true if sending succeeds, false if it fails - */ - public boolean sendDataZRTP(byte[] data) - { - int totalLength = ZRTP_PACKET_HEADER + data.length; - byte[] tmp = new byte[totalLength]; - System.arraycopy(data, 0, tmp, ZRTP_PACKET_HEADER, data.length); - ZrtpRawPacket packet = new ZrtpRawPacket(tmp, 0, tmp.length); - - packet.setSSRC(ownSSRC); - - packet.setSeqNum(senderZrtpSeqNo++); - - packet.setCrc(); - - try - { - zrtpConnector.getDataOutputStream().write( packet.getBuffer(), - packet.getOffset(), - packet.getLength()); - } - catch (IOException e) - { - logger.warn("Failed to send ZRTP data."); - - if (logger.isDebugEnabled()) - logger.debug("Failed to send ZRTP data.", e); - - return false; - } - return true; - } - - /** - * Switch on the security for the defined part. - * - * @param secrets The secret keys and salt negotiated by ZRTP - * @param part An enum that defines sender, receiver, or both. - * @return always return true. - */ - public boolean srtpSecretsReady( - ZrtpSrtpSecrets secrets, EnableSecurity part) - { - SRTPPolicy srtpPolicy = null; - int cipher = 0, authn = 0, authKeyLen = 0; - - if (secrets.getAuthAlgorithm() == ZrtpConstants.SupportedAuthAlgos.HS) - { - authn = SRTPPolicy.HMACSHA1_AUTHENTICATION; - authKeyLen = 20; - } - if (secrets.getAuthAlgorithm() == ZrtpConstants.SupportedAuthAlgos.SK) - { - authn = SRTPPolicy.SKEIN_AUTHENTICATION; - authKeyLen = 32; - } - if (secrets.getSymEncAlgorithm() == ZrtpConstants.SupportedSymAlgos.AES) - cipher = SRTPPolicy.AESCM_ENCRYPTION; - - if (secrets.getSymEncAlgorithm() == ZrtpConstants.SupportedSymAlgos.TwoFish) - cipher = SRTPPolicy.TWOFISH_ENCRYPTION; - - if (part == EnableSecurity.ForSender) - { - // To encrypt packets: initiator uses initiator keys, - // responder uses responder keys - // Create a "half baked" crypto context first and store it. This is - // the main crypto context for the sending part of the connection. - if (secrets.getRole() == Role.Initiator) - { - srtpPolicy = new SRTPPolicy(cipher, - secrets.getInitKeyLen() / 8, // key length - authn, authKeyLen, // auth key length - secrets.getSrtpAuthTagLen() / 8,// auth tag length - secrets.getInitSaltLen() / 8 // salt length - ); - - SRTPTransformEngine engine = new SRTPTransformEngine(secrets - .getKeyInitiator(), secrets.getSaltInitiator(), - srtpPolicy, srtpPolicy); - - srtpOutTransformer = engine.getRTPTransformer(); - getRTCPTransformer().setSrtcpOut(engine.getRTCPTransformer()); - } - else - { - srtpPolicy = new SRTPPolicy(cipher, - secrets.getRespKeyLen() / 8, // key length - authn, authKeyLen, // auth key length - secrets.getSrtpAuthTagLen() / 8,// auth taglength - secrets.getRespSaltLen() / 8 // salt length - ); - - SRTPTransformEngine engine = new SRTPTransformEngine(secrets - .getKeyResponder(), secrets.getSaltResponder(), - srtpPolicy, srtpPolicy); - srtpOutTransformer = engine.getRTPTransformer(); - getRTCPTransformer().setSrtcpOut(engine.getRTCPTransformer()); - } - } - - if (part == EnableSecurity.ForReceiver) - { - // To decrypt packets: initiator uses responder keys, - // responder initiator keys - // See comment above. - if (secrets.getRole() == Role.Initiator) - { - srtpPolicy = new SRTPPolicy(cipher, - secrets.getRespKeyLen() / 8, // key length - authn, authKeyLen, // auth key length - secrets.getSrtpAuthTagLen() / 8,// auth tag length - secrets.getRespSaltLen() / 8 // salt length - ); - - SRTPTransformEngine engine = new SRTPTransformEngine(secrets - .getKeyResponder(), secrets.getSaltResponder(), - srtpPolicy, srtpPolicy); - srtpInTransformer = engine.getRTPTransformer(); - getRTCPTransformer().setSrtcpIn(engine.getRTCPTransformer()); - this.muted = false; - } - else - { - srtpPolicy = new SRTPPolicy(cipher, - secrets.getInitKeyLen() / 8, // key length - authn, authKeyLen, // auth key length - secrets.getSrtpAuthTagLen() / 8,// auth tag length - secrets.getInitSaltLen() / 8 // salt length - ); - - SRTPTransformEngine engine = new SRTPTransformEngine(secrets - .getKeyInitiator(), secrets.getSaltInitiator(), - srtpPolicy, srtpPolicy); - srtpInTransformer = engine.getRTPTransformer(); - getRTCPTransformer().setSrtcpIn(engine.getRTCPTransformer()); - this.muted = false; - } - } - return true; - } - - /** - * - * @param c - * @param s - * @param verified - * @see gnu.java.zrtp.ZrtpCallback#srtpSecretsOn(java.lang.String, - * java.lang.String, boolean) - */ - public void srtpSecretsOn(String c, String s, boolean verified) - { - if (securityEventManager != null) - { - securityEventManager.secureOn(c); - } - - if (securityEventManager != null && (s != null || verified)) - { - securityEventManager.showSAS(s, verified); - } - } - - /** - * This method shall clear the ZRTP secrets. - * - * @param part Defines for which part (sender or receiver) - * to switch on security - */ - public void srtpSecretsOff(EnableSecurity part) - { - if (part == EnableSecurity.ForSender) - { - if (srtpOutTransformer != null) - srtpOutTransformer.close(); - srtpOutTransformer = null; - } - - if (part == EnableSecurity.ForReceiver) - { - if (srtpInTransformer != null) - srtpInTransformer.close(); - srtpInTransformer = null; - } - - if (securityEventManager != null) - { - securityEventManager.secureOff(); - } - } - - /** - * Activate timer. - * @param time The time in ms for the timer. - * @return always return 1. - */ - public int activateTimer(int time) - { - if (timeoutProvider != null) - { - timeoutProvider.requestTimeout(time); - } - - return 1; - } - - /** - * Cancel the active timer. - * @return always return 1. - */ - public int cancelTimer() - { - if (timeoutProvider != null) - { - timeoutProvider.cancelRequest(); - } - return 1; - } - - /** - * Timeout handling function. - * Delegates the handling to the ZRTP engine. - */ - public void handleTimeout() - { - if (zrtpEngine != null) - { - zrtpEngine.processTimeout(); - } - } - - /** - * Send information messages to the hosting environment. - * @param severity This defines the message's severity - * @param subCode The message code. - */ - public void sendInfo(ZrtpCodes.MessageSeverity severity, EnumSet subCode) - { - if (securityEventManager != null) - { - securityEventManager.showMessage(severity, subCode); - } - } - - /** - * Comes a message that zrtp negotiation has failed. - * @param severity This defines the message's severity - * @param subCode The message code. - */ - public void zrtpNegotiationFailed(ZrtpCodes.MessageSeverity severity, - EnumSet subCode) - { - if (securityEventManager != null) - { - securityEventManager.zrtpNegotiationFailed(severity, subCode); - } - } - - /** - * The other part doesn't support zrtp. - */ - public void zrtpNotSuppOther() - { - if (securityEventManager != null) - { - securityEventManager.zrtpNotSuppOther(); - } - } - - /** - * Zrtp ask for Enrollment. - * @param info supplied info. - */ - public void zrtpAskEnrollment(ZrtpCodes.InfoEnrollment info) - { - if (securityEventManager != null) - { - securityEventManager.zrtpAskEnrollment(info); - } - } - - /** - * - * @param info - * @see gnu.java.zrtp.ZrtpCallback#zrtpInformEnrollment( - * gnu.java.zrtp.ZrtpCodes.InfoEnrollment) - */ - public void zrtpInformEnrollment(ZrtpCodes.InfoEnrollment info) - { - if (securityEventManager != null) - { - securityEventManager.zrtpInformEnrollment(info); - } - } - - /** - * - * @param sas - * @see gnu.java.zrtp.ZrtpCallback#signSAS(java.lang.String) - */ - public void signSAS(byte[] sasHash) - { - if (securityEventManager != null) - { - securityEventManager.signSAS(sasHash); - } - } - - /** - * - * @param sas - * @return false if signature check fails, true otherwise - * @see gnu.java.zrtp.ZrtpCallback#checkSASSignature(java.lang.String) - */ - public boolean checkSASSignature(byte[] sasHash) - { - return ((securityEventManager != null) - ? securityEventManager.checkSASSignature(sasHash) - : false); - } - - /** - * Sets the enableZrtp flag. - * - * @param onOff The value for the enableZrtp flag. - */ - public void setEnableZrtp(boolean onOff) - { - enableZrtp = onOff; - } - - /** - * Returns the enableZrtp flag. - * - * @return the enableZrtp flag. - */ - public boolean isEnableZrtp() - { - return enableZrtp; - } - - /** - * Set the SAS as verified internally if the user confirms it - */ - public void SASVerified() - { - if (zrtpEngine != null) - zrtpEngine.SASVerified(); - } - - /** - * Resets the internal engine SAS verified flag - */ - public void resetSASVerified() - { - if (zrtpEngine != null) - zrtpEngine.resetSASVerified(); - } - - /** - * Method called when the user requests through GUI to switch a secured call - * to unsecure mode. Just forwards the request to the Zrtp class. - */ - public void requestGoClear() - { -// if (zrtpEngine != null) -// zrtpEngine.requestGoClear(); - } - - /** - * Method called when the user requests through GUI to switch a previously - * unsecured call back to secure mode. Just forwards the request to the - * Zrtp class. - */ - public void requestGoSecure() - { -// if (zrtpEngine != null) -// zrtpEngine.requestGoSecure(); - } - - /** - * Sets the auxilliary secret data - * - * @param data The auxilliary secret data - */ - public void setAuxSecret(byte[] data) - { - if (zrtpEngine != null) - zrtpEngine.setAuxSecret(data); - } - - /** - * Sets the client ID - * - * @param id The client ID - */ - public void setClientId(String id) - { - clientIdString = id; - } - - /** - * Gets the Hello packet Hash - * - * @return the Hello packet hash - */ - public String getHelloHash() - { - if (zrtpEngine != null) - return zrtpEngine.getHelloHash(); - else - return new String(); - } - - /** - * Get the ZRTP Hello Hash data - separate strings. - * - * @return String array containing the version string at offset 0, the Hello - * hash value as hex-digits at offset 1. Hello hash is available - * immediately after class instantiation. Returns null - * if ZRTP is not available. - */ - public String[] getHelloHashSep() { - if (zrtpEngine != null) - return zrtpEngine.getHelloHashSep(); - else - return null; - } - - /** - * Gets the multistream params - * - * @return the multistream params - */ - public byte[] getMultiStrParams() - { - if (zrtpEngine != null) - return zrtpEngine.getMultiStrParams(); - else - return new byte[0]; - } - - /** - * Sets the multistream params - * (The multistream part needs further development) - * @param parameters the multistream params - */ - public void setMultiStrParams(byte[] parameters) - { - if (zrtpEngine != null) { - zrtpEngine.setMultiStrParams(parameters); - } - } - - /** - * Gets the multistream flag - * (The multistream part needs further development) - * @return the multistream flag - */ - public boolean isMultiStream() - { - return ((zrtpEngine != null) ? zrtpEngine.isMultiStream() : false); - } - - /** - * Used to accept a PBX enrollment request - * (The PBX part needs further development) - * @param accepted The boolean value indicating if the request is accepted - */ - public void acceptEnrollment(boolean accepted) - { - if (zrtpEngine != null) - zrtpEngine.acceptEnrollment(accepted); - } - - /** - * Get the commited SAS rendering algorithm for this ZRTP session. - * - * @return the commited SAS rendering algorithm - */ - public ZrtpConstants.SupportedSASTypes getSasType() { - if (zrtpEngine != null) - return zrtpEngine.getSasType(); - else - return null; - } - - /** - * Get the computed SAS hash for this ZRTP session. - * - * @return a refernce to the byte array that contains the full - * SAS hash. - */ - public byte[] getSasHash() { - if (zrtpEngine != null) - return zrtpEngine.getSasHash(); - else - return null; - } - - /** - * Send the SAS relay packet. - * - * The method creates and sends a SAS relay packet according to the ZRTP - * specifications. Usually only a MitM capable user agent (PBX) uses this - * function. - * - * @param sh the full SAS hash value - * @param render the SAS rendering algorithm - * @return true if the SASReplay packet has been correctly sent, false - * otherwise - */ - public boolean sendSASRelayPacket(byte[] sh, - ZrtpConstants.SupportedSASTypes render) - { - if (zrtpEngine != null) - return zrtpEngine.sendSASRelayPacket(sh, render); - else - return false; - } - /** - * Check the state of the MitM mode flag. - * - * If true then this ZRTP session acts as MitM, usually enabled by a PBX - * based client (user agent) - * - * @return state of mitmMode - */ - public boolean isMitmMode() { - return mitmMode; - } - - /** - * Set the state of the MitM mode flag. - * - * If MitM mode is set to true this ZRTP session acts as MitM, usually - * enabled by a PBX based client (user agent). - * - * @param mitmMode defines the new state of the mitmMode flag - */ - public void setMitmMode(boolean mitmMode) { - this.mitmMode = mitmMode; - } - - /** - * Enables or disables paranoid mode. - * - * For further explanation of paranoid mode refer to the documentation - * of ZRtp class. - * - * @param yesNo - * If set to true then paranoid mode is enabled. - */ - public void setParanoidMode(boolean yesNo) { - enableParanoidMode = yesNo; - } - - /** - * Check status of paranoid mode. - * - * @return - * Returns true if paranoid mode is enabled. - */ - public boolean isParanoidMode() { - return enableParanoidMode; - } - - /** - * Check the state of the enrollment mode. - * - * If true then we will set the enrollment flag (E) in the confirm - * packets and performs the enrollment actions. A MitM (PBX) - * enrollment service sets this flag. - * - * @return status of the enrollmentMode flag. - */ - public boolean isEnrollmentMode() { - if (zrtpEngine != null) - return zrtpEngine.isEnrollmentMode(); - else - return false; - } - - /** - * Set the state of the enrollment mode. - * - * If true then we will set the enrollment flag (E) in the confirm - * packets and perform the enrollment actions. A MitM (PBX) enrollment - * service must set this mode to true. - * - * Can be set to true only if mitmMode is also true. - * - * @param enrollmentMode defines the new state of the enrollmentMode flag - */ - public void setEnrollmentMode(boolean enrollmentMode) { - if (zrtpEngine != null) - zrtpEngine.setEnrollmentMode(enrollmentMode); - } - /** - * Sets signature data for the Confirm packets - * - * @param data the signature data - * @return true if signature data was successfully set - */ - public boolean setSignatureData(byte[] data) - { - return ((zrtpEngine != null) ? zrtpEngine.setSignatureData(data) - : false); - } - - /** - * Gets signature data - * - * @return the signature data - */ - public byte[] getSignatureData() - { - if (zrtpEngine != null) - return zrtpEngine.getSignatureData(); - else - return new byte[0]; - } - - /** - * Gets signature length - * - * @return the signature length - */ - public int getSignatureLength() - { - return ((zrtpEngine != null) ? zrtpEngine.getSignatureLength() : 0); - } - - - /** - * Method called by the Zrtp class as result of a GoClear request from the - * other peer. An explicit user confirmation is needed before switching to - * unsecured mode. This is asked through the user callback. - */ - public void handleGoClear() - { - securityEventManager.confirmGoClear(); - } - - /** - * Sets the RTP connector using this ZRTP engine - * - * @param connector the connector to set - */ - public void setConnector(AbstractRTPConnector connector) - { - zrtpConnector = connector; - } - - /** - * Sets the user callback class used to maintain the GUI ZRTP part - * - * @param ub The user callback class - */ - public void setUserCallback(SecurityEventManager ub) - { - securityEventManager = ub; - } - - /** - * Returns the current status of the ZRTP engine - * - * @return the current status of the ZRTP engine - */ - public boolean isStarted() - { - return started; - } - - /** - * Gets the user callback used to manage the GUI part of ZRTP - * - * @return the user callback - */ - public SecurityEventManager getUserCallback() - { - return securityEventManager; - } - - /** - * Get other party's ZID (ZRTP Identifier) data - * - * This functions returns the other party's ZID that was receivied - * during ZRTP processing. - * - * The ZID data can be retrieved after ZRTP receive the first Hello - * packet from the other party. The application may call this method - * for example during SAS processing in showSAS(...) user callback - * method. - * - * @return the ZID data as byte array. - */ - public byte[] getPeerZid() - { - return ((zrtpEngine != null) ? zrtpEngine.getPeerZid() : null); - } -} diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZrtpRawPacket.java b/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZrtpRawPacket.java deleted file mode 100644 index 2560a9410..000000000 --- a/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZrtpRawPacket.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.neomedia.transform.zrtp; - -import gnu.java.zrtp.packets.*; -import gnu.java.zrtp.utils.*; - -import net.java.sip.communicator.impl.neomedia.*; - -/** - * ZRTP packet representation. - * - * This class extends the RawPacket class and adds some methods - * required by the ZRTP transformer. - * - * @author Werner Dittmann - */ -public class ZrtpRawPacket extends RawPacket -{ - /** - * Each ZRTP packet contains this magic number. - */ - public static byte[] zrtpMagic; - - static { - zrtpMagic = new byte[4]; - zrtpMagic[0]= 0x5a; - zrtpMagic[1]= 0x52; - zrtpMagic[2]= 0x54; - zrtpMagic[3]= 0x50; - } - - /** - * Construct an input ZrtpRawPacket using a received RTP raw packet. - * - * @param pkt a raw RTP packet as received - */ - public ZrtpRawPacket(RawPacket pkt) - { - super (pkt.getBuffer(), pkt.getOffset(), pkt.getLength()); - } - - /** - * Construct an output ZrtpRawPacket using specified value. - * - * Initialize this packet and set the ZRTP magic value - * to mark it as a ZRTP packet. - * - * @param buf Byte array holding the content of this Packet - * @param off Start offset of packet content inside buffer - * @param len Length of the packet's data - */ - public ZrtpRawPacket(byte[] buf, int off, int len) - { - super (buf, off, len); - writeByte(0, (byte)0x10); - writeByte(1, (byte)0); - - int at = 4; - writeByte(at++, zrtpMagic[0]); - writeByte(at++, zrtpMagic[1]); - writeByte(at++, zrtpMagic[2]); - writeByte(at, zrtpMagic[3]); - } - - /** - * Check if it could be a ZRTP packet. - * - * The method checks if the first byte of the received data - * matches the defined ZRTP pattern 0x10 - * - * @return true if could be a ZRTP packet, false otherwise. - */ - protected boolean isZrtpPacket() - { - return isZrtpData(this); - } - - /** - * Checks whether extension bit is set and if so is the extension header - * an zrtp one. - * @param pkt the packet to check. - * @return true if data is zrtp packet. - */ - static boolean isZrtpData(RawPacket pkt) - { - if(!pkt.getExtensionBit()) - return false; - - if(pkt.getHeaderExtensionType() == 0x505a) - return true; - - return false; - } - - /** - * Check if it is really a ZRTP packet. - * - * The method checks if the packet contains the ZRTP magic - * number. - * - * @return true if packet contains the magic number, false otherwise. - */ - protected boolean hasMagic() - { - return - (readByte(4) == zrtpMagic[0]) - && (readByte(5) == zrtpMagic[1]) - && (readByte(6) == zrtpMagic[2]) - && (readByte(7) == zrtpMagic[3]); - } - - /** - * Set the sequence number in this packet. - * @param seq sequence number - */ - protected void setSeqNum(short seq) - { - int at = 2; - writeByte(at++, (byte)(seq>>8)); - writeByte(at, (byte)seq); - } - - /** - * Set SSRC in this packet - * @param ssrc SSRC to set - */ - protected void setSSRC(int ssrc) - { - writeInt(8, ssrc); - } - - /** - * Check if the CRC of this packet is ok. - * - * @return true if the CRC is valid, false otherwise - */ - protected boolean checkCrc() - { - int crc = readInt(getLength()-ZrtpPacketBase.CRC_SIZE); - return ZrtpCrc32.zrtpCheckCksum(getBuffer(), getOffset(), - getLength()-ZrtpPacketBase.CRC_SIZE, crc); - } - - /** - * Set ZRTP CRC in this packet - */ - protected void setCrc() - { - int crc = ZrtpCrc32.zrtpGenerateCksum(getBuffer(), getOffset(), - getLength() - ZrtpPacketBase.CRC_SIZE); - // convert and store CRC in crc field of ZRTP packet. - crc = ZrtpCrc32.zrtpEndCksum(crc); - writeInt(getLength() - ZrtpPacketBase.CRC_SIZE, crc); - } -} diff --git a/src/net/java/sip/communicator/impl/netaddr/Ice4jPacketLogger.java b/src/net/java/sip/communicator/impl/netaddr/Ice4jPacketLogger.java index c41e5ad09..526364418 100644 --- a/src/net/java/sip/communicator/impl/netaddr/Ice4jPacketLogger.java +++ b/src/net/java/sip/communicator/impl/netaddr/Ice4jPacketLogger.java @@ -1,7 +1,7 @@ package net.java.sip.communicator.impl.netaddr; -import net.java.sip.communicator.service.packetlogging.*; import org.ice4j.stack.*; +import org.jitsi.service.packetlogging.*; /** * Logs Packets coming and going through ice4j stack. diff --git a/src/net/java/sip/communicator/impl/netaddr/NetaddrActivator.java b/src/net/java/sip/communicator/impl/netaddr/NetaddrActivator.java index a2295c06e..4109f2517 100644 --- a/src/net/java/sip/communicator/impl/netaddr/NetaddrActivator.java +++ b/src/net/java/sip/communicator/impl/netaddr/NetaddrActivator.java @@ -6,12 +6,13 @@ */ package net.java.sip.communicator.impl.netaddr; -import net.java.sip.communicator.service.packetlogging.*; -import org.osgi.framework.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.netaddr.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.packetlogging.*; +import org.osgi.framework.*; + /** * The activator manage the the bundles between OSGi framework and the * Network address manager diff --git a/src/net/java/sip/communicator/impl/netaddr/NetworkAddressManagerServiceImpl.java b/src/net/java/sip/communicator/impl/netaddr/NetworkAddressManagerServiceImpl.java index 83d685341..92f2ead72 100644 --- a/src/net/java/sip/communicator/impl/netaddr/NetworkAddressManagerServiceImpl.java +++ b/src/net/java/sip/communicator/impl/netaddr/NetworkAddressManagerServiceImpl.java @@ -6,17 +6,17 @@ */ package net.java.sip.communicator.impl.netaddr; -import java.lang.reflect.*; import java.beans.*; import java.io.*; +import java.lang.reflect.*; import java.net.*; import java.text.*; import java.util.*; -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.service.netaddr.*; import net.java.sip.communicator.service.netaddr.event.*; import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; import net.java.sip.communicator.util.NetworkUtils; import net.java.sip.communicator.util.dns.*; @@ -25,6 +25,8 @@ import org.ice4j.ice.harvest.*; import org.ice4j.security.*; import org.ice4j.stack.*; +import org.jitsi.service.configuration.*; +import org.jitsi.util.*; /** * This implementation of the Network Address Manager allows you to diff --git a/src/net/java/sip/communicator/impl/netaddr/netaddr.manifest.mf b/src/net/java/sip/communicator/impl/netaddr/netaddr.manifest.mf index 597d60607..0cc59bfb9 100644 --- a/src/net/java/sip/communicator/impl/netaddr/netaddr.manifest.mf +++ b/src/net/java/sip/communicator/impl/netaddr/netaddr.manifest.mf @@ -4,8 +4,9 @@ Bundle-Description: A bundle that provides local address selection and negotiati Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes -Import-Package: net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.packetlogging, +Import-Package: org.jitsi.service.configuration, + org.jitsi.service.packetlogging, + org.jitsi.util, net.java.sip.communicator.util, net.java.sip.communicator.util.dns, net.java.sip.communicator.service.sysactivity, diff --git a/src/net/java/sip/communicator/impl/notification/NotificationActivator.java b/src/net/java/sip/communicator/impl/notification/NotificationActivator.java index 99676c8f9..a7d94bd07 100644 --- a/src/net/java/sip/communicator/impl/notification/NotificationActivator.java +++ b/src/net/java/sip/communicator/impl/notification/NotificationActivator.java @@ -6,11 +6,11 @@ */ package net.java.sip.communicator.impl.notification; -import net.java.sip.communicator.service.audionotifier.*; import net.java.sip.communicator.service.notification.*; import net.java.sip.communicator.service.systray.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.audionotifier.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/notification/SoundNotificationHandlerImpl.java b/src/net/java/sip/communicator/impl/notification/SoundNotificationHandlerImpl.java index e5b0fba7c..025e82f15 100644 --- a/src/net/java/sip/communicator/impl/notification/SoundNotificationHandlerImpl.java +++ b/src/net/java/sip/communicator/impl/notification/SoundNotificationHandlerImpl.java @@ -8,10 +8,11 @@ import java.util.*; -import net.java.sip.communicator.service.audionotifier.*; import net.java.sip.communicator.service.notification.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.audionotifier.*; + /** * An implementation of the SoundNotificationHandler interface. * diff --git a/src/net/java/sip/communicator/impl/notification/notification.manifest.mf b/src/net/java/sip/communicator/impl/notification/notification.manifest.mf index c3b7bf9ed..0db21bae0 100644 --- a/src/net/java/sip/communicator/impl/notification/notification.manifest.mf +++ b/src/net/java/sip/communicator/impl/notification/notification.manifest.mf @@ -8,12 +8,12 @@ Import-Package: org.osgi.framework, javax.imageio, net.java.sip.communicator.util, net.java.sip.communicator.service.notification, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, - net.java.sip.communicator.service.audionotifier, + org.jitsi.service.audionotifier, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.protocol, - net.java.sip.communicator.service.neomedia, + org.jitsi.service.neomedia, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.service.systray diff --git a/src/net/java/sip/communicator/impl/osdependent/Desktop.java b/src/net/java/sip/communicator/impl/osdependent/Desktop.java index b8b39e0bb..d73f2d75f 100644 --- a/src/net/java/sip/communicator/impl/osdependent/Desktop.java +++ b/src/net/java/sip/communicator/impl/osdependent/Desktop.java @@ -11,9 +11,10 @@ import java.lang.reflect.*; import java.net.*; -import org.jdesktop.jdic.desktop.*; +import net.java.sip.communicator.util.Logger; -import net.java.sip.communicator.util.*; +import org.jdesktop.jdic.desktop.*; +import org.jitsi.util.*; /** * The Desktop class handles desktop operations through the default diff --git a/src/net/java/sip/communicator/impl/osdependent/OsDependentActivator.java b/src/net/java/sip/communicator/impl/osdependent/OsDependentActivator.java index d05e21f2d..83c6ba82d 100644 --- a/src/net/java/sip/communicator/impl/osdependent/OsDependentActivator.java +++ b/src/net/java/sip/communicator/impl/osdependent/OsDependentActivator.java @@ -8,14 +8,16 @@ import net.java.sip.communicator.impl.osdependent.jdic.*; import net.java.sip.communicator.impl.osdependent.macosx.*; -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.service.desktop.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.service.shutdown.*; import net.java.sip.communicator.service.systray.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; +import org.jitsi.service.configuration.*; +import org.jitsi.service.resources.*; +import org.jitsi.util.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/osdependent/Resources.java b/src/net/java/sip/communicator/impl/osdependent/Resources.java index f4f5da761..0279750be 100644 --- a/src/net/java/sip/communicator/impl/osdependent/Resources.java +++ b/src/net/java/sip/communicator/impl/osdependent/Resources.java @@ -12,6 +12,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Messages class manages the access to the internationalization * properties files. diff --git a/src/net/java/sip/communicator/impl/osdependent/TrayIcon.java b/src/net/java/sip/communicator/impl/osdependent/TrayIcon.java index 7556e00fb..c167b2a46 100644 --- a/src/net/java/sip/communicator/impl/osdependent/TrayIcon.java +++ b/src/net/java/sip/communicator/impl/osdependent/TrayIcon.java @@ -13,8 +13,9 @@ import javax.swing.*; import javax.swing.event.*; -import net.java.sip.communicator.impl.osdependent.SystemTray.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.impl.osdependent.SystemTray.SystemTrayPeer; + +import org.jitsi.util.*; /** * @author Lubomir Marinov diff --git a/src/net/java/sip/communicator/impl/osdependent/jdic/ProviderUnRegistration.java b/src/net/java/sip/communicator/impl/osdependent/jdic/ProviderUnRegistration.java index c1c4cfb23..658303f05 100644 --- a/src/net/java/sip/communicator/impl/osdependent/jdic/ProviderUnRegistration.java +++ b/src/net/java/sip/communicator/impl/osdependent/jdic/ProviderUnRegistration.java @@ -79,4 +79,4 @@ else if (errorCode == OperationFailedException } } } - } \ No newline at end of file + } diff --git a/src/net/java/sip/communicator/impl/osdependent/jdic/SystrayServiceJdicImpl.java b/src/net/java/sip/communicator/impl/osdependent/jdic/SystrayServiceJdicImpl.java index 81b844b55..3fa31a438 100644 --- a/src/net/java/sip/communicator/impl/osdependent/jdic/SystrayServiceJdicImpl.java +++ b/src/net/java/sip/communicator/impl/osdependent/jdic/SystrayServiceJdicImpl.java @@ -6,28 +6,30 @@ */ package net.java.sip.communicator.impl.osdependent.jdic; -import com.apple.eawt.*; - -import java.awt.GraphicsEnvironment; -import java.awt.Image; -import java.awt.Toolkit; +import java.awt.*; import java.awt.event.*; import java.net.*; import java.util.*; +import java.util.List; import javax.swing.*; import javax.swing.event.*; import net.java.sip.communicator.impl.osdependent.*; -import net.java.sip.communicator.service.configuration.*; +import net.java.sip.communicator.impl.osdependent.SystemTray; +import net.java.sip.communicator.impl.osdependent.TrayIcon; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.systray.*; import net.java.sip.communicator.service.systray.event.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; +import org.jitsi.service.configuration.*; +import org.jitsi.util.*; import org.osgi.framework.*; +import com.apple.eawt.*; + /** * The Systray provides a Icon and the associated TrayMenu * in the system tray using the Jdic library. diff --git a/src/net/java/sip/communicator/impl/osdependent/jdic/TrayMenuFactory.java b/src/net/java/sip/communicator/impl/osdependent/jdic/TrayMenuFactory.java index a6f8c0ca0..e57e7f235 100644 --- a/src/net/java/sip/communicator/impl/osdependent/jdic/TrayMenuFactory.java +++ b/src/net/java/sip/communicator/impl/osdependent/jdic/TrayMenuFactory.java @@ -14,7 +14,8 @@ import net.java.sip.communicator.impl.osdependent.*; import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.util.*; + +import org.jitsi.util.*; /** * The TrayMenu is the menu that appears when the user right-click @@ -301,4 +302,4 @@ public static boolean isVisible(Object trayMenu) return ((JPopupMenu) trayMenu).isVisible(); return false; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/osdependent/osdependent.manifest.mf b/src/net/java/sip/communicator/impl/osdependent/osdependent.manifest.mf index 0b3a30f6b..6f0ed5fd5 100644 --- a/src/net/java/sip/communicator/impl/osdependent/osdependent.manifest.mf +++ b/src/net/java/sip/communicator/impl/osdependent/osdependent.manifest.mf @@ -13,15 +13,16 @@ Import-Package: org.osgi.framework, com.apple.cocoa.application, com.apple.cocoa.foundation, com.apple.eawt, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.service.shutdown, net.java.sip.communicator.service.systray, net.java.sip.communicator.service.systray.event, + org.jitsi.util, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.accessibility, diff --git a/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingActivator.java b/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingActivator.java index 2fb54b877..3f65c57d6 100644 --- a/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingActivator.java +++ b/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingActivator.java @@ -6,11 +6,11 @@ */ package net.java.sip.communicator.impl.packetlogging; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.fileaccess.*; -import net.java.sip.communicator.service.packetlogging.*; import net.java.sip.communicator.util.*; -import net.java.sip.communicator.util.Logger; + +import org.jitsi.service.configuration.*; +import org.jitsi.service.fileaccess.*; +import org.jitsi.service.packetlogging.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingConfigurationImpl.java b/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingConfigurationImpl.java index fb9224d4b..809ee2e68 100644 --- a/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingConfigurationImpl.java +++ b/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingConfigurationImpl.java @@ -6,8 +6,9 @@ */ package net.java.sip.communicator.impl.packetlogging; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.packetlogging.*; +import org.jitsi.service.configuration.*; + +import org.jitsi.service.packetlogging.*; /** * Extends PacketLoggingConfiguration by storing and loading values from diff --git a/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingServiceImpl.java b/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingServiceImpl.java index 4f7f9dc88..08d80b6df 100644 --- a/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingServiceImpl.java +++ b/src/net/java/sip/communicator/impl/packetlogging/PacketLoggingServiceImpl.java @@ -6,12 +6,15 @@ */ package net.java.sip.communicator.impl.packetlogging; -import net.java.sip.communicator.service.packetlogging.*; -import net.java.sip.communicator.util.*; - import java.io.*; import java.util.*; +import net.java.sip.communicator.util.*; + +import org.jitsi.service.packetlogging.*; +import org.jitsi.service.packetlogging.PacketLoggingService.ProtocolName; +import org.jitsi.service.packetlogging.PacketLoggingService.TransportName; + /** * Packet Logging Service implementation dumping logs in * pcap(tcpdump/wireshark) format file. diff --git a/src/net/java/sip/communicator/impl/packetlogging/packetlogging.manifest.mf b/src/net/java/sip/communicator/impl/packetlogging/packetlogging.manifest.mf index c7800d377..9028ca77b 100644 --- a/src/net/java/sip/communicator/impl/packetlogging/packetlogging.manifest.mf +++ b/src/net/java/sip/communicator/impl/packetlogging/packetlogging.manifest.mf @@ -5,10 +5,11 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.fileaccess, + org.jitsi.service.configuration, + org.jitsi.service.fileaccess, + org.jitsi.service.packetlogging, net.java.sip.communicator.service.gui, - net.java.sip.communicator.service.neomedia, + org.jitsi.service.neomedia, net.java.sip.communicator.service.protocol, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, @@ -16,4 +17,3 @@ Import-Package: org.osgi.framework, javax.swing.border, javax.swing.event, javax.swing.text -Export-Package: net.java.sip.communicator.service.packetlogging diff --git a/src/net/java/sip/communicator/impl/protocol/dict/DictActivator.java b/src/net/java/sip/communicator/impl/protocol/dict/DictActivator.java index 5e201cb52..5e5b999af 100644 --- a/src/net/java/sip/communicator/impl/protocol/dict/DictActivator.java +++ b/src/net/java/sip/communicator/impl/protocol/dict/DictActivator.java @@ -6,12 +6,13 @@ */ package net.java.sip.communicator.impl.protocol.dict; -import org.osgi.framework.*; - -import net.java.sip.communicator.util.*; import java.util.*; + import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; +import net.java.sip.communicator.util.*; + +import org.jitsi.service.resources.*; +import org.osgi.framework.*; /** * Loads the Dict provider factory and registers its services in the OSGI diff --git a/src/net/java/sip/communicator/impl/protocol/dict/ProtocolProviderServiceDictImpl.java b/src/net/java/sip/communicator/impl/protocol/dict/ProtocolProviderServiceDictImpl.java index 0803c029e..469b996b3 100644 --- a/src/net/java/sip/communicator/impl/protocol/dict/ProtocolProviderServiceDictImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/dict/ProtocolProviderServiceDictImpl.java @@ -9,9 +9,9 @@ import net.java.dict4j.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.service.version.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.version.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/protocol/dict/dict.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/dict/dict.provider.manifest.mf index 4d0dc9740..eb4be9a45 100644 --- a/src/net/java/sip/communicator/impl/protocol/dict/dict.provider.manifest.mf +++ b/src/net/java/sip/communicator/impl/protocol/dict/dict.provider.manifest.mf @@ -5,11 +5,11 @@ Bundle-Vendor: jitsi.org Bundle-Version: 1.0.0 System-Bundle: yes Import-Package: org.osgi.framework, + org.jitsi.service.version, net.java.sip.communicator.service.contactlist, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.version Export-Package: net.java.dict4j diff --git a/src/net/java/sip/communicator/impl/protocol/gibberish/GibberishActivator.java b/src/net/java/sip/communicator/impl/protocol/gibberish/GibberishActivator.java index b9263303e..94a0b2358 100644 --- a/src/net/java/sip/communicator/impl/protocol/gibberish/GibberishActivator.java +++ b/src/net/java/sip/communicator/impl/protocol/gibberish/GibberishActivator.java @@ -6,12 +6,13 @@ */ package net.java.sip.communicator.impl.protocol.gibberish; -import org.osgi.framework.*; - -import net.java.sip.communicator.util.*; import java.util.*; + import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; +import net.java.sip.communicator.util.*; + +import org.jitsi.service.resources.*; +import org.osgi.framework.*; /** * Loads the Gibberish provider factory and registers its services in the OSGI diff --git a/src/net/java/sip/communicator/impl/protocol/gibberish/ProtocolIconGibberishImpl.java b/src/net/java/sip/communicator/impl/protocol/gibberish/ProtocolIconGibberishImpl.java index 356619260..7e479a694 100644 --- a/src/net/java/sip/communicator/impl/protocol/gibberish/ProtocolIconGibberishImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/gibberish/ProtocolIconGibberishImpl.java @@ -10,9 +10,9 @@ import java.util.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/protocol/gibberish/gibberish.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/gibberish/gibberish.provider.manifest.mf index f026f4ceb..df549896a 100644 --- a/src/net/java/sip/communicator/impl/protocol/gibberish/gibberish.provider.manifest.mf +++ b/src/net/java/sip/communicator/impl/protocol/gibberish/gibberish.provider.manifest.mf @@ -5,8 +5,8 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.resources, - net.java.sip.communicator.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, net.java.sip.communicator.util, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, diff --git a/src/net/java/sip/communicator/impl/protocol/icq/IcqActivator.java b/src/net/java/sip/communicator/impl/protocol/icq/IcqActivator.java index e9809e6d4..d201caf7c 100644 --- a/src/net/java/sip/communicator/impl/protocol/icq/IcqActivator.java +++ b/src/net/java/sip/communicator/impl/protocol/icq/IcqActivator.java @@ -2,11 +2,11 @@ import java.util.*; -import org.osgi.framework.*; - -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; + +import org.jitsi.service.resources.*; +import org.osgi.framework.*; /** * Loads the ICQ provider factory and registers it with service in the OSGI diff --git a/src/net/java/sip/communicator/impl/protocol/icq/OperationSetExtendedAuthorizationsIcqImpl.java b/src/net/java/sip/communicator/impl/protocol/icq/OperationSetExtendedAuthorizationsIcqImpl.java index b00d1eb09..d9e1ac2fe 100644 --- a/src/net/java/sip/communicator/impl/protocol/icq/OperationSetExtendedAuthorizationsIcqImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/icq/OperationSetExtendedAuthorizationsIcqImpl.java @@ -125,4 +125,4 @@ public SubscriptionStatus getSubscriptionStatus(Contact contact) return SubscriptionStatus.Subscribed; } } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/icq/ProtocolIconAimImpl.java b/src/net/java/sip/communicator/impl/protocol/icq/ProtocolIconAimImpl.java index 461ddd850..61f1bbfa2 100644 --- a/src/net/java/sip/communicator/impl/protocol/icq/ProtocolIconAimImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/icq/ProtocolIconAimImpl.java @@ -10,8 +10,9 @@ import java.util.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; + +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/protocol/icq/ProtocolIconIcqImpl.java b/src/net/java/sip/communicator/impl/protocol/icq/ProtocolIconIcqImpl.java index 40687f45e..42c09af6c 100644 --- a/src/net/java/sip/communicator/impl/protocol/icq/ProtocolIconIcqImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/icq/ProtocolIconIcqImpl.java @@ -10,8 +10,9 @@ import java.util.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; + +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/protocol/icq/VolatileBuddy.java b/src/net/java/sip/communicator/impl/protocol/icq/VolatileBuddy.java index 13a05f81d..903d16a5e 100644 --- a/src/net/java/sip/communicator/impl/protocol/icq/VolatileBuddy.java +++ b/src/net/java/sip/communicator/impl/protocol/icq/VolatileBuddy.java @@ -68,4 +68,4 @@ public void setAwaitingAuthorization(boolean value) { this.isAwaitingAuthorization = value; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/icq/icq.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/icq/icq.provider.manifest.mf index b5d364126..83c05c1a8 100644 --- a/src/net/java/sip/communicator/impl/protocol/icq/icq.provider.manifest.mf +++ b/src/net/java/sip/communicator/impl/protocol/icq/icq.provider.manifest.mf @@ -7,8 +7,8 @@ System-Bundle: yes Import-Package: org.osgi.framework, javax.net, sun.misc, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.dns, net.java.sip.communicator.service.protocol, diff --git a/src/net/java/sip/communicator/impl/protocol/irc/ChatRoomInvitationIrcImpl.java b/src/net/java/sip/communicator/impl/protocol/irc/ChatRoomInvitationIrcImpl.java index d01b2aa10..379aab1be 100644 --- a/src/net/java/sip/communicator/impl/protocol/irc/ChatRoomInvitationIrcImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/irc/ChatRoomInvitationIrcImpl.java @@ -96,4 +96,4 @@ public byte[] getChatRoomPassword() { return chatRoomPasword; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/irc/IrcActivator.java b/src/net/java/sip/communicator/impl/protocol/irc/IrcActivator.java index 2b8af5955..92c368f45 100644 --- a/src/net/java/sip/communicator/impl/protocol/irc/IrcActivator.java +++ b/src/net/java/sip/communicator/impl/protocol/irc/IrcActivator.java @@ -6,12 +6,14 @@ */ package net.java.sip.communicator.impl.protocol.irc; -import org.osgi.framework.*; - -import net.java.sip.communicator.util.*; import java.util.*; + import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; +import net.java.sip.communicator.util.*; + +import org.jitsi.service.resources.*; +import org.osgi.framework.*; /** * Loads the IRC provider factory and registers its services in the OSGI diff --git a/src/net/java/sip/communicator/impl/protocol/irc/irc.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/irc/irc.provider.manifest.mf index 197023235..42b4a1051 100644 --- a/src/net/java/sip/communicator/impl/protocol/irc/irc.provider.manifest.mf +++ b/src/net/java/sip/communicator/impl/protocol/irc/irc.provider.manifest.mf @@ -5,8 +5,8 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ActiveCallsRepositoryGTalkImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ActiveCallsRepositoryGTalkImpl.java index 5c421b07b..9742e9729 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/ActiveCallsRepositoryGTalkImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/ActiveCallsRepositoryGTalkImpl.java @@ -120,4 +120,4 @@ protected void fireCallEvent(int eventID, Call sourceCall) { parentOperationSet.fireCallEvent(eventID, sourceCall); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/CallJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/CallJabberImpl.java index 44d43a22c..f10667961 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/CallJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/CallJabberImpl.java @@ -12,12 +12,12 @@ import net.java.sip.communicator.impl.protocol.jabber.extensions.cobri.*; import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*; import net.java.sip.communicator.impl.protocol.jabber.jinglesdp.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.neomedia.*; import org.jivesoftware.smack.*; import org.jivesoftware.smack.filter.*; import org.jivesoftware.smack.packet.*; diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerJabberImpl.java index fd99abfea..f94059ee0 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerJabberImpl.java @@ -6,23 +6,23 @@ */ package net.java.sip.communicator.impl.protocol.jabber; -import java.util.*; import java.lang.reflect.*; - -import org.jivesoftware.smack.*; -import org.jivesoftware.smack.filter.*; -import org.jivesoftware.smack.packet.*; -import org.jivesoftware.smackx.packet.*; +import java.util.*; import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*; -import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.ContentPacketExtension.*; +import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.ContentPacketExtension.SendersEnum; import net.java.sip.communicator.impl.protocol.jabber.jinglesdp.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.neomedia.*; +import org.jivesoftware.smack.*; +import org.jivesoftware.smack.filter.*; +import org.jivesoftware.smack.packet.*; +import org.jivesoftware.smackx.packet.*; + /** * Implements a Jabber CallPeer. * diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerGTalkImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerGTalkImpl.java index 3e9eb889e..f0ebc96a6 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerGTalkImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerGTalkImpl.java @@ -12,13 +12,14 @@ import net.java.sip.communicator.impl.protocol.jabber.extensions.gtalk.*; import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*; import net.java.sip.communicator.impl.protocol.jabber.jinglesdp.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.format.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.device.*; +import org.jitsi.service.neomedia.format.*; + /** * A Google Talk-specific extension of the generic media handler. * diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java index b7dfa37c1..78e59af6b 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java @@ -9,18 +9,18 @@ import java.lang.reflect.*; import java.util.*; -import org.jivesoftware.smack.util.StringUtils; -import org.jivesoftware.smackx.packet.*; - import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*; import net.java.sip.communicator.impl.protocol.jabber.jinglesdp.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.format.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.device.*; +import org.jitsi.service.neomedia.format.*; +import org.jivesoftware.smack.util.StringUtils; +import org.jivesoftware.smackx.packet.*; + /** * An XMPP specific extension of the generic media handler. * diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java b/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java index c6d4b8f21..c7c532f56 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java @@ -12,7 +12,6 @@ import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*; import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.CandidateType; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.netaddr.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.media.*; @@ -22,8 +21,8 @@ import org.ice4j.ice.*; import org.ice4j.ice.harvest.*; import org.ice4j.security.*; +import org.jitsi.service.neomedia.*; import org.jivesoftware.smack.packet.*; - import org.xmpp.jnodes.smack.*; /** diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/JabberActivator.java b/src/net/java/sip/communicator/impl/protocol/jabber/JabberActivator.java index 6bfd8afc2..ec53bafa7 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/JabberActivator.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/JabberActivator.java @@ -8,19 +8,20 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.service.credentialsstorage.*; +import net.java.sip.communicator.service.googlecontacts.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.hid.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.netaddr.*; -import net.java.sip.communicator.service.packetlogging.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; -import net.java.sip.communicator.service.googlecontacts.*; -import net.java.sip.communicator.service.version.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.packetlogging.*; +import org.jitsi.service.resources.*; +import org.jitsi.service.version.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesHarvester.java b/src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesHarvester.java index 85ff9deec..5147f5e88 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesHarvester.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/JingleNodesHarvester.java @@ -178,4 +178,4 @@ protected JingleNodesCandidate createJingleNodesCandidate( return cand; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetAutoAnswerJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetAutoAnswerJabberImpl.java index 12343d144..1f1bfbdbd 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetAutoAnswerJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetAutoAnswerJabberImpl.java @@ -6,12 +6,11 @@ */ package net.java.sip.communicator.impl.protocol.jabber; -import net.java.sip.communicator.service.neomedia.*; +import java.util.*; + import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.util.*; -import java.util.*; +import org.jitsi.service.neomedia.*; /** * An Operation Set defining option to unconditionally auto answer incoming diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java index c012e7a7f..70064f6c5 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java @@ -8,18 +8,18 @@ import java.util.*; -import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*; import net.java.sip.communicator.impl.protocol.jabber.extensions.gtalk.*; -import net.java.sip.communicator.service.neomedia.*; +import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.neomedia.*; import org.jivesoftware.smack.*; import org.jivesoftware.smack.filter.*; import org.jivesoftware.smack.packet.*; -import org.jivesoftware.smack.packet.IQ.*; +import org.jivesoftware.smack.packet.IQ.Type; import org.jivesoftware.smack.provider.*; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smackx.packet.*; diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetDTMFJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetDTMFJabberImpl.java index 3af0f89b1..020f6e070 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetDTMFJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetDTMFJabberImpl.java @@ -8,12 +8,15 @@ import java.util.*; -import net.java.sip.communicator.impl.neomedia.codec.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.format.*; import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.OperationFailedException; import net.java.sip.communicator.util.*; +import org.jitsi.impl.neomedia.codec.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.format.*; +import org.jitsi.service.protocol.*; + /** * Class responsible for sending a DTMF Tone using using rfc4733 or Inband. * diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetDesktopSharingServerJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetDesktopSharingServerJabberImpl.java index c22fef81b..6f9c406ea 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetDesktopSharingServerJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetDesktopSharingServerJabberImpl.java @@ -6,25 +6,24 @@ */ package net.java.sip.communicator.impl.protocol.jabber; -import java.util.*; -import java.text.*; - import java.awt.event.*; - -import org.jivesoftware.smack.*; -import org.jivesoftware.smack.filter.*; -import org.jivesoftware.smack.packet.*; -import org.jivesoftware.smackx.packet.*; +import java.text.*; +import java.util.*; import net.java.sip.communicator.impl.protocol.jabber.extensions.inputevt.*; import net.java.sip.communicator.service.hid.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.format.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.device.*; +import org.jitsi.service.neomedia.format.*; +import org.jivesoftware.smack.*; +import org.jivesoftware.smack.filter.*; +import org.jivesoftware.smack.packet.*; +import org.jivesoftware.smackx.packet.*; + /** * Implements all desktop sharing server-side related functions for Jabber * protocol. diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetDesktopStreamingJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetDesktopStreamingJabberImpl.java index 6a3323048..8aedbf2f7 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetDesktopStreamingJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetDesktopStreamingJabberImpl.java @@ -9,12 +9,13 @@ import java.awt.*; import java.text.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.format.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.media.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.device.*; +import org.jitsi.service.neomedia.format.*; + /** * Implements all desktop streaming related functions for XMPP. * diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetTelephonyConferencingJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetTelephonyConferencingJabberImpl.java index 6c1238860..657e71163 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetTelephonyConferencingJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetTelephonyConferencingJabberImpl.java @@ -8,19 +8,19 @@ import java.util.*; -import org.jivesoftware.smack.*; -import org.jivesoftware.smack.filter.*; -import org.jivesoftware.smack.packet.*; -import org.jivesoftware.smack.packet.IQ.*; -import org.jivesoftware.smackx.packet.*; - import net.java.sip.communicator.impl.protocol.jabber.extensions.coin.*; import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.media.*; -import net.java.sip.communicator.util.Logger; +import net.java.sip.communicator.util.*; + +import org.jitsi.service.neomedia.*; +import org.jivesoftware.smack.*; +import org.jivesoftware.smack.filter.*; +import org.jivesoftware.smack.packet.*; +import org.jivesoftware.smack.packet.IQ.Type; +import org.jivesoftware.smackx.packet.*; /** * Implements OperationSetTelephonyConferencing for Jabber. diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetVideoTelephonyJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetVideoTelephonyJabberImpl.java index fa2d91288..76f606042 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetVideoTelephonyJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetVideoTelephonyJabberImpl.java @@ -6,11 +6,12 @@ */ package net.java.sip.communicator.impl.protocol.jabber; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.neomedia.*; + /** * Implements OperationSetVideoTelephony in order to give access to * video-specific functionality in the Jabber protocol implementation. diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolIconJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolIconJabberImpl.java index 956cacb98..be35ccfe4 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolIconJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolIconJabberImpl.java @@ -11,9 +11,9 @@ import java.util.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java index 6352de04b..a6e3b7286 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java @@ -32,7 +32,7 @@ import net.java.sip.communicator.impl.protocol.jabber.extensions.coin.*; import net.java.sip.communicator.impl.protocol.jabber.sasl.*; import net.java.sip.communicator.service.certificate.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import org.jivesoftware.smack.*; import org.jivesoftware.smack.packet.*; diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/QualityControlWrapper.java b/src/net/java/sip/communicator/impl/protocol/jabber/QualityControlWrapper.java index ce7386782..77e33bd1f 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/QualityControlWrapper.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/QualityControlWrapper.java @@ -6,11 +6,12 @@ */ package net.java.sip.communicator.impl.protocol.jabber; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.protocol.*; + /** * A wrapper of media quality control. * @@ -57,12 +58,18 @@ public void setPreferredRemoteSendMaxPreset(QualityPreset preset) // re-invites the peer with the new settings peer.sendModifyVideoResolutionContent(); } - catch (Throwable ex) + catch (Throwable cause) { - ProtocolProviderServiceJabberImpl.throwOperationFailedException( - "Failed to re-invite for video quality change.", - OperationFailedException.INTERNAL_ERROR, ex, logger); + String message + = "Failed to re-invite for video quality change."; + + logger.error(message, cause); + + throw new OperationFailedException( + message, + OperationFailedException.INTERNAL_ERROR, + cause); } } } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/RawUdpTransportManager.java b/src/net/java/sip/communicator/impl/protocol/jabber/RawUdpTransportManager.java index 2443d608d..0e52d38a0 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/RawUdpTransportManager.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/RawUdpTransportManager.java @@ -12,9 +12,10 @@ import net.java.sip.communicator.impl.protocol.jabber.extensions.cobri.*; import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*; import net.java.sip.communicator.impl.protocol.jabber.jinglesdp.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; +import org.jitsi.service.neomedia.*; + /** * A {@link TransportManagerJabberImpl} implementation that would only gather a * single candidate pair (i.e. RTP and RTCP). diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/TransportManagerGTalkImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/TransportManagerGTalkImpl.java index 457e3e444..c93f31bea 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/TransportManagerGTalkImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/TransportManagerGTalkImpl.java @@ -11,27 +11,27 @@ import java.net.*; import java.util.*; -import org.ice4j.*; -import org.ice4j.ice.*; -import org.ice4j.ice.harvest.*; -import org.jivesoftware.smack.*; -import org.jivesoftware.smack.filter.*; -import org.jivesoftware.smack.packet.*; -import org.jivesoftware.smack.packet.IQ.*; -import org.jivesoftware.smack.util.StringUtils; -import org.xmpp.jnodes.smack.*; - import net.java.sip.communicator.impl.protocol.jabber.extensions.*; import net.java.sip.communicator.impl.protocol.jabber.extensions.gtalk.*; import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*; import net.java.sip.communicator.impl.protocol.jabber.extensions.jingleinfo.*; import net.java.sip.communicator.service.httputil.*; import net.java.sip.communicator.service.httputil.HttpUtils.HTTPResponseResult; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; +import org.ice4j.*; +import org.ice4j.ice.*; +import org.ice4j.ice.harvest.*; +import org.jitsi.service.neomedia.*; +import org.jivesoftware.smack.*; +import org.jivesoftware.smack.filter.*; +import org.jivesoftware.smack.packet.IQ.Type; +import org.jivesoftware.smack.packet.*; +import org.jivesoftware.smack.util.StringUtils; +import org.xmpp.jnodes.smack.*; + /** * TransportManagers gather local candidates for incoming and outgoing * calls. Their work starts by calling a start method which, using the remote diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/TransportManagerJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/TransportManagerJabberImpl.java index 31975c4c5..687087d83 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/TransportManagerJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/TransportManagerJabberImpl.java @@ -10,10 +10,11 @@ import java.util.*; import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.media.*; +import org.jitsi.service.neomedia.*; + /** * TransportManagers gather local candidates for incoming and outgoing * calls. Their work starts by calling a start method which, using the remote diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/WhiteboardInvitationJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/WhiteboardInvitationJabberImpl.java index 3d280c86b..cac401140 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/WhiteboardInvitationJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/WhiteboardInvitationJabberImpl.java @@ -108,4 +108,4 @@ public WhiteboardObject getWhiteboardInitialObject() { return firstWhiteboardObject; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/debugger/SmackPacketDebugger.java b/src/net/java/sip/communicator/impl/protocol/jabber/debugger/SmackPacketDebugger.java index 77aa3eb5c..1117c8ab9 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/debugger/SmackPacketDebugger.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/debugger/SmackPacketDebugger.java @@ -7,7 +7,8 @@ package net.java.sip.communicator.impl.protocol.jabber.debugger; import net.java.sip.communicator.impl.protocol.jabber.*; -import net.java.sip.communicator.service.packetlogging.*; + +import org.jitsi.service.packetlogging.*; import org.jivesoftware.smack.*; import org.jivesoftware.smack.packet.*; diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/EntityCapsManager.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/EntityCapsManager.java index aab2c61cd..1142b3830 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/EntityCapsManager.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/EntityCapsManager.java @@ -13,7 +13,7 @@ import java.util.concurrent.*; import net.java.sip.communicator.impl.protocol.jabber.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.Logger; // disambiguation diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/cobri/CobriStreamConnector.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/cobri/CobriStreamConnector.java index 288da0e3f..a682ea662 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/cobri/CobriStreamConnector.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/cobri/CobriStreamConnector.java @@ -6,7 +6,7 @@ */ package net.java.sip.communicator.impl.protocol.jabber.extensions.cobri; -import net.java.sip.communicator.service.neomedia.*; +import org.jitsi.service.neomedia.*; /** * Implements a StreamConnector which allows sharing a specific diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/coin/StateProvider.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/coin/StateProvider.java index 4ff4b2dc1..81ad6642b 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/coin/StateProvider.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/coin/StateProvider.java @@ -75,4 +75,4 @@ else if (eventType == XmlPullParser.END_TAG) return ext; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/gtalk/SrcIdPacketExtension.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/gtalk/SrcIdPacketExtension.java index 85fa65987..a5e2af36c 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/gtalk/SrcIdPacketExtension.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/gtalk/SrcIdPacketExtension.java @@ -45,4 +45,4 @@ public void setSrcId(String srcId) { this.setText(srcId); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/gtalk/UsagePacketExtension.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/gtalk/UsagePacketExtension.java index 4e05d06ec..1664a3b0d 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/gtalk/UsagePacketExtension.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/gtalk/UsagePacketExtension.java @@ -33,4 +33,4 @@ public UsagePacketExtension() { super(NAMESPACE, ELEMENT_NAME); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/CoinPacketExtension.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/CoinPacketExtension.java index 17aa4dd2f..73cdcb163 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/CoinPacketExtension.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/jingle/CoinPacketExtension.java @@ -51,4 +51,4 @@ public CoinPacketExtension(boolean isFocus) super(NAMESPACE, ELEMENT_NAME); setAttribute(ISFOCUS_ATTR_NAME, isFocus); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/version/VersionManager.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/version/VersionManager.java index fa2e79ba2..8bf8168f8 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/version/VersionManager.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/version/VersionManager.java @@ -8,8 +8,9 @@ import net.java.sip.communicator.impl.protocol.jabber.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.version.Version; import net.java.sip.communicator.service.protocol.event.*; + +import org.jitsi.service.version.*; import org.jivesoftware.smack.*; import org.jivesoftware.smack.filter.*; import org.jivesoftware.smack.packet.*; diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectImageJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectImageJabberImpl.java index d9136f781..ad48129fd 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectImageJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectImageJabberImpl.java @@ -219,4 +219,4 @@ public String toXML () return s; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectJabberImpl.java index 67c5d9777..1e32aa6e0 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectJabberImpl.java @@ -195,4 +195,4 @@ public void setThickness (int thickness) * method */ public abstract String toXML (); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectJabberProvider.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectJabberProvider.java index 9543406b5..1a58bf9b7 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectJabberProvider.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectJabberProvider.java @@ -86,4 +86,4 @@ else if (eventType == XmlPullParser.END_TAG return extension; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectLineJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectLineJabberImpl.java index 42a45095a..e9baf038f 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectLineJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectLineJabberImpl.java @@ -168,4 +168,4 @@ public String toXML () return s; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectPacketExtension.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectPacketExtension.java index 4da11d516..46c37a0df 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectPacketExtension.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectPacketExtension.java @@ -284,4 +284,4 @@ public void setWhiteboardObjectID (String objectID) { this.whiteboardObjectID = objectID; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectRectJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectRectJabberImpl.java index 57a049b47..65e3b387c 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectRectJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectRectJabberImpl.java @@ -277,4 +277,4 @@ public String toXML () return s; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectTextJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectTextJabberImpl.java index 6f7cbf13c..ea9e730fe 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectTextJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/whiteboard/WhiteboardObjectTextJabberImpl.java @@ -220,4 +220,4 @@ public String toXML () return s; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/jabber.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/jabber/jabber.provider.manifest.mf index 8872df07b..f4bee41fd 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/jabber.provider.manifest.mf +++ b/src/net/java/sip/communicator/impl/protocol/jabber/jabber.provider.manifest.mf @@ -31,22 +31,23 @@ Import-Package: org.osgi.framework, org.jivesoftware.smackx.jingle.provider, org.jivesoftware.smackx.filetransfer, org.jivesoftware.smackx.provider, + org.jitsi.service.version, org.w3c.dom, net.java.sip.communicator.service.customavatar, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.dns, - net.java.sip.communicator.service.packetlogging, + org.jitsi.service.packetlogging, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.jabberconstants, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.protocol.whiteboardobjects, net.java.sip.communicator.service.protocol.media, - net.java.sip.communicator.service.neomedia, - net.java.sip.communicator.service.neomedia.device, - net.java.sip.communicator.service.neomedia.event, - net.java.sip.communicator.service.neomedia.format, + org.jitsi.service.neomedia, + org.jitsi.service.neomedia.device, + org.jitsi.service.neomedia.event, + org.jitsi.service.neomedia.format, net.java.sip.communicator.service.credentialsstorage, net.java.sip.communicator.service.hid, net.java.sip.communicator.service.netaddr, @@ -54,7 +55,6 @@ Import-Package: org.osgi.framework, net.java.sip.communicator.service.certificate, net.java.sip.communicator.service.httputil, net.java.sip.communicator.service.gui, - net.java.sip.communicator.service.version, org.xmlpull.v1, org.xmlpull.mxp1, javax.xml.parsers, diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/jinglesdp/JingleUtils.java b/src/net/java/sip/communicator/impl/protocol/jabber/jinglesdp/JingleUtils.java index 6edf49551..097dd4e6c 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/jinglesdp/JingleUtils.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/jinglesdp/JingleUtils.java @@ -11,12 +11,14 @@ import net.java.sip.communicator.impl.protocol.jabber.*; import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.format.*; +import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.ContentPacketExtension.CreatorEnum; +import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.ContentPacketExtension.SendersEnum; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; -import net.java.sip.communicator.util.NetworkUtils; //disambiguates with ice4j's network utils. -import static net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.ContentPacketExtension.*; + +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.format.*; +//disambiguates with ice4j's network utils. /** * The class contains a number of utility methods that are meant to facilitate diff --git a/src/net/java/sip/communicator/impl/protocol/msn/MsnActivator.java b/src/net/java/sip/communicator/impl/protocol/msn/MsnActivator.java index 31e22d941..50b1fd219 100644 --- a/src/net/java/sip/communicator/impl/protocol/msn/MsnActivator.java +++ b/src/net/java/sip/communicator/impl/protocol/msn/MsnActivator.java @@ -8,12 +8,13 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.fileaccess.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; - import net.java.sip.communicator.util.*; + +import org.jitsi.service.configuration.*; +import org.jitsi.service.fileaccess.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/protocol/msn/msn.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/msn/msn.provider.manifest.mf index bc2168875..e7c6189d1 100644 --- a/src/net/java/sip/communicator/impl/protocol/msn/msn.provider.manifest.mf +++ b/src/net/java/sip/communicator/impl/protocol/msn/msn.provider.manifest.mf @@ -29,9 +29,9 @@ Import-Package: org.apache.commons.logging, javax.xml.datatype, sun.security.action, javax.imageio, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.fileaccess, - net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, + org.jitsi.service.fileaccess, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.dns, net.java.sip.communicator.service.protocol, diff --git a/src/net/java/sip/communicator/impl/protocol/rss/ProtocolIconRssImpl.java b/src/net/java/sip/communicator/impl/protocol/rss/ProtocolIconRssImpl.java index e6152a77f..47839623c 100644 --- a/src/net/java/sip/communicator/impl/protocol/rss/ProtocolIconRssImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/rss/ProtocolIconRssImpl.java @@ -10,9 +10,9 @@ import java.util.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/protocol/rss/RssActivator.java b/src/net/java/sip/communicator/impl/protocol/rss/RssActivator.java index b275b2dd9..f25e531ee 100644 --- a/src/net/java/sip/communicator/impl/protocol/rss/RssActivator.java +++ b/src/net/java/sip/communicator/impl/protocol/rss/RssActivator.java @@ -6,8 +6,6 @@ */ package net.java.sip.communicator.impl.protocol.rss; -import org.osgi.framework.*; - import java.util.*; import net.java.sip.communicator.service.gui.*; @@ -15,6 +13,9 @@ import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; +import org.osgi.framework.*; + /** * Loads the Rss provider factory and registers its services in the OSGI * bundle context. diff --git a/src/net/java/sip/communicator/impl/protocol/rss/rss.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/rss/rss.provider.manifest.mf index 6a018f051..508ec35ab 100644 --- a/src/net/java/sip/communicator/impl/protocol/rss/rss.provider.manifest.mf +++ b/src/net/java/sip/communicator/impl/protocol/rss/rss.provider.manifest.mf @@ -13,9 +13,9 @@ Import-Package: org.osgi.framework, javax.xml.parsers, javax.imageio, javax.net.ssl, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, diff --git a/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandlerSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandlerSipImpl.java index 0aab3541a..8de5f0702 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandlerSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandlerSipImpl.java @@ -12,15 +12,16 @@ import javax.sdp.*; import net.java.sip.communicator.impl.protocol.sip.sdp.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.format.*; import net.java.sip.communicator.service.netaddr.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.device.*; +import org.jitsi.service.neomedia.format.*; + /** * The media handler class handles all media management for a single * CallPeer. This includes initializing and configuring streams, diff --git a/src/net/java/sip/communicator/impl/protocol/sip/CallPeerSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/CallPeerSipImpl.java index eaccbcd05..f43d06b66 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/CallPeerSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/CallPeerSipImpl.java @@ -6,6 +6,9 @@ */ package net.java.sip.communicator.impl.protocol.sip; +import static net.java.sip.communicator.service.protocol.OperationSetBasicTelephony.HANGUP_REASON_ENCRYPTION_REQUIRED; +import static net.java.sip.communicator.service.protocol.OperationSetBasicTelephony.HANGUP_REASON_NORMAL_CLEARING; +import static net.java.sip.communicator.service.protocol.OperationSetBasicTelephony.HANGUP_REASON_TIMEOUT; import gov.nist.javax.sip.header.*; import java.net.*; @@ -19,14 +22,13 @@ import javax.sip.message.*; import net.java.sip.communicator.impl.protocol.sip.sdp.*; -import net.java.sip.communicator.service.neomedia.control.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.Contact; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; -import static net.java.sip.communicator.service.protocol.OperationSetBasicTelephony.*; +import org.jitsi.service.neomedia.control.*; /** * Our SIP implementation of the default CallPeer; diff --git a/src/net/java/sip/communicator/impl/protocol/sip/CallSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/CallSipImpl.java index c02ddd6ce..8bd051c70 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/CallSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/CallSipImpl.java @@ -14,12 +14,13 @@ import javax.sip.message.*; import net.java.sip.communicator.impl.protocol.sip.sdp.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.neomedia.*; + /** * A SIP implementation of the Call abstract class encapsulating SIP dialogs. * diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetAutoAnswerSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetAutoAnswerSipImpl.java index 888331705..1cbf3f176 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetAutoAnswerSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetAutoAnswerSipImpl.java @@ -7,18 +7,22 @@ package net.java.sip.communicator.impl.protocol.sip; import gov.nist.javax.sip.header.*; -import net.java.sip.communicator.impl.protocol.sip.sdp.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.util.*; +import java.util.*; + +import javax.sdp.*; import javax.sip.*; import javax.sip.address.*; -import javax.sip.header.ContactHeader; // Disambiguation. +import javax.sip.header.*; import javax.sip.message.*; -import javax.sdp.*; -import java.util.*; + +import net.java.sip.communicator.impl.protocol.sip.sdp.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.*; + +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.MediaType; +// Disambiguation. /** * An Operation Set defining options to auto answer/forward incoming calls. diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDTMFSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDTMFSipImpl.java index a2002f5e4..7142577d3 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDTMFSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDTMFSipImpl.java @@ -8,13 +8,16 @@ import java.util.*; -import net.java.sip.communicator.impl.neomedia.codec.*; import net.java.sip.communicator.impl.protocol.sip.dtmf.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.format.*; import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.OperationFailedException; import net.java.sip.communicator.util.*; +import org.jitsi.impl.neomedia.codec.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.format.*; +import org.jitsi.service.protocol.*; + /** * Class responsible for sending a DTMF Tone using SIP INFO or using rfc4733. * diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDesktopSharingServerSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDesktopSharingServerSipImpl.java index 178ec1b16..63eb35321 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDesktopSharingServerSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDesktopSharingServerSipImpl.java @@ -6,30 +6,30 @@ */ package net.java.sip.communicator.impl.protocol.sip; -import java.io.*; -import java.util.List; // disambiguation -import java.text.*; import java.awt.*; import java.awt.event.*; +import java.io.*; +import java.text.*; +import java.util.List; -import javax.sip.Dialog; // disambiguation import javax.sip.*; +import javax.sip.Dialog; import javax.sip.address.*; import javax.sip.header.*; import javax.sip.message.*; import javax.xml.parsers.*; -import org.w3c.dom.*; -import org.xml.sax.*; - -import net.java.sip.communicator.service.neomedia.MediaType; // disambiguation -import net.java.sip.communicator.service.neomedia.format.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.hid.*; +import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.neomedia.MediaType; +import org.jitsi.service.neomedia.device.*; +import org.jitsi.service.neomedia.format.*; +import org.w3c.dom.*; +import org.xml.sax.*; + /** * Implements all desktop sharing server-side related functions for SIP * protocol. diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDesktopStreamingSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDesktopStreamingSipImpl.java index 6bb873a37..a906535dc 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDesktopStreamingSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetDesktopStreamingSipImpl.java @@ -11,11 +11,12 @@ import javax.sip.address.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.format.*; import net.java.sip.communicator.service.protocol.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.device.*; +import org.jitsi.service.neomedia.format.*; + /** * Implements all desktop streaming related functions for SIP. * diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetTelephonyConferencingSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetTelephonyConferencingSipImpl.java index 757513552..e4e573669 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetTelephonyConferencingSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetTelephonyConferencingSipImpl.java @@ -17,18 +17,18 @@ import javax.sip.address.*; import javax.sip.header.*; import javax.sip.message.*; -import javax.sip.message.Message; // disambiguation +import javax.sip.message.Message; import javax.xml.parsers.*; import net.java.sip.communicator.impl.protocol.sip.sdp.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.MediaType; // disambiguation import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.xml.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.MediaType; import org.w3c.dom.*; import org.xml.sax.*; diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetVideoTelephonySipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetVideoTelephonySipImpl.java index aa2a390f6..3ebfd52f8 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetVideoTelephonySipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetVideoTelephonySipImpl.java @@ -10,15 +10,16 @@ import java.text.*; import javax.sip.*; -import javax.sip.address.Address; +import javax.sip.address.*; import javax.sip.header.*; import javax.sip.message.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.neomedia.*; + /** * Implements OperationSetVideoTelephony in order to give access to * video-specific functionality in the SIP protocol implementation such as diff --git a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolIconSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolIconSipImpl.java index 9bd47822a..c361d7f30 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolIconSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolIconSipImpl.java @@ -10,9 +10,10 @@ import java.util.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; + /** * Represents the Sip protocol icon. Implements the ProtocolIcon * interface in order to provide an sip icon image in two different sizes. diff --git a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java index f4c91dcd9..9fb5b2e70 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java @@ -9,24 +9,26 @@ import gov.nist.javax.sip.address.*; import gov.nist.javax.sip.header.*; import gov.nist.javax.sip.message.*; + +import java.net.*; +import java.text.*; +import java.util.*; + +import javax.sip.*; +import javax.sip.address.*; +import javax.sip.header.*; +import javax.sip.message.*; + import net.java.sip.communicator.impl.protocol.sip.net.*; import net.java.sip.communicator.impl.protocol.sip.security.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.service.version.Version; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.dns.*; +import org.jitsi.service.version.Version; import org.osgi.framework.*; -import javax.sip.*; -import javax.sip.address.*; -import javax.sip.header.*; -import javax.sip.message.*; -import java.net.*; -import java.text.*; -import java.util.*; - /** * A SIP implementation of the Protocol Provider Service. * diff --git a/src/net/java/sip/communicator/impl/protocol/sip/QualityControlWrapper.java b/src/net/java/sip/communicator/impl/protocol/sip/QualityControlWrapper.java index 7b3ffcbd0..851636eff 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/QualityControlWrapper.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/QualityControlWrapper.java @@ -6,11 +6,12 @@ */ package net.java.sip.communicator.impl.protocol.sip; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.protocol.*; + /** * A wrapper of media quality control. * @author Damian Minkov @@ -55,11 +56,17 @@ public void setPreferredRemoteSendMaxPreset(QualityPreset preset) // re-invites the peer with the new settings peer.sendReInvite(); } - catch (Throwable ex) + catch (Throwable cause) { - ProtocolProviderServiceSipImpl.throwOperationFailedException( - "Failed to re-invite for video quality change.", - OperationFailedException.INTERNAL_ERROR, ex, logger); + String message + = "Failed to re-invite for video quality change."; + + logger.error(message, cause); + + throw new OperationFailedException( + message, + OperationFailedException.INTERNAL_ERROR, + cause); } } } diff --git a/src/net/java/sip/communicator/impl/protocol/sip/ServerStoredContactListXivoImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/ServerStoredContactListXivoImpl.java index 374871876..751e852b1 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/ServerStoredContactListXivoImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/ServerStoredContactListXivoImpl.java @@ -7,18 +7,23 @@ package net.java.sip.communicator.impl.protocol.sip; import gov.nist.javax.sip.address.*; -import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.util.*; -import org.json.*; -import javax.sip.address.*; import java.io.*; import java.net.*; import java.net.URI; import java.util.*; +import javax.sip.address.*; + +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.event.*; +import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; + +import org.jitsi.util.*; +import org.json.*; + /** * Xivo server stored contact list. Currently no modifications are possible. * Just connecting and downloading server contact list. diff --git a/src/net/java/sip/communicator/impl/protocol/sip/SipActivator.java b/src/net/java/sip/communicator/impl/protocol/sip/SipActivator.java index 2c7ff8c08..ad72d2220 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/SipActivator.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/SipActivator.java @@ -8,21 +8,21 @@ import java.util.*; -import net.java.sip.communicator.service.packetlogging.*; -import org.osgi.framework.*; - import net.java.sip.communicator.service.certificate.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.fileaccess.*; import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.hid.*; import net.java.sip.communicator.service.netaddr.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; -import net.java.sip.communicator.service.version.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.fileaccess.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.packetlogging.*; +import org.jitsi.service.resources.*; +import org.jitsi.service.version.*; +import org.osgi.framework.*; + /** * Activates the SIP package * @author Emil Ivov diff --git a/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java b/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java index 02c1950f7..4329c85da 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java @@ -9,14 +9,17 @@ import gov.nist.core.*; import gov.nist.javax.sip.*; import gov.nist.javax.sip.message.*; -import javax.sip.*; + import java.io.*; import java.net.*; import java.util.*; -import net.java.sip.communicator.service.packetlogging.*; +import javax.sip.*; + import net.java.sip.communicator.util.*; +import org.jitsi.service.packetlogging.*; + /** * This class passes log calls from JAIN-SIP to log4j, so that it is possible * to change the log level for the JAIN-SIP stack in logging.properties diff --git a/src/net/java/sip/communicator/impl/protocol/sip/SipStackProperties.java b/src/net/java/sip/communicator/impl/protocol/sip/SipStackProperties.java index b57243f71..ec87c51a5 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/SipStackProperties.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/SipStackProperties.java @@ -9,12 +9,14 @@ import java.io.*; import java.util.*; import java.util.logging.*; -import net.java.sip.communicator.util.*; -import net.java.sip.communicator.util.Logger; import javax.net.ssl.*; import net.java.sip.communicator.impl.protocol.sip.net.*; +import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; + +import org.jitsi.util.*; /** * The properties used at the creation of the JAIN-SIP stack. diff --git a/src/net/java/sip/communicator/impl/protocol/sip/dtmf/DTMFInfo.java b/src/net/java/sip/communicator/impl/protocol/sip/dtmf/DTMFInfo.java index 612030f90..04afee618 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/dtmf/DTMFInfo.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/dtmf/DTMFInfo.java @@ -18,9 +18,12 @@ import net.java.sip.communicator.impl.protocol.sip.*; import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.OperationFailedException; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.protocol.*; + /** * Sending DTMFs with SIP INFO. * diff --git a/src/net/java/sip/communicator/impl/protocol/sip/net/SslNetworkLayer.java b/src/net/java/sip/communicator/impl/protocol/sip/net/SslNetworkLayer.java index 850b3bc30..f4700cd11 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/net/SslNetworkLayer.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/net/SslNetworkLayer.java @@ -17,7 +17,7 @@ import net.java.sip.communicator.impl.protocol.sip.*; import net.java.sip.communicator.service.certificate.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.Logger; diff --git a/src/net/java/sip/communicator/impl/protocol/sip/sdp/SdpUtils.java b/src/net/java/sip/communicator/impl/protocol/sip/sdp/SdpUtils.java index 4b200df9a..a722d50f1 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/sdp/SdpUtils.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/sdp/SdpUtils.java @@ -12,15 +12,18 @@ import java.util.*; import javax.sdp.*; -import javax.sip.header.ContentTypeHeader; // disambiguates MediaType +import javax.sip.header.*; import net.java.sip.communicator.impl.protocol.sip.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.format.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.MediaType; +import org.jitsi.service.neomedia.format.*; +// disambiguates MediaType + /** * The class contains a number of utility methods that are meant to facilitate * creating and parsing SDP descriptions. diff --git a/src/net/java/sip/communicator/impl/protocol/sip/sip.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/sip/sip.provider.manifest.mf index 6f586f45a..37f89fd3e 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/sip.provider.manifest.mf +++ b/src/net/java/sip/communicator/impl/protocol/sip/sip.provider.manifest.mf @@ -31,29 +31,30 @@ Import-Package: org.apache.log4j, org.apache.http.conn.ssl, org.apache.http.conn.util, org.apache.http.impl.client, + org.jitsi.service.version, org.osgi.framework, org.w3c.dom, org.xml.sax, org.json, net.java.sip.communicator.service.argdelegation, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.credentialsstorage, net.java.sip.communicator.service.certificate, net.java.sip.communicator.service.gui, - net.java.sip.communicator.service.neomedia, - net.java.sip.communicator.service.neomedia.control, - net.java.sip.communicator.service.neomedia.device, - net.java.sip.communicator.service.neomedia.event, - net.java.sip.communicator.service.neomedia.format, + org.jitsi.service.neomedia, + org.jitsi.service.neomedia.control, + org.jitsi.service.neomedia.device, + org.jitsi.service.neomedia.event, + org.jitsi.service.neomedia.format, net.java.sip.communicator.service.hid, net.java.sip.communicator.service.netaddr, net.java.sip.communicator.service.netaddr.event, - net.java.sip.communicator.service.packetlogging, + org.jitsi.service.packetlogging, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.protocol.media, - net.java.sip.communicator.service.resources, - net.java.sip.communicator.service.version, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, + org.jitsi.util, net.java.sip.communicator.util, net.java.sip.communicator.util.dns, net.java.sip.communicator.util.xml, diff --git a/src/net/java/sip/communicator/impl/protocol/sip/xcap/BaseHttpXCapClient.java b/src/net/java/sip/communicator/impl/protocol/sip/xcap/BaseHttpXCapClient.java index 6d3ba2a74..060d4e01d 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/xcap/BaseHttpXCapClient.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/xcap/BaseHttpXCapClient.java @@ -582,4 +582,4 @@ protected String getXCapErrorMessage(XCapHttpResponse response) return null; } } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/ParsingException.java b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/ParsingException.java index ed1ee1303..55e602c29 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/ParsingException.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/ParsingException.java @@ -65,4 +65,4 @@ public ParsingException(Throwable cause) { super(cause); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/prescontent/DataType.java b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/prescontent/DataType.java index 4c04e492a..6c298241e 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/prescontent/DataType.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/prescontent/DataType.java @@ -57,4 +57,4 @@ public Map getAnyAttributes() { return anyAttributes; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/prescontent/EncodingType.java b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/prescontent/EncodingType.java index 1809e971b..a4d387ffe 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/prescontent/EncodingType.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/prescontent/EncodingType.java @@ -57,4 +57,4 @@ public Map getAnyAttributes() { return anyAttributes; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/prescontent/MimeType.java b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/prescontent/MimeType.java index c4a0b1563..564187072 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/prescontent/MimeType.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/prescontent/MimeType.java @@ -57,4 +57,4 @@ public Map getAnyAttributes() { return anyAttributes; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/ClassType.java b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/ClassType.java index b36c5c94b..13a7ab85f 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/ClassType.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/ClassType.java @@ -43,4 +43,4 @@ public void setValue(String value) { this.value = value; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/OccurrenceIdType.java b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/OccurrenceIdType.java index c1669bf89..3a7e9fc01 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/OccurrenceIdType.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/OccurrenceIdType.java @@ -43,4 +43,4 @@ public void setValue(String value) { this.value = value; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/PresRulesParser.java b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/PresRulesParser.java index b3fdc19f6..f48ee4de4 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/PresRulesParser.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/PresRulesParser.java @@ -718,4 +718,4 @@ public static Element elementFromPersonPermission( processAny(element, personPermission.getAny()); return element; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/ProvideServicePermissionType.java b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/ProvideServicePermissionType.java index 992c9fd21..ffa5f0c64 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/ProvideServicePermissionType.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/ProvideServicePermissionType.java @@ -241,4 +241,4 @@ public void setValue(String value) this.value = value; } } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/SubHandlingType.java b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/SubHandlingType.java index d71c10e1d..8a40956ff 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/SubHandlingType.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/presrules/SubHandlingType.java @@ -84,4 +84,4 @@ public static SubHandlingType fromString(String value) } return null; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/resourcelists/ListType.java b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/resourcelists/ListType.java index 95b66fdcb..e6b27ac4c 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/resourcelists/ListType.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/resourcelists/ListType.java @@ -199,4 +199,4 @@ public void setAnyAttributes(Map anyAttributes) { this.anyAttributes = anyAttributes; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/resourcelists/ResourceListsParser.java b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/resourcelists/ResourceListsParser.java index fed90b96d..02f2faef6 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/resourcelists/ResourceListsParser.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/xcap/model/resourcelists/ResourceListsParser.java @@ -714,4 +714,4 @@ else if (!isStandartXmlNamespace(namespaceUri)) displayName.setValue(displayNameElement.getTextContent()); return displayName; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/SSHActivator.java b/src/net/java/sip/communicator/impl/protocol/ssh/SSHActivator.java index c799077c7..8572eab41 100644 --- a/src/net/java/sip/communicator/impl/protocol/ssh/SSHActivator.java +++ b/src/net/java/sip/communicator/impl/protocol/ssh/SSHActivator.java @@ -13,10 +13,12 @@ import java.util.*; -import org.osgi.framework.*; -import net.java.sip.communicator.util.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; +import net.java.sip.communicator.util.*; + +import org.jitsi.service.resources.*; +import org.osgi.framework.*; /** * Loads the SSH provider factory and registers its services in the OSGI diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/ssh.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/ssh/ssh.provider.manifest.mf index 682107a73..4a1d6e132 100644 --- a/src/net/java/sip/communicator/impl/protocol/ssh/ssh.provider.manifest.mf +++ b/src/net/java/sip/communicator/impl/protocol/ssh/ssh.provider.manifest.mf @@ -11,10 +11,10 @@ Import-Package: org.osgi.framework, javax.swing, javax.swing.border, javax.swing.text, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolIconYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolIconYahooImpl.java index 30129f40d..0bfcbd853 100644 --- a/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolIconYahooImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolIconYahooImpl.java @@ -9,12 +9,12 @@ import java.io.*; import java.util.*; -import org.osgi.framework.*; - import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; +import org.osgi.framework.*; + /** * Represents the Yahoo protocol icon. Implements the ProtocolIcon * interface in order to provide an Yahoo icon image in two different sizes. diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/YahooActivator.java b/src/net/java/sip/communicator/impl/protocol/yahoo/YahooActivator.java index e9e712e0f..7b5063283 100644 --- a/src/net/java/sip/communicator/impl/protocol/yahoo/YahooActivator.java +++ b/src/net/java/sip/communicator/impl/protocol/yahoo/YahooActivator.java @@ -8,10 +8,11 @@ import java.util.*; -import org.osgi.framework.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; + +import org.jitsi.service.resources.*; +import org.osgi.framework.*; /** * Loads the Yahoo provider factory and registers it with service in the OSGI diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/yahoo.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/yahoo/yahoo.provider.manifest.mf index d39975759..65394a31f 100644 --- a/src/net/java/sip/communicator/impl/protocol/yahoo/yahoo.provider.manifest.mf +++ b/src/net/java/sip/communicator/impl/protocol/yahoo/yahoo.provider.manifest.mf @@ -13,8 +13,8 @@ Import-Package: org.osgi.framework, javax.naming.directory, org.xml.sax, sun.security.action, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.dns, net.java.sip.communicator.service.protocol, diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/ProtocolIconZeroconfImpl.java b/src/net/java/sip/communicator/impl/protocol/zeroconf/ProtocolIconZeroconfImpl.java index ccc1b896e..9f177add1 100644 --- a/src/net/java/sip/communicator/impl/protocol/zeroconf/ProtocolIconZeroconfImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/zeroconf/ProtocolIconZeroconfImpl.java @@ -10,9 +10,9 @@ import java.util.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/protocol/zeroconf/zeroconf.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/zeroconf/zeroconf.provider.manifest.mf index ce5882098..b6b0a703c 100644 --- a/src/net/java/sip/communicator/impl/protocol/zeroconf/zeroconf.provider.manifest.mf +++ b/src/net/java/sip/communicator/impl/protocol/zeroconf/zeroconf.provider.manifest.mf @@ -5,8 +5,8 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event diff --git a/src/net/java/sip/communicator/impl/provdisc/dhcp/ProvisioningDiscoveryServiceDHCPImpl.java b/src/net/java/sip/communicator/impl/provdisc/dhcp/ProvisioningDiscoveryServiceDHCPImpl.java index 2804e966d..7f3a820b8 100644 --- a/src/net/java/sip/communicator/impl/provdisc/dhcp/ProvisioningDiscoveryServiceDHCPImpl.java +++ b/src/net/java/sip/communicator/impl/provdisc/dhcp/ProvisioningDiscoveryServiceDHCPImpl.java @@ -106,4 +106,4 @@ public void notifyProvisioningURL(DiscoveryEvent event) { fireDiscoveryEvent(event); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/bliptv/BliptvActivator.java b/src/net/java/sip/communicator/impl/replacement/bliptv/BliptvActivator.java index 1e876f0ad..2bddcdd00 100644 --- a/src/net/java/sip/communicator/impl/replacement/bliptv/BliptvActivator.java +++ b/src/net/java/sip/communicator/impl/replacement/bliptv/BliptvActivator.java @@ -68,4 +68,4 @@ public void stop(BundleContext context) throws Exception bliptvServReg.unregister(); logger.info("Blip.TV source implementation [STOPPED]."); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/bliptv/ReplacementServiceBliptvImpl.java b/src/net/java/sip/communicator/impl/replacement/bliptv/ReplacementServiceBliptvImpl.java index a88eafdfe..8942201d5 100644 --- a/src/net/java/sip/communicator/impl/replacement/bliptv/ReplacementServiceBliptvImpl.java +++ b/src/net/java/sip/communicator/impl/replacement/bliptv/ReplacementServiceBliptvImpl.java @@ -114,4 +114,4 @@ public String getPattern() { return BLIPTV_PATTERN; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/bliptv/bliptv.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/bliptv/bliptv.source.manifest.mf index 6fc5ea13a..fd9d81540 100644 --- a/src/net/java/sip/communicator/impl/replacement/bliptv/bliptv.source.manifest.mf +++ b/src/net/java/sip/communicator/impl/replacement/bliptv/bliptv.source.manifest.mf @@ -6,8 +6,8 @@ Bundle-Version: 1.0.0 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.replacement, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, org.apache.http, - org.json \ No newline at end of file + org.json diff --git a/src/net/java/sip/communicator/impl/replacement/dailymotion/DailymotionActivator.java b/src/net/java/sip/communicator/impl/replacement/dailymotion/DailymotionActivator.java index 6db97e05d..120963435 100644 --- a/src/net/java/sip/communicator/impl/replacement/dailymotion/DailymotionActivator.java +++ b/src/net/java/sip/communicator/impl/replacement/dailymotion/DailymotionActivator.java @@ -67,4 +67,4 @@ public void stop(BundleContext context) throws Exception dailymotionSourceServReg.unregister(); logger.info("Dailymotion source implementation [STOPPED]."); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/dailymotion/ReplacementServiceDailymotionImpl.java b/src/net/java/sip/communicator/impl/replacement/dailymotion/ReplacementServiceDailymotionImpl.java index 58425e993..2db20fda9 100644 --- a/src/net/java/sip/communicator/impl/replacement/dailymotion/ReplacementServiceDailymotionImpl.java +++ b/src/net/java/sip/communicator/impl/replacement/dailymotion/ReplacementServiceDailymotionImpl.java @@ -93,4 +93,4 @@ public String getPattern() { return DAILYMOTION_PATTERN; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/dailymotion/dailymotion.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/dailymotion/dailymotion.source.manifest.mf index 019f210f7..b48159b96 100644 --- a/src/net/java/sip/communicator/impl/replacement/dailymotion/dailymotion.source.manifest.mf +++ b/src/net/java/sip/communicator/impl/replacement/dailymotion/dailymotion.source.manifest.mf @@ -5,8 +5,8 @@ Bundle-Vendor: jitsi.org Bundle-Version: 1.0.0 System-Bundle: yes Import-Package: org.osgi.framework, + org.jitsi.service.version, net.java.sip.communicator.service.replacement, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, - net.java.sip.communicator.util, - net.java.sip.communicator.service.version \ No newline at end of file + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, + net.java.sip.communicator.util diff --git a/src/net/java/sip/communicator/impl/replacement/directimage/DirectImageActivator.java b/src/net/java/sip/communicator/impl/replacement/directimage/DirectImageActivator.java index 548033e48..885df716d 100644 --- a/src/net/java/sip/communicator/impl/replacement/directimage/DirectImageActivator.java +++ b/src/net/java/sip/communicator/impl/replacement/directimage/DirectImageActivator.java @@ -68,4 +68,4 @@ public void stop(BundleContext context) throws Exception directImageSourceServReg.unregister(); logger.info("Direct Image Link source implementation [STOPPED]."); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/directimage/ReplacementServiceDirectImageImpl.java b/src/net/java/sip/communicator/impl/replacement/directimage/ReplacementServiceDirectImageImpl.java index 6de36b84a..f3fdb931b 100644 --- a/src/net/java/sip/communicator/impl/replacement/directimage/ReplacementServiceDirectImageImpl.java +++ b/src/net/java/sip/communicator/impl/replacement/directimage/ReplacementServiceDirectImageImpl.java @@ -77,4 +77,4 @@ public String getPattern() { return URL_PATTERN; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/directimage/directimage.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/directimage/directimage.source.manifest.mf index 331f52244..868724487 100644 --- a/src/net/java/sip/communicator/impl/replacement/directimage/directimage.source.manifest.mf +++ b/src/net/java/sip/communicator/impl/replacement/directimage/directimage.source.manifest.mf @@ -5,8 +5,8 @@ Bundle-Vendor: jitsi.org Bundle-Version: 1.0.0 System-Bundle: yes Import-Package: org.osgi.framework, + org.jitsi.service.version, net.java.sip.communicator.service.replacement, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, - net.java.sip.communicator.util, - net.java.sip.communicator.service.version \ No newline at end of file + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, + net.java.sip.communicator.util diff --git a/src/net/java/sip/communicator/impl/replacement/flickr/FlickrActivator.java b/src/net/java/sip/communicator/impl/replacement/flickr/FlickrActivator.java index 7088da02a..cf7e7e90f 100644 --- a/src/net/java/sip/communicator/impl/replacement/flickr/FlickrActivator.java +++ b/src/net/java/sip/communicator/impl/replacement/flickr/FlickrActivator.java @@ -68,4 +68,4 @@ public void stop(BundleContext context) throws Exception flickrServReg.unregister(); logger.info("Flickr source implementation [STOPPED]."); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/flickr/ReplacementServiceFlickrImpl.java b/src/net/java/sip/communicator/impl/replacement/flickr/ReplacementServiceFlickrImpl.java index 5b10caa17..fe79e2028 100644 --- a/src/net/java/sip/communicator/impl/replacement/flickr/ReplacementServiceFlickrImpl.java +++ b/src/net/java/sip/communicator/impl/replacement/flickr/ReplacementServiceFlickrImpl.java @@ -145,4 +145,4 @@ public String getPattern() { return FLICKR_PATTERN; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/flickr/flickr.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/flickr/flickr.source.manifest.mf index 5d91f2cbe..231f4959d 100644 --- a/src/net/java/sip/communicator/impl/replacement/flickr/flickr.source.manifest.mf +++ b/src/net/java/sip/communicator/impl/replacement/flickr/flickr.source.manifest.mf @@ -6,8 +6,8 @@ Bundle-Version: 1.0.0 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.replacement, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, org.apache.http, - org.json \ No newline at end of file + org.json diff --git a/src/net/java/sip/communicator/impl/replacement/hulu/HuluActivator.java b/src/net/java/sip/communicator/impl/replacement/hulu/HuluActivator.java index 42faadc7d..b445a3ac3 100644 --- a/src/net/java/sip/communicator/impl/replacement/hulu/HuluActivator.java +++ b/src/net/java/sip/communicator/impl/replacement/hulu/HuluActivator.java @@ -67,4 +67,4 @@ public void stop(BundleContext context) throws Exception huluServReg.unregister(); logger.info("Hulu source implementation [STOPPED]."); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/hulu/ReplacementServiceHuluImpl.java b/src/net/java/sip/communicator/impl/replacement/hulu/ReplacementServiceHuluImpl.java index 303c0047f..58a5841db 100644 --- a/src/net/java/sip/communicator/impl/replacement/hulu/ReplacementServiceHuluImpl.java +++ b/src/net/java/sip/communicator/impl/replacement/hulu/ReplacementServiceHuluImpl.java @@ -112,4 +112,4 @@ public String getPattern() { return HULU_PATTERN; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/hulu/hulu.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/hulu/hulu.source.manifest.mf index 39d1b5115..b50cd0d0f 100644 --- a/src/net/java/sip/communicator/impl/replacement/hulu/hulu.source.manifest.mf +++ b/src/net/java/sip/communicator/impl/replacement/hulu/hulu.source.manifest.mf @@ -6,8 +6,8 @@ Bundle-Version: 1.0.0 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.replacement, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, org.apache.http, - org.json \ No newline at end of file + org.json diff --git a/src/net/java/sip/communicator/impl/replacement/metacafe/MetacafeActivator.java b/src/net/java/sip/communicator/impl/replacement/metacafe/MetacafeActivator.java index f8b30c586..1d5ec4e5b 100644 --- a/src/net/java/sip/communicator/impl/replacement/metacafe/MetacafeActivator.java +++ b/src/net/java/sip/communicator/impl/replacement/metacafe/MetacafeActivator.java @@ -68,4 +68,4 @@ public void stop(BundleContext context) throws Exception metacafeServReg.unregister(); logger.info("Metacafe source implementation [STOPPED]."); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/metacafe/ReplacementServiceMetacafeImpl.java b/src/net/java/sip/communicator/impl/replacement/metacafe/ReplacementServiceMetacafeImpl.java index 2d0c116f6..6a156caec 100644 --- a/src/net/java/sip/communicator/impl/replacement/metacafe/ReplacementServiceMetacafeImpl.java +++ b/src/net/java/sip/communicator/impl/replacement/metacafe/ReplacementServiceMetacafeImpl.java @@ -92,4 +92,4 @@ public String getPattern() { return METACAFE_PATTERN; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/metacafe/metacafe.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/metacafe/metacafe.source.manifest.mf index df612234e..02a2a1b2f 100644 --- a/src/net/java/sip/communicator/impl/replacement/metacafe/metacafe.source.manifest.mf +++ b/src/net/java/sip/communicator/impl/replacement/metacafe/metacafe.source.manifest.mf @@ -6,6 +6,6 @@ Bundle-Version: 1.0.0 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.replacement, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, - net.java.sip.communicator.util \ No newline at end of file + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, + net.java.sip.communicator.util diff --git a/src/net/java/sip/communicator/impl/replacement/smiley/SmileyActivator.java b/src/net/java/sip/communicator/impl/replacement/smiley/SmileyActivator.java index 03b32aa8f..5b7c0363a 100644 --- a/src/net/java/sip/communicator/impl/replacement/smiley/SmileyActivator.java +++ b/src/net/java/sip/communicator/impl/replacement/smiley/SmileyActivator.java @@ -10,9 +10,9 @@ import net.java.sip.communicator.service.replacement.*; import net.java.sip.communicator.service.replacement.smilies.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** @@ -113,4 +113,4 @@ public static ResourceManagementService getResources() } return resourcesService; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/smiley/SmileyImpl.java b/src/net/java/sip/communicator/impl/replacement/smiley/SmileyImpl.java index a91c96787..4d2779483 100644 --- a/src/net/java/sip/communicator/impl/replacement/smiley/SmileyImpl.java +++ b/src/net/java/sip/communicator/impl/replacement/smiley/SmileyImpl.java @@ -103,4 +103,4 @@ public String getImagePath() return url.toString(); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/smiley/smiley.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/smiley/smiley.source.manifest.mf index 34ce08c9e..c02d7a151 100644 --- a/src/net/java/sip/communicator/impl/replacement/smiley/smiley.source.manifest.mf +++ b/src/net/java/sip/communicator/impl/replacement/smiley/smiley.source.manifest.mf @@ -7,8 +7,8 @@ System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.replacement, net.java.sip.communicator.service.replacement.smilies, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, - net.java.sip.communicator.service.neomedia, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, + org.jitsi.service.neomedia, net.java.sip.communicator.util, - net.java.sip.communicator.service.gui \ No newline at end of file + net.java.sip.communicator.service.gui diff --git a/src/net/java/sip/communicator/impl/replacement/twitpic/ReplacementServiceTwitpicImpl.java b/src/net/java/sip/communicator/impl/replacement/twitpic/ReplacementServiceTwitpicImpl.java index 167a974f4..7c0be3f15 100644 --- a/src/net/java/sip/communicator/impl/replacement/twitpic/ReplacementServiceTwitpicImpl.java +++ b/src/net/java/sip/communicator/impl/replacement/twitpic/ReplacementServiceTwitpicImpl.java @@ -92,4 +92,4 @@ public String getPattern() { return TWITPIC_PATTERN; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/twitpic/TwitpicActivator.java b/src/net/java/sip/communicator/impl/replacement/twitpic/TwitpicActivator.java index 0a627d5bf..a2f0d8f6f 100644 --- a/src/net/java/sip/communicator/impl/replacement/twitpic/TwitpicActivator.java +++ b/src/net/java/sip/communicator/impl/replacement/twitpic/TwitpicActivator.java @@ -68,4 +68,4 @@ public void stop(BundleContext context) throws Exception twitpicServReg.unregister(); logger.info("Twitpic source implementation [STOPPED]."); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/twitpic/twitpic.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/twitpic/twitpic.source.manifest.mf index 7e70d844a..e34d774d5 100644 --- a/src/net/java/sip/communicator/impl/replacement/twitpic/twitpic.source.manifest.mf +++ b/src/net/java/sip/communicator/impl/replacement/twitpic/twitpic.source.manifest.mf @@ -6,6 +6,6 @@ Bundle-Version: 1.0.0 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.replacement, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, - net.java.sip.communicator.util \ No newline at end of file + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, + net.java.sip.communicator.util diff --git a/src/net/java/sip/communicator/impl/replacement/vbox7/ReplacementServiceVbox7Impl.java b/src/net/java/sip/communicator/impl/replacement/vbox7/ReplacementServiceVbox7Impl.java index 3dcb71761..e05b5a2de 100644 --- a/src/net/java/sip/communicator/impl/replacement/vbox7/ReplacementServiceVbox7Impl.java +++ b/src/net/java/sip/communicator/impl/replacement/vbox7/ReplacementServiceVbox7Impl.java @@ -91,4 +91,4 @@ public String getPattern() { return VBOX7_PATTERN; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/vbox7/Vbox7Activator.java b/src/net/java/sip/communicator/impl/replacement/vbox7/Vbox7Activator.java index 05f030389..6c3438fba 100644 --- a/src/net/java/sip/communicator/impl/replacement/vbox7/Vbox7Activator.java +++ b/src/net/java/sip/communicator/impl/replacement/vbox7/Vbox7Activator.java @@ -68,4 +68,4 @@ public void stop(BundleContext context) throws Exception vbox7ServReg.unregister(); logger.info("Vbox7 source implementation [STOPPED]."); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/vbox7/vbox7.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/vbox7/vbox7.source.manifest.mf index 60e802ed6..53705dd16 100644 --- a/src/net/java/sip/communicator/impl/replacement/vbox7/vbox7.source.manifest.mf +++ b/src/net/java/sip/communicator/impl/replacement/vbox7/vbox7.source.manifest.mf @@ -6,6 +6,6 @@ Bundle-Version: 1.0.0 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.replacement, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, - net.java.sip.communicator.util \ No newline at end of file + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, + net.java.sip.communicator.util diff --git a/src/net/java/sip/communicator/impl/replacement/viddler/ReplacementServiceViddlerImpl.java b/src/net/java/sip/communicator/impl/replacement/viddler/ReplacementServiceViddlerImpl.java index 1ccb9aab6..56cb8c40d 100644 --- a/src/net/java/sip/communicator/impl/replacement/viddler/ReplacementServiceViddlerImpl.java +++ b/src/net/java/sip/communicator/impl/replacement/viddler/ReplacementServiceViddlerImpl.java @@ -131,4 +131,4 @@ public String getPattern() { return VIDDLER_PATTERN; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/viddler/ViddlerActivator.java b/src/net/java/sip/communicator/impl/replacement/viddler/ViddlerActivator.java index 92d1283f6..63a68d54d 100644 --- a/src/net/java/sip/communicator/impl/replacement/viddler/ViddlerActivator.java +++ b/src/net/java/sip/communicator/impl/replacement/viddler/ViddlerActivator.java @@ -69,4 +69,4 @@ public void stop(BundleContext bc) throws Exception viddlerServReg.unregister(); logger.info("Viddler source implementation [STOPPED]."); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/viddler/viddler.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/viddler/viddler.source.manifest.mf index 2c5ca73fa..94859a9b4 100644 --- a/src/net/java/sip/communicator/impl/replacement/viddler/viddler.source.manifest.mf +++ b/src/net/java/sip/communicator/impl/replacement/viddler/viddler.source.manifest.mf @@ -6,7 +6,7 @@ Bundle-Version: 1.0.0 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.replacement, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, - org.apache.http \ No newline at end of file + org.apache.http diff --git a/src/net/java/sip/communicator/impl/replacement/vimeo/ReplacementServiceVimeoImpl.java b/src/net/java/sip/communicator/impl/replacement/vimeo/ReplacementServiceVimeoImpl.java index 320461a55..d3305441b 100644 --- a/src/net/java/sip/communicator/impl/replacement/vimeo/ReplacementServiceVimeoImpl.java +++ b/src/net/java/sip/communicator/impl/replacement/vimeo/ReplacementServiceVimeoImpl.java @@ -125,4 +125,4 @@ public String getPattern() { return VIMEO_PATTERN; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/vimeo/VimeoActivator.java b/src/net/java/sip/communicator/impl/replacement/vimeo/VimeoActivator.java index 1a0e1b530..202631001 100644 --- a/src/net/java/sip/communicator/impl/replacement/vimeo/VimeoActivator.java +++ b/src/net/java/sip/communicator/impl/replacement/vimeo/VimeoActivator.java @@ -67,4 +67,4 @@ public void stop(BundleContext context) throws Exception vimeoServReg.unregister(); logger.info("Vimeo source implementation [STOPPED]."); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/vimeo/vimeo.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/vimeo/vimeo.source.manifest.mf index 0b7c8a914..019f275b5 100644 --- a/src/net/java/sip/communicator/impl/replacement/vimeo/vimeo.source.manifest.mf +++ b/src/net/java/sip/communicator/impl/replacement/vimeo/vimeo.source.manifest.mf @@ -6,8 +6,8 @@ Bundle-Version: 1.0.0 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.replacement, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, org.apache.http, - org.json \ No newline at end of file + org.json diff --git a/src/net/java/sip/communicator/impl/replacement/youtube/ReplacementServiceYoutubeImpl.java b/src/net/java/sip/communicator/impl/replacement/youtube/ReplacementServiceYoutubeImpl.java index 7bd29100c..8201714d4 100644 --- a/src/net/java/sip/communicator/impl/replacement/youtube/ReplacementServiceYoutubeImpl.java +++ b/src/net/java/sip/communicator/impl/replacement/youtube/ReplacementServiceYoutubeImpl.java @@ -112,4 +112,4 @@ public String getPattern() { return YOUTUBE_PATTERN; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/youtube/YoutubeActivator.java b/src/net/java/sip/communicator/impl/replacement/youtube/YoutubeActivator.java index d7215bdf9..b1758e639 100644 --- a/src/net/java/sip/communicator/impl/replacement/youtube/YoutubeActivator.java +++ b/src/net/java/sip/communicator/impl/replacement/youtube/YoutubeActivator.java @@ -67,4 +67,4 @@ public void stop(BundleContext context) throws Exception youtubeSourceServReg.unregister(); logger.info("Youtube source implementation [STOPPED]."); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/replacement/youtube/youtube.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/youtube/youtube.source.manifest.mf index c64f517ba..fabe1989a 100644 --- a/src/net/java/sip/communicator/impl/replacement/youtube/youtube.source.manifest.mf +++ b/src/net/java/sip/communicator/impl/replacement/youtube/youtube.source.manifest.mf @@ -6,8 +6,8 @@ Bundle-Version: 1.0.0 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.replacement, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, org.apache.http, - org.json \ No newline at end of file + org.json diff --git a/src/net/java/sip/communicator/impl/resources/ResourceManagementActivator.java b/src/net/java/sip/communicator/impl/resources/ResourceManagementActivator.java index 0bebe765d..e8f02380c 100644 --- a/src/net/java/sip/communicator/impl/resources/ResourceManagementActivator.java +++ b/src/net/java/sip/communicator/impl/resources/ResourceManagementActivator.java @@ -6,10 +6,10 @@ */ package net.java.sip.communicator.impl.resources; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.resources.*; - +import org.jitsi.service.configuration.*; import net.java.sip.communicator.util.*; + +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/resources/ResourceManagementServiceImpl.java b/src/net/java/sip/communicator/impl/resources/ResourceManagementServiceImpl.java index 4a0f0a9e4..c4ef3b84b 100644 --- a/src/net/java/sip/communicator/impl/resources/ResourceManagementServiceImpl.java +++ b/src/net/java/sip/communicator/impl/resources/ResourceManagementServiceImpl.java @@ -18,6 +18,7 @@ import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/resources/resourcemanagement.manifest.mf b/src/net/java/sip/communicator/impl/resources/resourcemanagement.manifest.mf index 83fe65133..95ac100aa 100644 --- a/src/net/java/sip/communicator/impl/resources/resourcemanagement.manifest.mf +++ b/src/net/java/sip/communicator/impl/resources/resourcemanagement.manifest.mf @@ -6,7 +6,8 @@ Bundle-Version: 0.0.1 System-Bundle: yes Export-Package: net.java.sip.communicator.service.resources Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.service.gui, javax.imageio, diff --git a/src/net/java/sip/communicator/impl/shutdowntimeout/shutdown.timeout.manifest.mf b/src/net/java/sip/communicator/impl/shutdowntimeout/shutdown.timeout.manifest.mf index 68144976c..6991b2f39 100644 --- a/src/net/java/sip/communicator/impl/shutdowntimeout/shutdown.timeout.manifest.mf +++ b/src/net/java/sip/communicator/impl/shutdowntimeout/shutdown.timeout.manifest.mf @@ -5,5 +5,5 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.util diff --git a/src/net/java/sip/communicator/impl/sparkle/SparkleActivator.java b/src/net/java/sip/communicator/impl/sparkle/SparkleActivator.java index d521fdb0e..45637d3fc 100644 --- a/src/net/java/sip/communicator/impl/sparkle/SparkleActivator.java +++ b/src/net/java/sip/communicator/impl/sparkle/SparkleActivator.java @@ -9,7 +9,7 @@ import net.java.sip.communicator.service.resources.*; import org.osgi.framework.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.util.*; /** diff --git a/src/net/java/sip/communicator/impl/sparkle/sparkle.manifest.mf b/src/net/java/sip/communicator/impl/sparkle/sparkle.manifest.mf index ea9588197..72b68f01b 100644 --- a/src/net/java/sip/communicator/impl/sparkle/sparkle.manifest.mf +++ b/src/net/java/sip/communicator/impl/sparkle/sparkle.manifest.mf @@ -5,6 +5,6 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util diff --git a/src/net/java/sip/communicator/impl/swingnotification/SwingNotificationActivator.java b/src/net/java/sip/communicator/impl/swingnotification/SwingNotificationActivator.java index 959945994..e22d62946 100644 --- a/src/net/java/sip/communicator/impl/swingnotification/SwingNotificationActivator.java +++ b/src/net/java/sip/communicator/impl/swingnotification/SwingNotificationActivator.java @@ -6,13 +6,14 @@ */ package net.java.sip.communicator.impl.swingnotification; -import org.osgi.framework.*; - -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.service.systray.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; +import org.osgi.framework.*; + /** * Activator for the swing notification service. * @author Symphorien Wanko diff --git a/src/net/java/sip/communicator/impl/swingnotification/swingnotification.manifest.mf b/src/net/java/sip/communicator/impl/swingnotification/swingnotification.manifest.mf index 7fb886704..5558ef8cd 100644 --- a/src/net/java/sip/communicator/impl/swingnotification/swingnotification.manifest.mf +++ b/src/net/java/sip/communicator/impl/swingnotification/swingnotification.manifest.mf @@ -5,9 +5,9 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.protocol, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.service.systray, net.java.sip.communicator.service.systray.event, net.java.sip.communicator.util, diff --git a/src/net/java/sip/communicator/impl/sysactivity/NetworkManagerListenerImpl.java b/src/net/java/sip/communicator/impl/sysactivity/NetworkManagerListenerImpl.java index 6208a8439..113d4b6b5 100644 --- a/src/net/java/sip/communicator/impl/sysactivity/NetworkManagerListenerImpl.java +++ b/src/net/java/sip/communicator/impl/sysactivity/NetworkManagerListenerImpl.java @@ -8,6 +8,7 @@ import net.java.sip.communicator.service.sysactivity.event.*; import net.java.sip.communicator.util.*; + import org.freedesktop.*; import org.freedesktop.dbus.*; import org.freedesktop.dbus.exceptions.*; diff --git a/src/net/java/sip/communicator/impl/sysactivity/SysActivityActivator.java b/src/net/java/sip/communicator/impl/sysactivity/SysActivityActivator.java index ea60cfc7b..90b30df3f 100644 --- a/src/net/java/sip/communicator/impl/sysactivity/SysActivityActivator.java +++ b/src/net/java/sip/communicator/impl/sysactivity/SysActivityActivator.java @@ -7,10 +7,10 @@ package net.java.sip.communicator.impl.sysactivity; import net.java.sip.communicator.service.sysactivity.*; -import org.osgi.framework.*; - import net.java.sip.communicator.util.*; +import org.osgi.framework.*; + /** * Listens for system activity changes like sleep, network change, inactivity * and inform all its listeners. @@ -23,8 +23,7 @@ public class SysActivityActivator /** * The logger. */ - private Logger logger = Logger.getLogger( - SysActivityActivator.class.getName()); + private final Logger logger = Logger.getLogger(SysActivityActivator.class); /** * The OSGi service registration. diff --git a/src/net/java/sip/communicator/impl/sysactivity/SystemActivityEventDispatcher.java b/src/net/java/sip/communicator/impl/sysactivity/SystemActivityEventDispatcher.java index be16d8878..8e091a541 100644 --- a/src/net/java/sip/communicator/impl/sysactivity/SystemActivityEventDispatcher.java +++ b/src/net/java/sip/communicator/impl/sysactivity/SystemActivityEventDispatcher.java @@ -6,12 +6,12 @@ */ package net.java.sip.communicator.impl.sysactivity; +import java.util.*; + import net.java.sip.communicator.service.sysactivity.*; import net.java.sip.communicator.service.sysactivity.event.*; import net.java.sip.communicator.util.*; -import java.util.*; - /** * The class implements a dispatch event thread. The thread will * fire event every time it is added through the fireSystemActivityEvent() diff --git a/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotificationsServiceImpl.java b/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotificationsServiceImpl.java index ea3c78fb3..9a2ad63a4 100644 --- a/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotificationsServiceImpl.java +++ b/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotificationsServiceImpl.java @@ -6,11 +6,13 @@ */ package net.java.sip.communicator.impl.sysactivity; +import java.util.*; + import net.java.sip.communicator.service.sysactivity.*; import net.java.sip.communicator.service.sysactivity.event.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; -import java.util.*; +import org.jitsi.util.*; /** * Service implementation listens for computer changes as sleeping, network diff --git a/src/net/java/sip/communicator/impl/sysactivity/sysactivity.impl.manifest.mf b/src/net/java/sip/communicator/impl/sysactivity/sysactivity.impl.manifest.mf index f60184d86..3785a2694 100644 --- a/src/net/java/sip/communicator/impl/sysactivity/sysactivity.impl.manifest.mf +++ b/src/net/java/sip/communicator/impl/sysactivity/sysactivity.impl.manifest.mf @@ -5,9 +5,10 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, - net.java.sip.communicator.util, - net.java.sip.communicator.service.version + org.jitsi.service.version, + org.jitsi.service.configuration, + org.jitsi.util, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, + net.java.sip.communicator.util Export-Package: net.java.sip.communicator.service.sysactivity, net.java.sip.communicator.service.sysactivity.event diff --git a/src/net/java/sip/communicator/impl/version/VersionActivator.java b/src/net/java/sip/communicator/impl/version/VersionActivator.java index 30f4c151d..45da6be88 100644 --- a/src/net/java/sip/communicator/impl/version/VersionActivator.java +++ b/src/net/java/sip/communicator/impl/version/VersionActivator.java @@ -6,11 +6,11 @@ */ package net.java.sip.communicator.impl.version; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.version.*; -import net.java.sip.communicator.service.version.Version; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.version.*; +import org.jitsi.service.version.Version; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/impl/version/VersionImpl.java b/src/net/java/sip/communicator/impl/version/VersionImpl.java index 1c6d74ce5..bafc75c49 100644 --- a/src/net/java/sip/communicator/impl/version/VersionImpl.java +++ b/src/net/java/sip/communicator/impl/version/VersionImpl.java @@ -6,10 +6,11 @@ */ package net.java.sip.communicator.impl.version; -import net.java.sip.communicator.service.resources.*; -import net.java.sip.communicator.service.version.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; +import org.jitsi.service.version.*; + /** * A static implementation of the Version interface. */ diff --git a/src/net/java/sip/communicator/impl/version/VersionServiceImpl.java b/src/net/java/sip/communicator/impl/version/VersionServiceImpl.java index a5950683c..db0ea7e8a 100644 --- a/src/net/java/sip/communicator/impl/version/VersionServiceImpl.java +++ b/src/net/java/sip/communicator/impl/version/VersionServiceImpl.java @@ -6,7 +6,7 @@ */ package net.java.sip.communicator.impl.version; -import net.java.sip.communicator.service.version.*; +import org.jitsi.service.version.*; /** * The version service keeps track of the SIP Communicator version that we are diff --git a/src/net/java/sip/communicator/impl/version/version.impl.manifest.mf b/src/net/java/sip/communicator/impl/version/version.impl.manifest.mf index 0f3f76e91..a526ab94d 100755 --- a/src/net/java/sip/communicator/impl/version/version.impl.manifest.mf +++ b/src/net/java/sip/communicator/impl/version/version.impl.manifest.mf @@ -5,7 +5,7 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, - net.java.sip.communicator.util, - net.java.sip.communicator.service.version + org.jitsi.service.configuration, + org.jitsi.service.version, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, + net.java.sip.communicator.util diff --git a/src/net/java/sip/communicator/launcher/BrowserLauncher.java b/src/net/java/sip/communicator/launcher/BrowserLauncher.java index 97aedcb26..e88bfeab8 100644 --- a/src/net/java/sip/communicator/launcher/BrowserLauncher.java +++ b/src/net/java/sip/communicator/launcher/BrowserLauncher.java @@ -6,9 +6,9 @@ */ package net.java.sip.communicator.launcher; -import com.apple.eio.*; +import org.jitsi.util.*; -import net.java.sip.communicator.util.*; +import com.apple.eio.*; /** * A simple implementation of the BrowserLauncherService. Checks the operating diff --git a/src/net/java/sip/communicator/plugin/accountinfo/Resources.java b/src/net/java/sip/communicator/plugin/accountinfo/Resources.java index 7ece21a3b..f6bd38750 100644 --- a/src/net/java/sip/communicator/plugin/accountinfo/Resources.java +++ b/src/net/java/sip/communicator/plugin/accountinfo/Resources.java @@ -10,6 +10,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the image resources used in this plugin. diff --git a/src/net/java/sip/communicator/plugin/accountinfo/accountinfo.manifest.mf b/src/net/java/sip/communicator/plugin/accountinfo/accountinfo.manifest.mf index 47ccf4bca..e32907692 100644 --- a/src/net/java/sip/communicator/plugin/accountinfo/accountinfo.manifest.mf +++ b/src/net/java/sip/communicator/plugin/accountinfo/accountinfo.manifest.mf @@ -12,7 +12,7 @@ Import-Package: org.osgi.framework, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/addrbook/AddrBookActivator.java b/src/net/java/sip/communicator/plugin/addrbook/AddrBookActivator.java index a19b16fca..7c3dafa7a 100644 --- a/src/net/java/sip/communicator/plugin/addrbook/AddrBookActivator.java +++ b/src/net/java/sip/communicator/plugin/addrbook/AddrBookActivator.java @@ -8,13 +8,15 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.service.contactsource.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; +import org.jitsi.service.configuration.*; +import org.jitsi.service.resources.*; +import org.jitsi.util.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/addrbook/AdvancedConfigForm.java b/src/net/java/sip/communicator/plugin/addrbook/AdvancedConfigForm.java index dcb7ce495..f88c27cd9 100644 --- a/src/net/java/sip/communicator/plugin/addrbook/AdvancedConfigForm.java +++ b/src/net/java/sip/communicator/plugin/addrbook/AdvancedConfigForm.java @@ -10,11 +10,12 @@ import javax.swing.*; -import net.java.sip.communicator.plugin.addrbook.macosx.MacOSXAddrBookContactSourceService; -import net.java.sip.communicator.plugin.addrbook.msoutlook.MsOutlookAddrBookContactSourceService; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.plugin.addrbook.macosx.*; +import net.java.sip.communicator.plugin.addrbook.msoutlook.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.util.*; + /** * Implementation of the advanced address book configuration form. * @@ -156,4 +157,4 @@ public void focusLost(FocusEvent e) }); return prefixPanel; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/addrbook/addrbook.manifest.mf b/src/net/java/sip/communicator/plugin/addrbook/addrbook.manifest.mf index 70110fbcb..ee9e92daf 100644 --- a/src/net/java/sip/communicator/plugin/addrbook/addrbook.manifest.mf +++ b/src/net/java/sip/communicator/plugin/addrbook/addrbook.manifest.mf @@ -4,11 +4,12 @@ Bundle-Name: OS-specific Address Book support Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 Import-Package: javax.swing, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, + org.jitsi.util, net.java.sip.communicator.service.contactsource, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.protocol, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, org.osgi.framework diff --git a/src/net/java/sip/communicator/plugin/advancedconfig/AdvancedConfigActivator.java b/src/net/java/sip/communicator/plugin/advancedconfig/AdvancedConfigActivator.java index feff4b0f7..82d0d2232 100644 --- a/src/net/java/sip/communicator/plugin/advancedconfig/AdvancedConfigActivator.java +++ b/src/net/java/sip/communicator/plugin/advancedconfig/AdvancedConfigActivator.java @@ -2,11 +2,12 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/advancedconfig/advancedconfig.manifest.mf b/src/net/java/sip/communicator/plugin/advancedconfig/advancedconfig.manifest.mf index 8bd44ca63..b0065cf9b 100644 --- a/src/net/java/sip/communicator/plugin/advancedconfig/advancedconfig.manifest.mf +++ b/src/net/java/sip/communicator/plugin/advancedconfig/advancedconfig.manifest.mf @@ -5,13 +5,13 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.service.systray, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, diff --git a/src/net/java/sip/communicator/plugin/aimaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/aimaccregwizz/Resources.java index de35837ad..82df085fc 100644 --- a/src/net/java/sip/communicator/plugin/aimaccregwizz/Resources.java +++ b/src/net/java/sip/communicator/plugin/aimaccregwizz/Resources.java @@ -8,6 +8,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the image resources used in this plugin. diff --git a/src/net/java/sip/communicator/plugin/aimaccregwizz/aimaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/aimaccregwizz/aimaccregwizz.manifest.mf index b59193200..d71dd9183 100644 --- a/src/net/java/sip/communicator/plugin/aimaccregwizz/aimaccregwizz.manifest.mf +++ b/src/net/java/sip/communicator/plugin/aimaccregwizz/aimaccregwizz.manifest.mf @@ -6,7 +6,7 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, net.java.sip.communicator.service.gui, @@ -15,7 +15,7 @@ Import-Package: org.osgi.framework, net.java.sip.communicator.service.protocol.aimconstants, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.protocol.icqconstants, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/branding/AboutWindow.java b/src/net/java/sip/communicator/plugin/branding/AboutWindow.java index 35ea79554..47ba575b5 100644 --- a/src/net/java/sip/communicator/plugin/branding/AboutWindow.java +++ b/src/net/java/sip/communicator/plugin/branding/AboutWindow.java @@ -16,12 +16,14 @@ import net.java.sip.communicator.service.browserlauncher.*; import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; import net.java.sip.communicator.util.swing.plaf.*; +import org.jitsi.service.resources.*; +import org.jitsi.util.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/branding/BrandingActivator.java b/src/net/java/sip/communicator/plugin/branding/BrandingActivator.java index 327478552..e0786ff5c 100644 --- a/src/net/java/sip/communicator/plugin/branding/BrandingActivator.java +++ b/src/net/java/sip/communicator/plugin/branding/BrandingActivator.java @@ -9,11 +9,12 @@ import java.lang.reflect.*; import java.util.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/branding/JitsiWarningWindow.java b/src/net/java/sip/communicator/plugin/branding/JitsiWarningWindow.java index e037729c0..b07286990 100644 --- a/src/net/java/sip/communicator/plugin/branding/JitsiWarningWindow.java +++ b/src/net/java/sip/communicator/plugin/branding/JitsiWarningWindow.java @@ -12,10 +12,10 @@ import javax.swing.*; import net.java.sip.communicator.service.browserlauncher.*; -import net.java.sip.communicator.service.resources.*; -import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; +import org.jitsi.util.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/branding/WelcomeWindow.java b/src/net/java/sip/communicator/plugin/branding/WelcomeWindow.java index 61e7a9e1c..345546bab 100644 --- a/src/net/java/sip/communicator/plugin/branding/WelcomeWindow.java +++ b/src/net/java/sip/communicator/plugin/branding/WelcomeWindow.java @@ -14,9 +14,10 @@ import javax.imageio.*; import javax.swing.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; + /** * The WelcomeWindow is actually the splash screen shown while the * application is loading. It displays the status of the loading process and diff --git a/src/net/java/sip/communicator/plugin/branding/branding.manifest.mf b/src/net/java/sip/communicator/plugin/branding/branding.manifest.mf index 9388e0d8b..659f89d66 100755 --- a/src/net/java/sip/communicator/plugin/branding/branding.manifest.mf +++ b/src/net/java/sip/communicator/plugin/branding/branding.manifest.mf @@ -6,11 +6,12 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.protocol, + org.jitsi.util, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, net.java.sip.communicator.util.swing.plaf, diff --git a/src/net/java/sip/communicator/plugin/certconfig/CertConfigActivator.java b/src/net/java/sip/communicator/plugin/certconfig/CertConfigActivator.java index 12bb09370..95d8880e6 100644 --- a/src/net/java/sip/communicator/plugin/certconfig/CertConfigActivator.java +++ b/src/net/java/sip/communicator/plugin/certconfig/CertConfigActivator.java @@ -9,12 +9,12 @@ import java.util.*; import net.java.sip.communicator.service.certificate.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.credentialsstorage.CredentialsStorageService; +import org.jitsi.service.configuration.*; +import net.java.sip.communicator.service.credentialsstorage.*; import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/certconfig/CertConfigEntryDialog.java b/src/net/java/sip/communicator/plugin/certconfig/CertConfigEntryDialog.java index cfc43c073..861820c59 100644 --- a/src/net/java/sip/communicator/plugin/certconfig/CertConfigEntryDialog.java +++ b/src/net/java/sip/communicator/plugin/certconfig/CertConfigEntryDialog.java @@ -11,19 +11,19 @@ import java.io.*; import java.lang.reflect.*; import java.security.*; -import java.security.cert.X509Certificate; +import java.security.cert.*; import java.util.*; import javax.security.auth.callback.*; import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; +import javax.swing.event.*; import net.java.sip.communicator.service.certificate.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; + /** * Dialog window to add/edit client certificate configuration entries. * diff --git a/src/net/java/sip/communicator/plugin/certconfig/CertConfigPanel.java b/src/net/java/sip/communicator/plugin/certconfig/CertConfigPanel.java index bbf636454..86e9c573c 100644 --- a/src/net/java/sip/communicator/plugin/certconfig/CertConfigPanel.java +++ b/src/net/java/sip/communicator/plugin/certconfig/CertConfigPanel.java @@ -10,15 +10,16 @@ import java.awt.event.*; import javax.swing.*; -import javax.swing.border.EmptyBorder; +import javax.swing.border.*; import javax.swing.event.*; import net.java.sip.communicator.service.certificate.*; import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.resources.*; -import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; +import org.jitsi.util.*; + /** * Advanced configuration form to define client TLS certificate templates. * diff --git a/src/net/java/sip/communicator/plugin/certconfig/CertConfigTableModel.java b/src/net/java/sip/communicator/plugin/certconfig/CertConfigTableModel.java index 493366123..198baf72b 100644 --- a/src/net/java/sip/communicator/plugin/certconfig/CertConfigTableModel.java +++ b/src/net/java/sip/communicator/plugin/certconfig/CertConfigTableModel.java @@ -12,7 +12,8 @@ import javax.swing.table.*; import net.java.sip.communicator.service.certificate.*; -import net.java.sip.communicator.service.resources.*; + +import org.jitsi.service.resources.*; /** * Backing data model for a JTable that displays the client certificate diff --git a/src/net/java/sip/communicator/plugin/certconfig/certconfig.manifest.mf b/src/net/java/sip/communicator/plugin/certconfig/certconfig.manifest.mf index 99a98993a..5989fec5b 100644 --- a/src/net/java/sip/communicator/plugin/certconfig/certconfig.manifest.mf +++ b/src/net/java/sip/communicator/plugin/certconfig/certconfig.manifest.mf @@ -6,10 +6,11 @@ Bundle-Version: 0.0.1 System-Bundle: no Import-Package: org.osgi.framework, net.java.sip.communicator.service.certificate, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.credentialsstorage, net.java.sip.communicator.service.gui, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, + org.jitsi.util, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, @@ -18,4 +19,4 @@ Import-Package: org.osgi.framework, javax.swing.table, javax.security.auth, javax.security.auth.callback, - sun.security.pkcs11 \ No newline at end of file + sun.security.pkcs11 diff --git a/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java b/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java index 9b8e7f2a3..449aa1a48 100644 --- a/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java +++ b/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java @@ -11,9 +11,10 @@ import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; import org.jdesktop.jdic.misc.*; +import org.jitsi.util.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/chatalerter/chatalerter.manifest.mf b/src/net/java/sip/communicator/plugin/chatalerter/chatalerter.manifest.mf index ac6b9eb82..cd6349c87 100644 --- a/src/net/java/sip/communicator/plugin/chatalerter/chatalerter.manifest.mf +++ b/src/net/java/sip/communicator/plugin/chatalerter/chatalerter.manifest.mf @@ -5,9 +5,10 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.util, - net.java.sip.communicator.service.gui, - net.java.sip.communicator.service.protocol, - net.java.sip.communicator.service.protocol.event, - com.apple.eawt, - javax.swing + org.jitsi.util, + net.java.sip.communicator.util, + net.java.sip.communicator.service.gui, + net.java.sip.communicator.service.protocol, + net.java.sip.communicator.service.protocol.event, + com.apple.eawt, + javax.swing diff --git a/src/net/java/sip/communicator/plugin/chatconfig/ChatConfigActivator.java b/src/net/java/sip/communicator/plugin/chatconfig/ChatConfigActivator.java index 61fa681c5..181c4174f 100644 --- a/src/net/java/sip/communicator/plugin/chatconfig/ChatConfigActivator.java +++ b/src/net/java/sip/communicator/plugin/chatconfig/ChatConfigActivator.java @@ -10,13 +10,14 @@ import javax.swing.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.replacement.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/chatconfig/ChatConfigPanel.java b/src/net/java/sip/communicator/plugin/chatconfig/ChatConfigPanel.java index f96dc0aad..fbdedc749 100644 --- a/src/net/java/sip/communicator/plugin/chatconfig/ChatConfigPanel.java +++ b/src/net/java/sip/communicator/plugin/chatconfig/ChatConfigPanel.java @@ -40,4 +40,4 @@ public ChatConfigPanel() mainPanel.add(new ReplacementConfigPanel()); mainPanel.add(Box.createVerticalStrut(10)); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/chatconfig/chatconfig.manifest.mf b/src/net/java/sip/communicator/plugin/chatconfig/chatconfig.manifest.mf index 49d96b594..f332b74d0 100644 --- a/src/net/java/sip/communicator/plugin/chatconfig/chatconfig.manifest.mf +++ b/src/net/java/sip/communicator/plugin/chatconfig/chatconfig.manifest.mf @@ -5,10 +5,10 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, net.java.sip.communicator.service.replacement, @@ -25,4 +25,4 @@ Import-Package: org.osgi.framework, javax.swing.filechooser, javax.swing.tree, javax.swing.undo, - javax.swing.border \ No newline at end of file + javax.swing.border diff --git a/src/net/java/sip/communicator/plugin/chatconfig/replacement/ReplacementConfigPanel.java b/src/net/java/sip/communicator/plugin/chatconfig/replacement/ReplacementConfigPanel.java index 8223ed2ac..117d9356d 100644 --- a/src/net/java/sip/communicator/plugin/chatconfig/replacement/ReplacementConfigPanel.java +++ b/src/net/java/sip/communicator/plugin/chatconfig/replacement/ReplacementConfigPanel.java @@ -14,7 +14,7 @@ import net.java.sip.communicator.impl.replacement.smiley.*; import net.java.sip.communicator.plugin.chatconfig.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.replacement.*; import net.java.sip.communicator.util.swing.*; @@ -250,4 +250,4 @@ public Component getTableCellRendererComponent(JTable table, Object value, return this; } } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/chatconfig/replacement/ReplacementConfigurationTableModel.java b/src/net/java/sip/communicator/plugin/chatconfig/replacement/ReplacementConfigurationTableModel.java index 482c7c485..3f3d619ad 100644 --- a/src/net/java/sip/communicator/plugin/chatconfig/replacement/ReplacementConfigurationTableModel.java +++ b/src/net/java/sip/communicator/plugin/chatconfig/replacement/ReplacementConfigurationTableModel.java @@ -10,7 +10,7 @@ import javax.swing.table.*; import net.java.sip.communicator.plugin.chatconfig.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.replacement.*; /** @@ -141,4 +141,4 @@ public void setValueAt(Object value, int rowIndex, int columnIndex) } } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoActivator.java b/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoActivator.java index db3ec8e5a..3f3eba093 100644 --- a/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoActivator.java +++ b/src/net/java/sip/communicator/plugin/contactinfo/ContactInfoActivator.java @@ -68,4 +68,4 @@ public static BrowserLauncherService getBrowserLauncher() return browserLauncherService; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/contactinfo/Resources.java b/src/net/java/sip/communicator/plugin/contactinfo/Resources.java index 5a77b2e35..dbb8ff45e 100644 --- a/src/net/java/sip/communicator/plugin/contactinfo/Resources.java +++ b/src/net/java/sip/communicator/plugin/contactinfo/Resources.java @@ -15,6 +15,8 @@ import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the image resources used in this plugin. diff --git a/src/net/java/sip/communicator/plugin/contactinfo/contactinfo.manifest.mf b/src/net/java/sip/communicator/plugin/contactinfo/contactinfo.manifest.mf index 1e1e3bc4a..09bf6c159 100644 --- a/src/net/java/sip/communicator/plugin/contactinfo/contactinfo.manifest.mf +++ b/src/net/java/sip/communicator/plugin/contactinfo/contactinfo.manifest.mf @@ -11,7 +11,7 @@ Import-Package: org.osgi.framework, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.protocol, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/contactsourceconfig/ContactSourceConfigActivator.java b/src/net/java/sip/communicator/plugin/contactsourceconfig/ContactSourceConfigActivator.java index f0b4d68fd..6fde91b3b 100644 --- a/src/net/java/sip/communicator/plugin/contactsourceconfig/ContactSourceConfigActivator.java +++ b/src/net/java/sip/communicator/plugin/contactsourceconfig/ContactSourceConfigActivator.java @@ -7,11 +7,13 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; +import net.java.sip.communicator.plugin.securityconfig.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/contactsourceconfig/contactsourceconfig.manifest.mf b/src/net/java/sip/communicator/plugin/contactsourceconfig/contactsourceconfig.manifest.mf index 8b306b468..0814977c3 100644 --- a/src/net/java/sip/communicator/plugin/contactsourceconfig/contactsourceconfig.manifest.mf +++ b/src/net/java/sip/communicator/plugin/contactsourceconfig/contactsourceconfig.manifest.mf @@ -8,8 +8,8 @@ Import-Package: net.java.sip.communicator.service.contactsource, net.java.sip.communicator.util, net.java.sip.communicator.service.gui, net.java.sip.communicator.util.swing, - net.java.sip.communicator.service.resources, - net.java.sip.communicator.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, org.osgi.framework, javax.swing System-Bundle: yes diff --git a/src/net/java/sip/communicator/plugin/defaultresourcepack/defaultresourcepack.manifest.mf b/src/net/java/sip/communicator/plugin/defaultresourcepack/defaultresourcepack.manifest.mf index a6c46c673..467bf888a 100644 --- a/src/net/java/sip/communicator/plugin/defaultresourcepack/defaultresourcepack.manifest.mf +++ b/src/net/java/sip/communicator/plugin/defaultresourcepack/defaultresourcepack.manifest.mf @@ -6,4 +6,4 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.util, - net.java.sip.communicator.service.resources + org.jitsi.service.resources, net.java.sip.communicator.service.resources diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/dictaccregwizz/Resources.java index aae29db66..c520207ca 100644 --- a/src/net/java/sip/communicator/plugin/dictaccregwizz/Resources.java +++ b/src/net/java/sip/communicator/plugin/dictaccregwizz/Resources.java @@ -8,6 +8,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the image resources used in this plugin. diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/dictaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/dictaccregwizz/dictaccregwizz.manifest.mf index 7e9a51c0a..ebf4a69ad 100644 --- a/src/net/java/sip/communicator/plugin/dictaccregwizz/dictaccregwizz.manifest.mf +++ b/src/net/java/sip/communicator/plugin/dictaccregwizz/dictaccregwizz.manifest.mf @@ -7,7 +7,7 @@ System-Bundle: yes Import-Package: org.osgi.framework, net.java.dict4j, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, net.java.sip.communicator.service.gui, @@ -15,7 +15,7 @@ Import-Package: org.osgi.framework, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.protocol.icqconstants, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/dnsconfig/DnsConfigActivator.java b/src/net/java/sip/communicator/plugin/dnsconfig/DnsConfigActivator.java index 4c1b00ce6..c8acab7b4 100644 --- a/src/net/java/sip/communicator/plugin/dnsconfig/DnsConfigActivator.java +++ b/src/net/java/sip/communicator/plugin/dnsconfig/DnsConfigActivator.java @@ -8,11 +8,11 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.fileaccess.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.fileaccess.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/dnsconfig/DnsContainerPanel.java b/src/net/java/sip/communicator/plugin/dnsconfig/DnsContainerPanel.java index 487bcf1c9..ff55fbcd8 100644 --- a/src/net/java/sip/communicator/plugin/dnsconfig/DnsContainerPanel.java +++ b/src/net/java/sip/communicator/plugin/dnsconfig/DnsContainerPanel.java @@ -6,12 +6,12 @@ */ package net.java.sip.communicator.plugin.dnsconfig; -import org.osgi.framework.*; - -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; +import org.osgi.framework.*; + /** * Container for all DNS configuration panels. * diff --git a/src/net/java/sip/communicator/plugin/dnsconfig/DnssecPanel.java b/src/net/java/sip/communicator/plugin/dnsconfig/DnssecPanel.java index c663eb35e..2bdfde0a2 100644 --- a/src/net/java/sip/communicator/plugin/dnsconfig/DnssecPanel.java +++ b/src/net/java/sip/communicator/plugin/dnsconfig/DnssecPanel.java @@ -8,21 +8,21 @@ import java.awt.*; import java.awt.event.*; -import java.io.File; +import java.io.*; import javax.swing.*; import javax.swing.plaf.basic.*; import javax.swing.table.*; -import org.osgi.framework.*; - -import net.java.sip.communicator.impl.gui.customcontrols.ErrorDialog; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.resources.*; +import net.java.sip.communicator.impl.gui.customcontrols.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.dns.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; +import org.osgi.framework.*; + /** * Configuration of the DNSSEC validating resolver. * diff --git a/src/net/java/sip/communicator/plugin/dnsconfig/DnssecTableModel.java b/src/net/java/sip/communicator/plugin/dnsconfig/DnssecTableModel.java index accdfbbb5..68ff7754c 100644 --- a/src/net/java/sip/communicator/plugin/dnsconfig/DnssecTableModel.java +++ b/src/net/java/sip/communicator/plugin/dnsconfig/DnssecTableModel.java @@ -12,11 +12,11 @@ import javax.swing.table.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.dns.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/dnsconfig/ParallelDnsPanel.java b/src/net/java/sip/communicator/plugin/dnsconfig/ParallelDnsPanel.java index 79975ceda..85eca21fc 100644 --- a/src/net/java/sip/communicator/plugin/dnsconfig/ParallelDnsPanel.java +++ b/src/net/java/sip/communicator/plugin/dnsconfig/ParallelDnsPanel.java @@ -6,26 +6,36 @@ */ package net.java.sip.communicator.plugin.dnsconfig; +import static net.java.sip.communicator.util.NetworkUtils.DEFAULT_BACKUP_RESOLVER; +import static net.java.sip.communicator.util.NetworkUtils.PDEFAULT_BACKUP_RESOLVER_ENABLED; +import static net.java.sip.communicator.util.NetworkUtils.PNAME_BACKUP_RESOLVER; +import static net.java.sip.communicator.util.NetworkUtils.PNAME_BACKUP_RESOLVER_ENABLED; +import static net.java.sip.communicator.util.NetworkUtils.PNAME_BACKUP_RESOLVER_FALLBACK_IP; +import static net.java.sip.communicator.util.NetworkUtils.PNAME_BACKUP_RESOLVER_PORT; +import static net.java.sip.communicator.util.NetworkUtils.getDefaultDnsPort; +import static net.java.sip.communicator.util.NetworkUtils.isIPv4Address; +import static net.java.sip.communicator.util.NetworkUtils.isIPv6Address; +import static net.java.sip.communicator.util.dns.ParallelResolver.DNS_PATIENCE; +import static net.java.sip.communicator.util.dns.ParallelResolver.DNS_REDEMPTION; +import static net.java.sip.communicator.util.dns.ParallelResolver.PNAME_DNS_PATIENCE; +import static net.java.sip.communicator.util.dns.ParallelResolver.PNAME_DNS_REDEMPTION; + import java.awt.*; import java.awt.event.*; import java.text.*; -import java.util.EventObject; +import java.util.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; - -import org.osgi.framework.*; - -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.dns.*; import net.java.sip.communicator.util.swing.*; -import static net.java.sip.communicator.util.NetworkUtils.*; -import static net.java.sip.communicator.util.dns.ParallelResolver.*; +import org.jitsi.service.resources.*; +import org.osgi.framework.*; /** * Page inside the advanced configuration options that allow the user to diff --git a/src/net/java/sip/communicator/plugin/dnsconfig/dnsconfig.manifest.mf b/src/net/java/sip/communicator/plugin/dnsconfig/dnsconfig.manifest.mf index 61c903d0d..b6a4bc3ad 100644 --- a/src/net/java/sip/communicator/plugin/dnsconfig/dnsconfig.manifest.mf +++ b/src/net/java/sip/communicator/plugin/dnsconfig/dnsconfig.manifest.mf @@ -5,11 +5,11 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: no Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.fileaccess, + org.jitsi.service.configuration, + org.jitsi.service.fileaccess, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.dns, net.java.sip.communicator.util.swing, diff --git a/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccRegWizzActivator.java index 1b7fdced8..ae518bdc8 100644 --- a/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccRegWizzActivator.java +++ b/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccRegWizzActivator.java @@ -8,12 +8,13 @@ import java.util.*; +import net.java.sip.communicator.service.browserlauncher.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; -import net.java.sip.communicator.service.browserlauncher.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/facebookaccregwizz/facebookaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/facebookaccregwizz/facebookaccregwizz.manifest.mf index 5e5b36e4d..a6143fea3 100644 --- a/src/net/java/sip/communicator/plugin/facebookaccregwizz/facebookaccregwizz.manifest.mf +++ b/src/net/java/sip/communicator/plugin/facebookaccregwizz/facebookaccregwizz.manifest.mf @@ -6,14 +6,14 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, net.java.sip.communicator.plugin.jabberaccregwizz, diff --git a/src/net/java/sip/communicator/plugin/generalconfig/ConfigurationManager.java b/src/net/java/sip/communicator/plugin/generalconfig/ConfigurationManager.java index 6d1adbacf..56f2aa4f4 100644 --- a/src/net/java/sip/communicator/plugin/generalconfig/ConfigurationManager.java +++ b/src/net/java/sip/communicator/plugin/generalconfig/ConfigurationManager.java @@ -11,11 +11,13 @@ import javax.net.ssl.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; + public class ConfigurationManager { private static final Logger logger diff --git a/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigPluginActivator.java b/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigPluginActivator.java index 227ce81aa..dfdb32f2a 100644 --- a/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigPluginActivator.java +++ b/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigPluginActivator.java @@ -13,7 +13,7 @@ import javax.swing.border.*; import net.java.sip.communicator.plugin.generalconfig.autoaway.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; @@ -21,6 +21,7 @@ import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigurationPanel.java b/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigurationPanel.java index 0cf8ae0d7..537c98ecc 100644 --- a/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigurationPanel.java +++ b/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigurationPanel.java @@ -17,9 +17,10 @@ import net.java.sip.communicator.plugin.generalconfig.autoaway.*; import net.java.sip.communicator.service.systray.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; import net.java.sip.communicator.util.swing.*; +import org.jitsi.util.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/generalconfig/Resources.java b/src/net/java/sip/communicator/plugin/generalconfig/Resources.java index 8c8d75b6a..87f283f81 100644 --- a/src/net/java/sip/communicator/plugin/generalconfig/Resources.java +++ b/src/net/java/sip/communicator/plugin/generalconfig/Resources.java @@ -8,6 +8,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the image resources used in this plugin. diff --git a/src/net/java/sip/communicator/plugin/generalconfig/SIPConfigForm.java b/src/net/java/sip/communicator/plugin/generalconfig/SIPConfigForm.java index 186d554ec..d65b9e376 100644 --- a/src/net/java/sip/communicator/plugin/generalconfig/SIPConfigForm.java +++ b/src/net/java/sip/communicator/plugin/generalconfig/SIPConfigForm.java @@ -182,4 +182,4 @@ public void actionPerformed(ActionEvent e) ConfigurationManager.setEnabledSslProtocols( enabledSslProtocols.toArray(new String[]{})); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayConfigurationPanel.java b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayConfigurationPanel.java index e0ad1fc5f..b4fe353f1 100644 --- a/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayConfigurationPanel.java +++ b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayConfigurationPanel.java @@ -13,10 +13,11 @@ import javax.swing.event.*; import net.java.sip.communicator.plugin.generalconfig.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; + /** * The ConfigurationForm that would be added in the user interface * configuration window. diff --git a/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayWatcher.java b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayWatcher.java index 382861ff1..b9d5a741c 100644 --- a/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayWatcher.java +++ b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayWatcher.java @@ -7,7 +7,7 @@ package net.java.sip.communicator.plugin.generalconfig.autoaway; import net.java.sip.communicator.plugin.generalconfig.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.sysactivity.*; diff --git a/src/net/java/sip/communicator/plugin/generalconfig/autoaway/Preferences.java b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/Preferences.java index 5573e2bdc..80faf2a45 100644 --- a/src/net/java/sip/communicator/plugin/generalconfig/autoaway/Preferences.java +++ b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/Preferences.java @@ -18,4 +18,4 @@ public final class Preferences "net.java.sip.communicator.plugin.statusupdate.enable"; public static final String TIMER = "net.java.sip.communicator.plugin.statusupdate.timer"; -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/generalconfig/autoaway/StatusUpdateThread.java b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/StatusUpdateThread.java index 2c97bfa5e..6399672a2 100644 --- a/src/net/java/sip/communicator/plugin/generalconfig/autoaway/StatusUpdateThread.java +++ b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/StatusUpdateThread.java @@ -10,9 +10,10 @@ import java.util.*; import net.java.sip.communicator.plugin.generalconfig.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; + +import org.jitsi.service.resources.*; /** * A Runnable, which permanently looks at the mouse position. If the mouse is diff --git a/src/net/java/sip/communicator/plugin/generalconfig/generalconfig.manifest.mf b/src/net/java/sip/communicator/plugin/generalconfig/generalconfig.manifest.mf index e5741a735..67c6e59d9 100644 --- a/src/net/java/sip/communicator/plugin/generalconfig/generalconfig.manifest.mf +++ b/src/net/java/sip/communicator/plugin/generalconfig/generalconfig.manifest.mf @@ -5,14 +5,15 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, + org.jitsi.util, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.service.systray, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, diff --git a/src/net/java/sip/communicator/plugin/gibberishaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/gibberishaccregwizz/Resources.java index bf5e634f9..ab2ba3675 100644 --- a/src/net/java/sip/communicator/plugin/gibberishaccregwizz/Resources.java +++ b/src/net/java/sip/communicator/plugin/gibberishaccregwizz/Resources.java @@ -8,6 +8,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the image resources used in this plugin. diff --git a/src/net/java/sip/communicator/plugin/gibberishaccregwizz/gibberishaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/gibberishaccregwizz/gibberishaccregwizz.manifest.mf index 98aacf211..88de8d48f 100644 --- a/src/net/java/sip/communicator/plugin/gibberishaccregwizz/gibberishaccregwizz.manifest.mf +++ b/src/net/java/sip/communicator/plugin/gibberishaccregwizz/gibberishaccregwizz.manifest.mf @@ -6,14 +6,14 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyConfigForm.java b/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyConfigForm.java index cb2cb586f..240f33d18 100644 --- a/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyConfigForm.java +++ b/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyConfigForm.java @@ -9,7 +9,7 @@ import java.awt.event.*; import javax.swing.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.swing.*; diff --git a/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyPluginActivator.java b/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyPluginActivator.java index e665bb524..73bd752f8 100644 --- a/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyPluginActivator.java +++ b/src/net/java/sip/communicator/plugin/globalproxyconfig/GlobalProxyPluginActivator.java @@ -9,7 +9,7 @@ import java.net.*; import java.util.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; diff --git a/src/net/java/sip/communicator/plugin/globalproxyconfig/Resources.java b/src/net/java/sip/communicator/plugin/globalproxyconfig/Resources.java index ae6660855..ca301e7bf 100644 --- a/src/net/java/sip/communicator/plugin/globalproxyconfig/Resources.java +++ b/src/net/java/sip/communicator/plugin/globalproxyconfig/Resources.java @@ -7,8 +7,7 @@ package net.java.sip.communicator.plugin.globalproxyconfig; -import net.java.sip.communicator.service.resources.*; - +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/globalproxyconfig/globalproxyconfig.manifest.mf b/src/net/java/sip/communicator/plugin/globalproxyconfig/globalproxyconfig.manifest.mf index fae4f8d47..58d2153bc 100644 --- a/src/net/java/sip/communicator/plugin/globalproxyconfig/globalproxyconfig.manifest.mf +++ b/src/net/java/sip/communicator/plugin/globalproxyconfig/globalproxyconfig.manifest.mf @@ -9,8 +9,8 @@ Import-Package: org.osgi.framework, net.java.sip.communicator.util.swing, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.protocol, - net.java.sip.communicator.service.resources, - net.java.sip.communicator.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, javax.swing, javax.swing.event, javax.swing.table, diff --git a/src/net/java/sip/communicator/plugin/googletalkaccregwizz/GoogleTalkAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/googletalkaccregwizz/GoogleTalkAccRegWizzActivator.java index ed93d89e0..f7bbe2b64 100644 --- a/src/net/java/sip/communicator/plugin/googletalkaccregwizz/GoogleTalkAccRegWizzActivator.java +++ b/src/net/java/sip/communicator/plugin/googletalkaccregwizz/GoogleTalkAccRegWizzActivator.java @@ -8,14 +8,15 @@ import java.util.*; -import org.osgi.framework.*; - import net.java.sip.communicator.service.browserlauncher.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; +import org.osgi.framework.*; + /** * Registers the GoogleTalkAccountRegistrationWizard in the UI Service. * diff --git a/src/net/java/sip/communicator/plugin/googletalkaccregwizz/googletalkaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/googletalkaccregwizz/googletalkaccregwizz.manifest.mf index c63b034a2..248077b79 100644 --- a/src/net/java/sip/communicator/plugin/googletalkaccregwizz/googletalkaccregwizz.manifest.mf +++ b/src/net/java/sip/communicator/plugin/googletalkaccregwizz/googletalkaccregwizz.manifest.mf @@ -6,16 +6,16 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, - net.java.sip.communicator.service.fileaccess, + org.jitsi.service.fileaccess, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.protocol.icqconstants, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, net.java.sip.communicator.plugin.jabberaccregwizz, diff --git a/src/net/java/sip/communicator/plugin/icqaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/icqaccregwizz/Resources.java index 28a3c9308..a6909a17b 100644 --- a/src/net/java/sip/communicator/plugin/icqaccregwizz/Resources.java +++ b/src/net/java/sip/communicator/plugin/icqaccregwizz/Resources.java @@ -8,6 +8,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the image resources used in this plugin. diff --git a/src/net/java/sip/communicator/plugin/icqaccregwizz/icqaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/icqaccregwizz/icqaccregwizz.manifest.mf index d6d635848..d22b94be1 100644 --- a/src/net/java/sip/communicator/plugin/icqaccregwizz/icqaccregwizz.manifest.mf +++ b/src/net/java/sip/communicator/plugin/icqaccregwizz/icqaccregwizz.manifest.mf @@ -6,7 +6,7 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, net.java.sip.communicator.service.gui, @@ -14,7 +14,7 @@ Import-Package: org.osgi.framework, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.protocol.icqconstants, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/ippiaccregwizz/IppiAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/ippiaccregwizz/IppiAccRegWizzActivator.java index fde883d28..2a559aad7 100644 --- a/src/net/java/sip/communicator/plugin/ippiaccregwizz/IppiAccRegWizzActivator.java +++ b/src/net/java/sip/communicator/plugin/ippiaccregwizz/IppiAccRegWizzActivator.java @@ -8,13 +8,14 @@ import java.util.*; -import org.osgi.framework.*; - import net.java.sip.communicator.service.browserlauncher.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; +import org.osgi.framework.*; + /** * Registers the IppiAccountRegistrationWizard in the UI Service. * diff --git a/src/net/java/sip/communicator/plugin/ippiaccregwizz/ippiaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/ippiaccregwizz/ippiaccregwizz.manifest.mf index 42ed35a61..34479665d 100644 --- a/src/net/java/sip/communicator/plugin/ippiaccregwizz/ippiaccregwizz.manifest.mf +++ b/src/net/java/sip/communicator/plugin/ippiaccregwizz/ippiaccregwizz.manifest.mf @@ -6,16 +6,16 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, - net.java.sip.communicator.service.fileaccess, + org.jitsi.service.fileaccess, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.protocol.icqconstants, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, net.java.sip.communicator.plugin.sipaccregwizz, diff --git a/src/net/java/sip/communicator/plugin/iptelaccregwizz/IptelAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/iptelaccregwizz/IptelAccRegWizzActivator.java index eaa411747..dda76d2f0 100644 --- a/src/net/java/sip/communicator/plugin/iptelaccregwizz/IptelAccRegWizzActivator.java +++ b/src/net/java/sip/communicator/plugin/iptelaccregwizz/IptelAccRegWizzActivator.java @@ -8,14 +8,15 @@ import java.util.*; -import org.osgi.framework.*; - import net.java.sip.communicator.service.browserlauncher.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; +import org.osgi.framework.*; + /** * Registers the GoogleTalkAccountRegistrationWizard in the UI Service. * diff --git a/src/net/java/sip/communicator/plugin/iptelaccregwizz/iptelaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/iptelaccregwizz/iptelaccregwizz.manifest.mf index bb42ab481..03df9d7ca 100644 --- a/src/net/java/sip/communicator/plugin/iptelaccregwizz/iptelaccregwizz.manifest.mf +++ b/src/net/java/sip/communicator/plugin/iptelaccregwizz/iptelaccregwizz.manifest.mf @@ -6,16 +6,16 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, - net.java.sip.communicator.service.fileaccess, + org.jitsi.service.fileaccess, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.protocol.icqconstants, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, net.java.sip.communicator.plugin.sipaccregwizz, diff --git a/src/net/java/sip/communicator/plugin/ircaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/ircaccregwizz/Resources.java index 110f157f2..a9a588649 100644 --- a/src/net/java/sip/communicator/plugin/ircaccregwizz/Resources.java +++ b/src/net/java/sip/communicator/plugin/ircaccregwizz/Resources.java @@ -8,6 +8,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Messages class manages the access to the internationalization * properties files. diff --git a/src/net/java/sip/communicator/plugin/ircaccregwizz/ircaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/ircaccregwizz/ircaccregwizz.manifest.mf index ccc4971b5..5731d33ce 100644 --- a/src/net/java/sip/communicator/plugin/ircaccregwizz/ircaccregwizz.manifest.mf +++ b/src/net/java/sip/communicator/plugin/ircaccregwizz/ircaccregwizz.manifest.mf @@ -6,12 +6,12 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccRegWizzActivator.java index cd567cdc3..d9d03be82 100644 --- a/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccRegWizzActivator.java +++ b/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccRegWizzActivator.java @@ -11,7 +11,7 @@ import org.osgi.framework.*; import net.java.sip.communicator.service.browserlauncher.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.credentialsstorage.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; diff --git a/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistration.java b/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistration.java index 4e579b44a..799eff394 100755 --- a/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistration.java +++ b/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistration.java @@ -816,4 +816,4 @@ public void setDefaultDTMFMethod(String defaultDTMFMethod) { this.defaultDTMFMethod = defaultDTMFMethod; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistrationWizard.java b/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistrationWizard.java index 5c6a58b7d..eec4b284a 100644 --- a/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistrationWizard.java +++ b/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistrationWizard.java @@ -729,4 +729,4 @@ protected String getHomeLinkLabel() { return null; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberServerChooserDialog.java b/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberServerChooserDialog.java index c89322330..079fc7661 100644 --- a/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberServerChooserDialog.java +++ b/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberServerChooserDialog.java @@ -19,10 +19,10 @@ import javax.swing.table.*; import javax.xml.parsers.*; -import net.java.sip.communicator.service.fileaccess.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.fileaccess.*; import org.osgi.framework.*; import org.w3c.dom.*; import org.xml.sax.*; diff --git a/src/net/java/sip/communicator/plugin/jabberaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/jabberaccregwizz/Resources.java index 7ede295d4..7e241d2f1 100644 --- a/src/net/java/sip/communicator/plugin/jabberaccregwizz/Resources.java +++ b/src/net/java/sip/communicator/plugin/jabberaccregwizz/Resources.java @@ -10,6 +10,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the image resources used in this plugin. diff --git a/src/net/java/sip/communicator/plugin/jabberaccregwizz/jabberaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/jabberaccregwizz/jabberaccregwizz.manifest.mf index 4a06c859c..184dd65eb 100755 --- a/src/net/java/sip/communicator/plugin/jabberaccregwizz/jabberaccregwizz.manifest.mf +++ b/src/net/java/sip/communicator/plugin/jabberaccregwizz/jabberaccregwizz.manifest.mf @@ -7,17 +7,17 @@ System-Bundle: yes Export-package: net.java.sip.communicator.plugin.jabberaccregwizz Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.credentialsstorage, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, - net.java.sip.communicator.service.fileaccess, + org.jitsi.service.fileaccess, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.protocol.icqconstants, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.naming, diff --git a/src/net/java/sip/communicator/plugin/keybindingchooser/KeybindingChooserActivator.java b/src/net/java/sip/communicator/plugin/keybindingchooser/KeybindingChooserActivator.java index 1fc6ab0af..77e0a993f 100644 --- a/src/net/java/sip/communicator/plugin/keybindingchooser/KeybindingChooserActivator.java +++ b/src/net/java/sip/communicator/plugin/keybindingchooser/KeybindingChooserActivator.java @@ -8,13 +8,14 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.globalshortcut.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.keybindings.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/keybindingchooser/globalchooser/GlobalShortcutDialog.java b/src/net/java/sip/communicator/plugin/keybindingchooser/globalchooser/GlobalShortcutDialog.java index 2c862deac..68f9ef561 100644 --- a/src/net/java/sip/communicator/plugin/keybindingchooser/globalchooser/GlobalShortcutDialog.java +++ b/src/net/java/sip/communicator/plugin/keybindingchooser/globalchooser/GlobalShortcutDialog.java @@ -9,17 +9,19 @@ import java.awt.*; import java.awt.event.*; import java.util.*; -import java.util.List; // disambiguation +import java.util.List; import javax.swing.*; import net.java.sip.communicator.plugin.keybindingchooser.*; import net.java.sip.communicator.service.globalshortcut.*; -import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.skin.*; import net.java.sip.communicator.util.swing.*; import net.java.sip.communicator.util.swing.plaf.*; +import org.jitsi.util.*; +// disambiguation + /** * Dialog to choose the shortcut. * diff --git a/src/net/java/sip/communicator/plugin/keybindingchooser/keybindingChooser.manifest.mf b/src/net/java/sip/communicator/plugin/keybindingchooser/keybindingChooser.manifest.mf index 26c565894..780e86026 100644 --- a/src/net/java/sip/communicator/plugin/keybindingchooser/keybindingChooser.manifest.mf +++ b/src/net/java/sip/communicator/plugin/keybindingchooser/keybindingChooser.manifest.mf @@ -7,9 +7,10 @@ System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.keybindings, - net.java.sip.communicator.service.resources, - net.java.sip.communicator.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, net.java.sip.communicator.service.globalshortcut, + org.jitsi.util, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, net.java.sip.communicator.util.swing.plaf, diff --git a/src/net/java/sip/communicator/plugin/ldap/LdapActivator.java b/src/net/java/sip/communicator/plugin/ldap/LdapActivator.java index 99414a0bb..2baaa19cb 100644 --- a/src/net/java/sip/communicator/plugin/ldap/LdapActivator.java +++ b/src/net/java/sip/communicator/plugin/ldap/LdapActivator.java @@ -10,9 +10,9 @@ import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.ldap.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/ldap/ldap.manifest.mf b/src/net/java/sip/communicator/plugin/ldap/ldap.manifest.mf index a6a00ba60..a418501c6 100644 --- a/src/net/java/sip/communicator/plugin/ldap/ldap.manifest.mf +++ b/src/net/java/sip/communicator/plugin/ldap/ldap.manifest.mf @@ -4,7 +4,7 @@ Bundle-Name: LDAP support Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 Import-Package: net.java.sip.communicator.service.contactsource, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.ldap, @@ -18,4 +18,4 @@ Import-Package: net.java.sip.communicator.service.contactsource, javax.swing.tree, javax.swing.text, org.osgi.framework -System-Bundle: yes \ No newline at end of file +System-Bundle: yes diff --git a/src/net/java/sip/communicator/plugin/loggingutils/LoggingConfigForm.java b/src/net/java/sip/communicator/plugin/loggingutils/LoggingConfigForm.java index 0bb08392b..7af0bdd77 100644 --- a/src/net/java/sip/communicator/plugin/loggingutils/LoggingConfigForm.java +++ b/src/net/java/sip/communicator/plugin/loggingutils/LoggingConfigForm.java @@ -5,19 +5,21 @@ */ package net.java.sip.communicator.plugin.loggingutils; +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.util.*; + +import javax.swing.*; +import javax.swing.event.*; + import net.java.sip.communicator.service.httputil.*; import net.java.sip.communicator.service.notification.*; -import net.java.sip.communicator.service.packetlogging.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; -import javax.swing.*; -import javax.swing.event.*; -import java.awt.*; -import java.awt.event.*; -import java.io.*; -import java.util.*; +import org.jitsi.service.packetlogging.*; +import org.jitsi.service.resources.*; /** * The Logging configuration form. diff --git a/src/net/java/sip/communicator/plugin/loggingutils/LoggingUtilsActivator.java b/src/net/java/sip/communicator/plugin/loggingutils/LoggingUtilsActivator.java index a6d531fea..075111fbd 100644 --- a/src/net/java/sip/communicator/plugin/loggingutils/LoggingUtilsActivator.java +++ b/src/net/java/sip/communicator/plugin/loggingutils/LoggingUtilsActivator.java @@ -6,16 +6,17 @@ */ package net.java.sip.communicator.plugin.loggingutils; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.fileaccess.*; +import java.util.*; + import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.notification.*; -import net.java.sip.communicator.service.packetlogging.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; -import org.osgi.framework.*; -import java.util.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.fileaccess.*; +import org.jitsi.service.packetlogging.*; +import org.jitsi.service.resources.*; +import org.osgi.framework.*; /** * Creates and registers logging config form. diff --git a/src/net/java/sip/communicator/plugin/loggingutils/LogsCollector.java b/src/net/java/sip/communicator/plugin/loggingutils/LogsCollector.java index cb0b3d8f8..d88ffd0ae 100644 --- a/src/net/java/sip/communicator/plugin/loggingutils/LogsCollector.java +++ b/src/net/java/sip/communicator/plugin/loggingutils/LogsCollector.java @@ -5,14 +5,16 @@ */ package net.java.sip.communicator.plugin.loggingutils; -import net.java.sip.communicator.util.*; - import java.io.*; import java.text.*; import java.util.*; import java.util.regex.*; import java.util.zip.*; +import net.java.sip.communicator.util.Logger; + +import org.jitsi.util.*; + /** * Collects logs and save them in compressed zip file. * @author Damian Minkov diff --git a/src/net/java/sip/communicator/plugin/loggingutils/loggingutils.manifest.mf b/src/net/java/sip/communicator/plugin/loggingutils/loggingutils.manifest.mf index 284b59689..44d864f6e 100644 --- a/src/net/java/sip/communicator/plugin/loggingutils/loggingutils.manifest.mf +++ b/src/net/java/sip/communicator/plugin/loggingutils/loggingutils.manifest.mf @@ -5,13 +5,14 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.fileaccess, + org.jitsi.service.configuration, + org.jitsi.service.fileaccess, + org.jitsi.util, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.httputil, net.java.sip.communicator.service.notification, - net.java.sip.communicator.service.packetlogging, - net.java.sip.communicator.service.resources, + org.jitsi.service.packetlogging, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.net.ssl, diff --git a/src/net/java/sip/communicator/plugin/msnaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/msnaccregwizz/Resources.java index 250af24c3..5c01e8824 100644 --- a/src/net/java/sip/communicator/plugin/msnaccregwizz/Resources.java +++ b/src/net/java/sip/communicator/plugin/msnaccregwizz/Resources.java @@ -8,6 +8,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the image resources used in this plugin. diff --git a/src/net/java/sip/communicator/plugin/msnaccregwizz/msnaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/msnaccregwizz/msnaccregwizz.manifest.mf index c151aecbb..c18c354e8 100755 --- a/src/net/java/sip/communicator/plugin/msnaccregwizz/msnaccregwizz.manifest.mf +++ b/src/net/java/sip/communicator/plugin/msnaccregwizz/msnaccregwizz.manifest.mf @@ -6,7 +6,7 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, net.java.sip.communicator.service.gui, @@ -14,7 +14,7 @@ Import-Package: org.osgi.framework, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.protocol.icqconstants, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/msofficecomm/MsOfficeCommActivator.java b/src/net/java/sip/communicator/plugin/msofficecomm/MsOfficeCommActivator.java index e59f10a49..6b8af557f 100644 --- a/src/net/java/sip/communicator/plugin/msofficecomm/MsOfficeCommActivator.java +++ b/src/net/java/sip/communicator/plugin/msofficecomm/MsOfficeCommActivator.java @@ -6,8 +6,7 @@ */ package net.java.sip.communicator.plugin.msofficecomm; -import net.java.sip.communicator.util.*; - +import org.jitsi.util.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/msofficecomm/msofficecomm.manifest.mf b/src/net/java/sip/communicator/plugin/msofficecomm/msofficecomm.manifest.mf index 96421c21b..2e8b5042d 100644 --- a/src/net/java/sip/communicator/plugin/msofficecomm/msofficecomm.manifest.mf +++ b/src/net/java/sip/communicator/plugin/msofficecomm/msofficecomm.manifest.mf @@ -12,4 +12,5 @@ Import-Package: javax.swing, net.java.sip.communicator.service.protocol.msnconstants, net.java.sip.communicator.service.protocol.yahooconstants, net.java.sip.communicator.util, + org.jitsi.util, org.osgi.framework diff --git a/src/net/java/sip/communicator/plugin/notificationconfiguration/NotificationConfigurationActivator.java b/src/net/java/sip/communicator/plugin/notificationconfiguration/NotificationConfigurationActivator.java index 38e8765ef..262829ccb 100644 --- a/src/net/java/sip/communicator/plugin/notificationconfiguration/NotificationConfigurationActivator.java +++ b/src/net/java/sip/communicator/plugin/notificationconfiguration/NotificationConfigurationActivator.java @@ -8,12 +8,12 @@ import java.util.*; -import net.java.sip.communicator.service.audionotifier.*; -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.notification.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.audionotifier.*; +import org.jitsi.service.configuration.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/notificationconfiguration/NotificationConfigurationPanel.java b/src/net/java/sip/communicator/plugin/notificationconfiguration/NotificationConfigurationPanel.java index b5cc785a5..b561da00c 100644 --- a/src/net/java/sip/communicator/plugin/notificationconfiguration/NotificationConfigurationPanel.java +++ b/src/net/java/sip/communicator/plugin/notificationconfiguration/NotificationConfigurationPanel.java @@ -14,11 +14,13 @@ import javax.swing.*; import javax.swing.event.*; -import net.java.sip.communicator.service.audionotifier.*; import net.java.sip.communicator.service.notification.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.audionotifier.*; +import org.jitsi.util.*; + /** * The UI of ConfigurationForm that would be added in the user * interface configuration window. It contains a list of all installed diff --git a/src/net/java/sip/communicator/plugin/notificationconfiguration/Resources.java b/src/net/java/sip/communicator/plugin/notificationconfiguration/Resources.java index 035499611..8e2d3fdb9 100644 --- a/src/net/java/sip/communicator/plugin/notificationconfiguration/Resources.java +++ b/src/net/java/sip/communicator/plugin/notificationconfiguration/Resources.java @@ -10,6 +10,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Messages class manages the access to the internationalization * properties files. diff --git a/src/net/java/sip/communicator/plugin/notificationconfiguration/SoundFilter.java b/src/net/java/sip/communicator/plugin/notificationconfiguration/SoundFilter.java index 83c7e90f8..9604b1b3a 100644 --- a/src/net/java/sip/communicator/plugin/notificationconfiguration/SoundFilter.java +++ b/src/net/java/sip/communicator/plugin/notificationconfiguration/SoundFilter.java @@ -9,9 +9,10 @@ import java.io.*; -import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.util.*; + /** * Filter to display only the sound files in the filechooser. * diff --git a/src/net/java/sip/communicator/plugin/notificationconfiguration/notificationconfiguration.manifest.mf b/src/net/java/sip/communicator/plugin/notificationconfiguration/notificationconfiguration.manifest.mf index 2f0b01f55..0e9d8c2bf 100644 --- a/src/net/java/sip/communicator/plugin/notificationconfiguration/notificationconfiguration.manifest.mf +++ b/src/net/java/sip/communicator/plugin/notificationconfiguration/notificationconfiguration.manifest.mf @@ -5,13 +5,13 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.audionotifier, - net.java.sip.communicator.service.configuration, + org.jitsi.service.audionotifier, + org.jitsi.service.configuration, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.notification, net.java.sip.communicator.service.notification.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/notificationwiring/NotificationManager.java b/src/net/java/sip/communicator/plugin/notificationwiring/NotificationManager.java index 3c3d8d0ce..53526f6a1 100644 --- a/src/net/java/sip/communicator/plugin/notificationwiring/NotificationManager.java +++ b/src/net/java/sip/communicator/plugin/notificationwiring/NotificationManager.java @@ -6,20 +6,23 @@ */ package net.java.sip.communicator.plugin.notificationwiring; +import java.awt.image.*; +import java.net.*; +import java.util.*; + +import javax.imageio.*; + import net.java.sip.communicator.service.contactlist.*; import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.notification.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; -import org.osgi.framework.*; -import javax.imageio.*; -import java.awt.image.*; -import java.net.*; -import java.util.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.protocol.event.*; +import org.osgi.framework.*; /** * Listens for all kinds of events and triggers when needed a notification, diff --git a/src/net/java/sip/communicator/plugin/notificationwiring/NotificationWiringActivator.java b/src/net/java/sip/communicator/plugin/notificationwiring/NotificationWiringActivator.java index a4ee0ba20..cbde8d0cd 100644 --- a/src/net/java/sip/communicator/plugin/notificationwiring/NotificationWiringActivator.java +++ b/src/net/java/sip/communicator/plugin/notificationwiring/NotificationWiringActivator.java @@ -7,11 +7,11 @@ package net.java.sip.communicator.plugin.notificationwiring; import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.notification.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/notificationwiring/SoundProperties.java b/src/net/java/sip/communicator/plugin/notificationwiring/SoundProperties.java index 73b3b9bfc..3d411a443 100644 --- a/src/net/java/sip/communicator/plugin/notificationwiring/SoundProperties.java +++ b/src/net/java/sip/communicator/plugin/notificationwiring/SoundProperties.java @@ -6,7 +6,7 @@ */ package net.java.sip.communicator.plugin.notificationwiring; -import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; /** * Manages the access to the properties file containing all sounds paths. diff --git a/src/net/java/sip/communicator/plugin/notificationwiring/notificationwiring.manifest.mf b/src/net/java/sip/communicator/plugin/notificationwiring/notificationwiring.manifest.mf index 0ad7d4491..a94675d55 100644 --- a/src/net/java/sip/communicator/plugin/notificationwiring/notificationwiring.manifest.mf +++ b/src/net/java/sip/communicator/plugin/notificationwiring/notificationwiring.manifest.mf @@ -9,8 +9,8 @@ Import-Package: org.osgi.framework, net.java.sip.communicator.util, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.gui, - net.java.sip.communicator.service.neomedia, + org.jitsi.service.neomedia, net.java.sip.communicator.service.notification, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.resources + org.jitsi.service.resources, net.java.sip.communicator.service.resources diff --git a/src/net/java/sip/communicator/plugin/otr/OtrActionHandlers.java b/src/net/java/sip/communicator/plugin/otr/OtrActionHandlers.java index e4cd81fc8..ede2733b5 100644 --- a/src/net/java/sip/communicator/plugin/otr/OtrActionHandlers.java +++ b/src/net/java/sip/communicator/plugin/otr/OtrActionHandlers.java @@ -33,4 +33,4 @@ static void openAuthDialog(Contact contact) - authenticateBuddyDialog.getHeight() / 2); authenticateBuddyDialog.setVisible(true); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/otr/OtrActivator.java b/src/net/java/sip/communicator/plugin/otr/OtrActivator.java index bcd8a184f..643399909 100644 --- a/src/net/java/sip/communicator/plugin/otr/OtrActivator.java +++ b/src/net/java/sip/communicator/plugin/otr/OtrActivator.java @@ -8,12 +8,13 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/otr/OtrConfigurationPanel.java b/src/net/java/sip/communicator/plugin/otr/OtrConfigurationPanel.java index fab645566..59fd25a9d 100644 --- a/src/net/java/sip/communicator/plugin/otr/OtrConfigurationPanel.java +++ b/src/net/java/sip/communicator/plugin/otr/OtrConfigurationPanel.java @@ -353,4 +353,4 @@ private void initComponents() c.gridy = 2; this.add(pnlPolicy, c); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/otr/OtrConfigurator.java b/src/net/java/sip/communicator/plugin/otr/OtrConfigurator.java index 5b787a9de..9eeeb69ba 100755 --- a/src/net/java/sip/communicator/plugin/otr/OtrConfigurator.java +++ b/src/net/java/sip/communicator/plugin/otr/OtrConfigurator.java @@ -6,7 +6,7 @@ */ package net.java.sip.communicator.plugin.otr; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import org.bouncycastle.util.encoders.*; diff --git a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java index 246fc1b3f..f1d3dcff0 100755 --- a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java +++ b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java @@ -40,4 +40,4 @@ public interface ScOtrKeyManager public abstract void generateKeyPair(AccountID accountID); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/otr/otr.manifest.mf b/src/net/java/sip/communicator/plugin/otr/otr.manifest.mf index 24aabd876..c8296e598 100644 --- a/src/net/java/sip/communicator/plugin/otr/otr.manifest.mf +++ b/src/net/java/sip/communicator/plugin/otr/otr.manifest.mf @@ -6,12 +6,12 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.imageio, diff --git a/src/net/java/sip/communicator/plugin/pluginmanager/PluginManagerActivator.java b/src/net/java/sip/communicator/plugin/pluginmanager/PluginManagerActivator.java index 5ef6833d7..8c602f9e8 100644 --- a/src/net/java/sip/communicator/plugin/pluginmanager/PluginManagerActivator.java +++ b/src/net/java/sip/communicator/plugin/pluginmanager/PluginManagerActivator.java @@ -7,7 +7,7 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.gui.*; import org.osgi.framework.*; diff --git a/src/net/java/sip/communicator/plugin/pluginmanager/Resources.java b/src/net/java/sip/communicator/plugin/pluginmanager/Resources.java index d14698634..8d4e93cff 100644 --- a/src/net/java/sip/communicator/plugin/pluginmanager/Resources.java +++ b/src/net/java/sip/communicator/plugin/pluginmanager/Resources.java @@ -8,6 +8,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the image resources used in this plugin. diff --git a/src/net/java/sip/communicator/plugin/pluginmanager/pluginmanager.manifest.mf b/src/net/java/sip/communicator/plugin/pluginmanager/pluginmanager.manifest.mf index 71cd57e74..2b2d31ba6 100644 --- a/src/net/java/sip/communicator/plugin/pluginmanager/pluginmanager.manifest.mf +++ b/src/net/java/sip/communicator/plugin/pluginmanager/pluginmanager.manifest.mf @@ -5,10 +5,10 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/profiler4j/Resources.java b/src/net/java/sip/communicator/plugin/profiler4j/Resources.java index 82e9d809e..a995ea757 100644 --- a/src/net/java/sip/communicator/plugin/profiler4j/Resources.java +++ b/src/net/java/sip/communicator/plugin/profiler4j/Resources.java @@ -8,6 +8,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Messages class manages the access to the internationalization properties * files. diff --git a/src/net/java/sip/communicator/plugin/profiler4j/profiler4j.manifest.mf b/src/net/java/sip/communicator/plugin/profiler4j/profiler4j.manifest.mf index b817d4594..c956cc65d 100644 --- a/src/net/java/sip/communicator/plugin/profiler4j/profiler4j.manifest.mf +++ b/src/net/java/sip/communicator/plugin/profiler4j/profiler4j.manifest.mf @@ -11,7 +11,7 @@ Import-Package: org.apache.commons.logging, org.xml.sax.helpers, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.gui, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.service.protocol, net.java.sip.communicator.util, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/provisioning/ProvisioningActivator.java b/src/net/java/sip/communicator/plugin/provisioning/ProvisioningActivator.java index bd081a835..9da4a694f 100644 --- a/src/net/java/sip/communicator/plugin/provisioning/ProvisioningActivator.java +++ b/src/net/java/sip/communicator/plugin/provisioning/ProvisioningActivator.java @@ -8,15 +8,15 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.credentialsstorage.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.netaddr.*; import net.java.sip.communicator.service.provdisc.*; import net.java.sip.communicator.service.provisioning.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/provisioning/ProvisioningForm.java b/src/net/java/sip/communicator/plugin/provisioning/ProvisioningForm.java index 151a11915..636cf758b 100644 --- a/src/net/java/sip/communicator/plugin/provisioning/ProvisioningForm.java +++ b/src/net/java/sip/communicator/plugin/provisioning/ProvisioningForm.java @@ -13,11 +13,12 @@ import javax.swing.*; import javax.swing.event.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; + /** * * @author Yana Stamcheva diff --git a/src/net/java/sip/communicator/plugin/provisioning/ProvisioningServiceImpl.java b/src/net/java/sip/communicator/plugin/provisioning/ProvisioningServiceImpl.java index 8a63586ce..89e2fce94 100644 --- a/src/net/java/sip/communicator/plugin/provisioning/ProvisioningServiceImpl.java +++ b/src/net/java/sip/communicator/plugin/provisioning/ProvisioningServiceImpl.java @@ -8,7 +8,7 @@ import javax.swing.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.httputil.*; import net.java.sip.communicator.service.provisioning.*; import net.java.sip.communicator.util.*; diff --git a/src/net/java/sip/communicator/plugin/provisioning/provisioning.manifest.mf b/src/net/java/sip/communicator/plugin/provisioning/provisioning.manifest.mf index 8b9305b85..ee967c133 100644 --- a/src/net/java/sip/communicator/plugin/provisioning/provisioning.manifest.mf +++ b/src/net/java/sip/communicator/plugin/provisioning/provisioning.manifest.mf @@ -5,11 +5,11 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.httputil, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.service.provdisc, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.netaddr, diff --git a/src/net/java/sip/communicator/plugin/reconnectplugin/ReconnectPluginActivator.java b/src/net/java/sip/communicator/plugin/reconnectplugin/ReconnectPluginActivator.java index 3fa83c11d..db24090da 100644 --- a/src/net/java/sip/communicator/plugin/reconnectplugin/ReconnectPluginActivator.java +++ b/src/net/java/sip/communicator/plugin/reconnectplugin/ReconnectPluginActivator.java @@ -8,16 +8,16 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.netaddr.*; import net.java.sip.communicator.service.netaddr.event.*; import net.java.sip.communicator.service.notification.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/reconnectplugin/reconnectplugin.manifest.mf b/src/net/java/sip/communicator/plugin/reconnectplugin/reconnectplugin.manifest.mf index a2b463fc1..9163cb26b 100644 --- a/src/net/java/sip/communicator/plugin/reconnectplugin/reconnectplugin.manifest.mf +++ b/src/net/java/sip/communicator/plugin/reconnectplugin/reconnectplugin.manifest.mf @@ -7,11 +7,11 @@ System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.netaddr, net.java.sip.communicator.service.netaddr.event, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.notification, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, - net.java.sip.communicator.util.swing \ No newline at end of file + net.java.sip.communicator.util.swing diff --git a/src/net/java/sip/communicator/plugin/rssaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/rssaccregwizz/Resources.java index 371faacd8..fedca1076 100644 --- a/src/net/java/sip/communicator/plugin/rssaccregwizz/Resources.java +++ b/src/net/java/sip/communicator/plugin/rssaccregwizz/Resources.java @@ -8,6 +8,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the image resources used in this plugin. diff --git a/src/net/java/sip/communicator/plugin/rssaccregwizz/rssaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/rssaccregwizz/rssaccregwizz.manifest.mf index 60c642952..81e2df7b2 100644 --- a/src/net/java/sip/communicator/plugin/rssaccregwizz/rssaccregwizz.manifest.mf +++ b/src/net/java/sip/communicator/plugin/rssaccregwizz/rssaccregwizz.manifest.mf @@ -6,14 +6,14 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/securityconfig/SecurityConfigActivator.java b/src/net/java/sip/communicator/plugin/securityconfig/SecurityConfigActivator.java index 6842b9e60..5a90a92db 100644 --- a/src/net/java/sip/communicator/plugin/securityconfig/SecurityConfigActivator.java +++ b/src/net/java/sip/communicator/plugin/securityconfig/SecurityConfigActivator.java @@ -7,13 +7,14 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.credentialsstorage.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/securityconfig/SecurityConfigurationPanel.java b/src/net/java/sip/communicator/plugin/securityconfig/SecurityConfigurationPanel.java index 50a1bd283..c60d871fd 100644 --- a/src/net/java/sip/communicator/plugin/securityconfig/SecurityConfigurationPanel.java +++ b/src/net/java/sip/communicator/plugin/securityconfig/SecurityConfigurationPanel.java @@ -131,4 +131,4 @@ private void addConfigForm(ConfigurationForm form) formTitle, cIndex); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/securityconfig/masterpassword/MasterPasswordChangeDialog.java b/src/net/java/sip/communicator/plugin/securityconfig/masterpassword/MasterPasswordChangeDialog.java index 333eb2b22..24ce6f772 100644 --- a/src/net/java/sip/communicator/plugin/securityconfig/masterpassword/MasterPasswordChangeDialog.java +++ b/src/net/java/sip/communicator/plugin/securityconfig/masterpassword/MasterPasswordChangeDialog.java @@ -15,9 +15,10 @@ import net.java.sip.communicator.plugin.securityconfig.*; import net.java.sip.communicator.service.credentialsstorage.*; import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; + /** * UI dialog to change the master password. * diff --git a/src/net/java/sip/communicator/plugin/securityconfig/masterpassword/MasterPasswordPanel.java b/src/net/java/sip/communicator/plugin/securityconfig/masterpassword/MasterPasswordPanel.java index 598888e91..7e85595db 100644 --- a/src/net/java/sip/communicator/plugin/securityconfig/masterpassword/MasterPasswordPanel.java +++ b/src/net/java/sip/communicator/plugin/securityconfig/masterpassword/MasterPasswordPanel.java @@ -12,12 +12,13 @@ import javax.swing.*; import net.java.sip.communicator.plugin.securityconfig.*; -import net.java.sip.communicator.plugin.securityconfig.masterpassword.MasterPasswordChangeDialog.*; +import net.java.sip.communicator.plugin.securityconfig.masterpassword.MasterPasswordChangeDialog.MasterPasswordExecutable; import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; + /** * Panel containing the master password checkbox and change button. * diff --git a/src/net/java/sip/communicator/plugin/securityconfig/masterpassword/SavedPasswordsDialog.java b/src/net/java/sip/communicator/plugin/securityconfig/masterpassword/SavedPasswordsDialog.java index 495f9b43a..4f8813eeb 100644 --- a/src/net/java/sip/communicator/plugin/securityconfig/masterpassword/SavedPasswordsDialog.java +++ b/src/net/java/sip/communicator/plugin/securityconfig/masterpassword/SavedPasswordsDialog.java @@ -9,7 +9,7 @@ import java.awt.*; import java.awt.event.*; import java.util.*; -import java.util.List; // disambiguation +import java.util.List; import javax.swing.*; import javax.swing.border.*; @@ -17,13 +17,15 @@ import javax.swing.table.*; import net.java.sip.communicator.plugin.securityconfig.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.credentialsstorage.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; +// disambiguation + /** * The dialog that displays all saved account passwords. * diff --git a/src/net/java/sip/communicator/plugin/securityconfig/securityconfig.manifest.mf b/src/net/java/sip/communicator/plugin/securityconfig/securityconfig.manifest.mf index 1fb372ef9..261175b10 100644 --- a/src/net/java/sip/communicator/plugin/securityconfig/securityconfig.manifest.mf +++ b/src/net/java/sip/communicator/plugin/securityconfig/securityconfig.manifest.mf @@ -5,13 +5,13 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.credentialsstorage, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, gnu.java.zrtp, diff --git a/src/net/java/sip/communicator/plugin/simpleaccreg/InitialAccountRegistrationFrame.java b/src/net/java/sip/communicator/plugin/simpleaccreg/InitialAccountRegistrationFrame.java index 98937375a..a433adabb 100644 --- a/src/net/java/sip/communicator/plugin/simpleaccreg/InitialAccountRegistrationFrame.java +++ b/src/net/java/sip/communicator/plugin/simpleaccreg/InitialAccountRegistrationFrame.java @@ -15,7 +15,7 @@ import javax.swing.*; import javax.swing.text.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.contactlist.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; diff --git a/src/net/java/sip/communicator/plugin/simpleaccreg/Resources.java b/src/net/java/sip/communicator/plugin/simpleaccreg/Resources.java index 663aab359..4b614dd2b 100644 --- a/src/net/java/sip/communicator/plugin/simpleaccreg/Resources.java +++ b/src/net/java/sip/communicator/plugin/simpleaccreg/Resources.java @@ -7,8 +7,11 @@ package net.java.sip.communicator.plugin.simpleaccreg; import javax.swing.*; + import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the image resources used in this plugin. diff --git a/src/net/java/sip/communicator/plugin/simpleaccreg/SimpleAccountRegistrationActivator.java b/src/net/java/sip/communicator/plugin/simpleaccreg/SimpleAccountRegistrationActivator.java index 17bc36531..0d627e8ac 100644 --- a/src/net/java/sip/communicator/plugin/simpleaccreg/SimpleAccountRegistrationActivator.java +++ b/src/net/java/sip/communicator/plugin/simpleaccreg/SimpleAccountRegistrationActivator.java @@ -9,13 +9,13 @@ import java.awt.*; import java.util.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.contactlist.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/simpleaccreg/simpleaccreg.manifest.mf b/src/net/java/sip/communicator/plugin/simpleaccreg/simpleaccreg.manifest.mf index 242e94f5d..791a58659 100644 --- a/src/net/java/sip/communicator/plugin/simpleaccreg/simpleaccreg.manifest.mf +++ b/src/net/java/sip/communicator/plugin/simpleaccreg/simpleaccreg.manifest.mf @@ -6,14 +6,14 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/Sip2SipAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/Sip2SipAccRegWizzActivator.java index be62d3718..84ce64ea9 100644 --- a/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/Sip2SipAccRegWizzActivator.java +++ b/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/Sip2SipAccRegWizzActivator.java @@ -8,13 +8,14 @@ import java.util.*; -import org.osgi.framework.*; - import net.java.sip.communicator.service.browserlauncher.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; +import org.osgi.framework.*; + /** * Registers the GoogleTalkAccountRegistrationWizard in the UI Service. * diff --git a/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/sip2sipaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/sip2sipaccregwizz.manifest.mf index d94956243..98f186f60 100644 --- a/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/sip2sipaccregwizz.manifest.mf +++ b/src/net/java/sip/communicator/plugin/sip2sipaccregwizz/sip2sipaccregwizz.manifest.mf @@ -6,16 +6,16 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, - net.java.sip.communicator.service.fileaccess, + org.jitsi.service.fileaccess, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.protocol.icqconstants, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, net.java.sip.communicator.plugin.sipaccregwizz, diff --git a/src/net/java/sip/communicator/plugin/sipaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/sipaccregwizz/Resources.java index 4e410f676..6d65a0b2a 100644 --- a/src/net/java/sip/communicator/plugin/sipaccregwizz/Resources.java +++ b/src/net/java/sip/communicator/plugin/sipaccregwizz/Resources.java @@ -8,6 +8,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the image resources used in this plugin. diff --git a/src/net/java/sip/communicator/plugin/sipaccregwizz/SIPAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/sipaccregwizz/SIPAccRegWizzActivator.java index d0c9fa735..3caf86758 100644 --- a/src/net/java/sip/communicator/plugin/sipaccregwizz/SIPAccRegWizzActivator.java +++ b/src/net/java/sip/communicator/plugin/sipaccregwizz/SIPAccRegWizzActivator.java @@ -11,7 +11,7 @@ import net.java.sip.communicator.service.browserlauncher.*; import net.java.sip.communicator.service.certificate.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; diff --git a/src/net/java/sip/communicator/plugin/sipaccregwizz/SecurityPanel.java b/src/net/java/sip/communicator/plugin/sipaccregwizz/SecurityPanel.java index 079788c05..c64c21194 100644 --- a/src/net/java/sip/communicator/plugin/sipaccregwizz/SecurityPanel.java +++ b/src/net/java/sip/communicator/plugin/sipaccregwizz/SecurityPanel.java @@ -9,12 +9,13 @@ import javax.swing.border.*; import javax.swing.table.*; -import ch.imvs.sdes4j.srtp.SrtpCryptoSuite; - -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.neomedia.*; + +import ch.imvs.sdes4j.srtp.*; + /** * Contains the security settings for SIP media encryption. * diff --git a/src/net/java/sip/communicator/plugin/sipaccregwizz/sipaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/sipaccregwizz/sipaccregwizz.manifest.mf index 3c75af414..054b038ae 100644 --- a/src/net/java/sip/communicator/plugin/sipaccregwizz/sipaccregwizz.manifest.mf +++ b/src/net/java/sip/communicator/plugin/sipaccregwizz/sipaccregwizz.manifest.mf @@ -8,16 +8,16 @@ Export-package: net.java.sip.communicator.plugin.sipaccregwizz Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, net.java.sip.communicator.service.certificate, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, - net.java.sip.communicator.service.neomedia, + org.jitsi.service.neomedia, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.protocol.icqconstants, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/skinmanager/Resources.java b/src/net/java/sip/communicator/plugin/skinmanager/Resources.java index 4d99e1f6d..b523cf048 100644 --- a/src/net/java/sip/communicator/plugin/skinmanager/Resources.java +++ b/src/net/java/sip/communicator/plugin/skinmanager/Resources.java @@ -8,6 +8,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the image resources used in this plugin. diff --git a/src/net/java/sip/communicator/plugin/skinmanager/SkinManagerActivator.java b/src/net/java/sip/communicator/plugin/skinmanager/SkinManagerActivator.java index 9953a0d10..a91b270a2 100644 --- a/src/net/java/sip/communicator/plugin/skinmanager/SkinManagerActivator.java +++ b/src/net/java/sip/communicator/plugin/skinmanager/SkinManagerActivator.java @@ -7,7 +7,7 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.util.*; diff --git a/src/net/java/sip/communicator/plugin/skinmanager/SkinSelectionListener.java b/src/net/java/sip/communicator/plugin/skinmanager/SkinSelectionListener.java index 1b66204a6..41cc4fb7e 100644 --- a/src/net/java/sip/communicator/plugin/skinmanager/SkinSelectionListener.java +++ b/src/net/java/sip/communicator/plugin/skinmanager/SkinSelectionListener.java @@ -215,4 +215,4 @@ public String getDescription() return chooser; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/skinmanager/SkinSelector.java b/src/net/java/sip/communicator/plugin/skinmanager/SkinSelector.java index 6cc408fa9..87148dd4e 100644 --- a/src/net/java/sip/communicator/plugin/skinmanager/SkinSelector.java +++ b/src/net/java/sip/communicator/plugin/skinmanager/SkinSelector.java @@ -292,4 +292,4 @@ private boolean isSkin(Bundle bundle) return false; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/skinmanager/skinmanager.manifest.mf b/src/net/java/sip/communicator/plugin/skinmanager/skinmanager.manifest.mf index bfe0c717d..1464ff50c 100644 --- a/src/net/java/sip/communicator/plugin/skinmanager/skinmanager.manifest.mf +++ b/src/net/java/sip/communicator/plugin/skinmanager/skinmanager.manifest.mf @@ -5,10 +5,10 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/skinresourcepack/skinresourcepack.manifest.mf b/src/net/java/sip/communicator/plugin/skinresourcepack/skinresourcepack.manifest.mf index d64b30676..dd07b2c88 100644 --- a/src/net/java/sip/communicator/plugin/skinresourcepack/skinresourcepack.manifest.mf +++ b/src/net/java/sip/communicator/plugin/skinresourcepack/skinresourcepack.manifest.mf @@ -6,5 +6,5 @@ Bundle-Vendor: jitsi.org, Adam Netocny, CircleTech, s.r.o. Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util diff --git a/src/net/java/sip/communicator/plugin/spellcheck/ChatAttachments.java b/src/net/java/sip/communicator/plugin/spellcheck/ChatAttachments.java index 4954dab90..89b413ef4 100644 --- a/src/net/java/sip/communicator/plugin/spellcheck/ChatAttachments.java +++ b/src/net/java/sip/communicator/plugin/spellcheck/ChatAttachments.java @@ -14,10 +14,10 @@ import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.gui.event.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; import org.dts.spell.dictionary.*; +import org.jitsi.service.resources.*; /** * Wrapper for handling the multiple listeners associated with chats for the @@ -312,4 +312,4 @@ public void actionPerformed(ActionEvent event) chat.setMessage(newMessage.toString()); } } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/spellcheck/DocUnderliner.java b/src/net/java/sip/communicator/plugin/spellcheck/DocUnderliner.java index b00bc1ada..860333b00 100644 --- a/src/net/java/sip/communicator/plugin/spellcheck/DocUnderliner.java +++ b/src/net/java/sip/communicator/plugin/spellcheck/DocUnderliner.java @@ -442,4 +442,4 @@ public void reset(String message) promptRepaint(); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/spellcheck/Parameters.java b/src/net/java/sip/communicator/plugin/spellcheck/Parameters.java index 3993be2c1..10d78f4fd 100644 --- a/src/net/java/sip/communicator/plugin/spellcheck/Parameters.java +++ b/src/net/java/sip/communicator/plugin/spellcheck/Parameters.java @@ -318,4 +318,4 @@ public String toString() return this.tag; } } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/spellcheck/Resources.java b/src/net/java/sip/communicator/plugin/spellcheck/Resources.java index 7e5c79277..b58a4c072 100644 --- a/src/net/java/sip/communicator/plugin/spellcheck/Resources.java +++ b/src/net/java/sip/communicator/plugin/spellcheck/Resources.java @@ -11,9 +11,9 @@ import javax.imageio.*; import javax.swing.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** @@ -136,4 +136,4 @@ public static ResourceManagementService getResources() return resourceService; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/spellcheck/SpellCheckActivator.java b/src/net/java/sip/communicator/plugin/spellcheck/SpellCheckActivator.java index eb6cae0de..6c8b4fdef 100644 --- a/src/net/java/sip/communicator/plugin/spellcheck/SpellCheckActivator.java +++ b/src/net/java/sip/communicator/plugin/spellcheck/SpellCheckActivator.java @@ -7,10 +7,10 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.fileaccess.*; import net.java.sip.communicator.service.gui.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.fileaccess.*; import org.osgi.framework.*; /** @@ -119,4 +119,4 @@ public void stop(BundleContext arg0) throws Exception { this.checker.stop(); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/spellcheck/SpellChecker.java b/src/net/java/sip/communicator/plugin/spellcheck/SpellChecker.java index bc2765b62..b661cb667 100644 --- a/src/net/java/sip/communicator/plugin/spellcheck/SpellChecker.java +++ b/src/net/java/sip/communicator/plugin/spellcheck/SpellChecker.java @@ -9,12 +9,12 @@ import java.net.*; import java.util.*; -import net.java.sip.communicator.service.fileaccess.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.gui.event.*; -import net.java.sip.communicator.util.Logger; +import net.java.sip.communicator.util.*; import org.dts.spell.dictionary.*; +import org.jitsi.service.fileaccess.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/spellcheck/SpellCheckerConfigDialog.java b/src/net/java/sip/communicator/plugin/spellcheck/SpellCheckerConfigDialog.java index 579318645..ac51b2799 100644 --- a/src/net/java/sip/communicator/plugin/spellcheck/SpellCheckerConfigDialog.java +++ b/src/net/java/sip/communicator/plugin/spellcheck/SpellCheckerConfigDialog.java @@ -13,13 +13,13 @@ import javax.swing.event.*; import javax.swing.text.*; -import org.dts.spell.dictionary.*; - import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.resources.*; -import net.java.sip.communicator.util.Logger; +import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; +import org.dts.spell.dictionary.*; +import org.jitsi.service.resources.*; + /** * The spell check dialog that would be opened from the right click menu in the * chat window. diff --git a/src/net/java/sip/communicator/plugin/spellcheck/Word.java b/src/net/java/sip/communicator/plugin/spellcheck/Word.java index 1ba21cfcc..9c87c03d8 100644 --- a/src/net/java/sip/communicator/plugin/spellcheck/Word.java +++ b/src/net/java/sip/communicator/plugin/spellcheck/Word.java @@ -83,4 +83,4 @@ public String toString() { return this.text; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/spellcheck/spellCheck.manifest.mf b/src/net/java/sip/communicator/plugin/spellcheck/spellCheck.manifest.mf index aaf654774..32977475d 100644 --- a/src/net/java/sip/communicator/plugin/spellcheck/spellCheck.manifest.mf +++ b/src/net/java/sip/communicator/plugin/spellcheck/spellCheck.manifest.mf @@ -5,11 +5,11 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 Import-Package: org.osgi.framework, net.java.sip.communicator.util, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.fileaccess, + org.jitsi.service.configuration, + org.jitsi.service.fileaccess, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util.swing, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.protocol, @@ -20,4 +20,4 @@ Import-Package: org.osgi.framework, javax.imageio, javax.xml.parsers, org.w3c.dom, - org.xml.sax \ No newline at end of file + org.xml.sax diff --git a/src/net/java/sip/communicator/plugin/sshaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/sshaccregwizz/Resources.java index 97a5ff369..444dd688b 100644 --- a/src/net/java/sip/communicator/plugin/sshaccregwizz/Resources.java +++ b/src/net/java/sip/communicator/plugin/sshaccregwizz/Resources.java @@ -15,6 +15,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the image resources used in this plugin. diff --git a/src/net/java/sip/communicator/plugin/sshaccregwizz/sshaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/sshaccregwizz/sshaccregwizz.manifest.mf index f6c650f6d..d4fa3372b 100644 --- a/src/net/java/sip/communicator/plugin/sshaccregwizz/sshaccregwizz.manifest.mf +++ b/src/net/java/sip/communicator/plugin/sshaccregwizz/sshaccregwizz.manifest.mf @@ -6,14 +6,14 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/update/Resources.java b/src/net/java/sip/communicator/plugin/update/Resources.java index 3aff8917d..c622fda1c 100644 --- a/src/net/java/sip/communicator/plugin/update/Resources.java +++ b/src/net/java/sip/communicator/plugin/update/Resources.java @@ -8,9 +8,10 @@ import java.io.*; import java.util.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; + /** * Implements methods to facilitate dealing with resources in the update * plug-in. diff --git a/src/net/java/sip/communicator/plugin/update/Update.java b/src/net/java/sip/communicator/plugin/update/Update.java index bdba08aa2..749a1e710 100644 --- a/src/net/java/sip/communicator/plugin/update/Update.java +++ b/src/net/java/sip/communicator/plugin/update/Update.java @@ -11,19 +11,23 @@ import java.io.*; import java.net.*; import java.util.*; -import java.util.List; // disambiguation +import java.util.List; import javax.swing.*; import javax.swing.text.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.httputil.*; -import net.java.sip.communicator.service.resources.*; -import net.java.sip.communicator.service.update.UpdateService; -import net.java.sip.communicator.service.version.*; +import net.java.sip.communicator.service.update.*; import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; +import org.jitsi.service.version.*; +import org.jitsi.util.*; +// disambiguation + /** * Implements checking for software updates, downloading and applying them i.e. * the very logic of the update plug-in. diff --git a/src/net/java/sip/communicator/plugin/update/UpdateActivator.java b/src/net/java/sip/communicator/plugin/update/UpdateActivator.java index f9ff19887..14951d5d3 100644 --- a/src/net/java/sip/communicator/plugin/update/UpdateActivator.java +++ b/src/net/java/sip/communicator/plugin/update/UpdateActivator.java @@ -9,12 +9,14 @@ import java.util.*; import net.java.sip.communicator.service.browserlauncher.*; -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.shutdown.*; -import net.java.sip.communicator.service.update.UpdateService; +import net.java.sip.communicator.service.update.*; import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; +import org.jitsi.service.configuration.*; +import org.jitsi.util.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/plugin/update/update.manifest.mf b/src/net/java/sip/communicator/plugin/update/update.manifest.mf index 5a822e830..98b694828 100644 --- a/src/net/java/sip/communicator/plugin/update/update.manifest.mf +++ b/src/net/java/sip/communicator/plugin/update/update.manifest.mf @@ -5,14 +5,16 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, + org.jitsi.service.configuration, + org.jitsi.service.resources, + org.jitsi.service.version, + org.jitsi.util, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, net.java.sip.communicator.service.httputil, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.resources, net.java.sip.communicator.service.shutdown, - net.java.sip.communicator.service.version, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, net.java.sip.communicator.service.update, diff --git a/src/net/java/sip/communicator/plugin/whiteboard/Resources.java b/src/net/java/sip/communicator/plugin/whiteboard/Resources.java index 05d273d18..12880109c 100644 --- a/src/net/java/sip/communicator/plugin/whiteboard/Resources.java +++ b/src/net/java/sip/communicator/plugin/whiteboard/Resources.java @@ -9,6 +9,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the image resources used in this plugin. diff --git a/src/net/java/sip/communicator/plugin/whiteboard/WhiteboardMenuItem.java b/src/net/java/sip/communicator/plugin/whiteboard/WhiteboardMenuItem.java index a1941113f..de1872de7 100644 --- a/src/net/java/sip/communicator/plugin/whiteboard/WhiteboardMenuItem.java +++ b/src/net/java/sip/communicator/plugin/whiteboard/WhiteboardMenuItem.java @@ -158,4 +158,4 @@ public String getName() { return whiteboardMenu.getText(); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardFileFilter.java b/src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardFileFilter.java index 18706db60..23e330c58 100644 --- a/src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardFileFilter.java +++ b/src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardFileFilter.java @@ -89,4 +89,4 @@ public String getExtension (File f) { } return null; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardPanel.java b/src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardPanel.java index 696612918..5282b66a1 100644 --- a/src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardPanel.java +++ b/src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardPanel.java @@ -302,4 +302,4 @@ private void checkPopupEvent(MouseEvent e) popupMenu.show(e.getComponent(), e.getX(), e.getY()); } } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/whiteboard/gui/whiteboardshapes/WhiteboardShape.java b/src/net/java/sip/communicator/plugin/whiteboard/gui/whiteboardshapes/WhiteboardShape.java index 0bd074643..c303fba2a 100644 --- a/src/net/java/sip/communicator/plugin/whiteboard/gui/whiteboardshapes/WhiteboardShape.java +++ b/src/net/java/sip/communicator/plugin/whiteboard/gui/whiteboardshapes/WhiteboardShape.java @@ -368,4 +368,4 @@ public boolean equals (Object obj) */ public abstract WhiteboardPoint getSelectionPoint (Point2D p); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/plugin/whiteboard/whiteboard.manifest.mf b/src/net/java/sip/communicator/plugin/whiteboard/whiteboard.manifest.mf index 080d8f925..14cd534d8 100644 --- a/src/net/java/sip/communicator/plugin/whiteboard/whiteboard.manifest.mf +++ b/src/net/java/sip/communicator/plugin/whiteboard/whiteboard.manifest.mf @@ -12,7 +12,7 @@ Import-Package: org.osgi.framework, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.protocol.whiteboardobjects, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/yahooaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/yahooaccregwizz/Resources.java index 5f7c6eb31..a33650998 100644 --- a/src/net/java/sip/communicator/plugin/yahooaccregwizz/Resources.java +++ b/src/net/java/sip/communicator/plugin/yahooaccregwizz/Resources.java @@ -8,6 +8,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the image resources used in this plugin. diff --git a/src/net/java/sip/communicator/plugin/yahooaccregwizz/yahooaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/yahooaccregwizz/yahooaccregwizz.manifest.mf index aecb0aa04..1f27b2b91 100644 --- a/src/net/java/sip/communicator/plugin/yahooaccregwizz/yahooaccregwizz.manifest.mf +++ b/src/net/java/sip/communicator/plugin/yahooaccregwizz/yahooaccregwizz.manifest.mf @@ -6,7 +6,7 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, net.java.sip.communicator.service.gui, @@ -14,7 +14,7 @@ Import-Package: org.osgi.framework, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.protocol.icqconstants, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/Resources.java index bfa379f76..253ea9cb1 100644 --- a/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/Resources.java +++ b/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/Resources.java @@ -8,6 +8,8 @@ import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * The Resources class manages the access to the internationalization * properties files and the images properties file. diff --git a/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/zeroconfaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/zeroconfaccregwizz.manifest.mf index 728fedcf4..611a2d846 100644 --- a/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/zeroconfaccregwizz.manifest.mf +++ b/src/net/java/sip/communicator/plugin/zeroconfaccregwizz/zeroconfaccregwizz.manifest.mf @@ -6,14 +6,14 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.service.browserlauncher, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.contactlist.event, net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, javax.swing, diff --git a/src/net/java/sip/communicator/service/audionotifier/AudioNotifierService.java b/src/net/java/sip/communicator/service/audionotifier/AudioNotifierService.java deleted file mode 100644 index 3ae86337b..000000000 --- a/src/net/java/sip/communicator/service/audionotifier/AudioNotifierService.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.audionotifier; - -/** - * The AudioNotifierService is meant to be used to control all sounds in the - * application. An audio could be created by calling the createAudio method. - * In order to stop all sounds in the application one could call the setMute - * method. To check whether the sound is currently enabled the isMute method - * could be used. - * - * @author Yana Stamcheva - */ -public interface AudioNotifierService -{ - /** - * Creates an SCAudioClip and returns it. - * @param uri the uri, which will be the source of the audio - * @return the created SCAudioClip, that could be played. - */ - public SCAudioClip createAudio(String uri); - - /** - * Destroys the given audio. - * - * @param audio SCAudioClip to destroy - */ - public void destroyAudio(SCAudioClip audio); - - /** - * Stops/Restores all currently playing sounds. - * - * @param isMute mute or not currently playing sounds - */ - public void setMute(boolean isMute); - - /** - * Specifies if currently the sound is off. - * - * @return TRUE if currently the sound is off, FALSE otherwise - */ - public boolean isMute(); -} diff --git a/src/net/java/sip/communicator/service/audionotifier/SCAudioClip.java b/src/net/java/sip/communicator/service/audionotifier/SCAudioClip.java deleted file mode 100644 index daf81c753..000000000 --- a/src/net/java/sip/communicator/service/audionotifier/SCAudioClip.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.audionotifier; - -/** - * SCAudioClip represents an audio clip created using the AudioNotifierService. - * Like any audio it could be played, stopped or played in loop. - * - * @author Yana Stamcheva - */ -public interface SCAudioClip -{ - /** - * Plays this audio. - */ - public void play(); - - /** - * Plays this audio in loop. - * - * @param silenceInterval interval between loops - */ - public void playInLoop(int silenceInterval); - - /** - * Stops this audio. - */ - public void stop(); -} diff --git a/src/net/java/sip/communicator/service/certificate/CertificateService.java b/src/net/java/sip/communicator/service/certificate/CertificateService.java index 33a2ed9ae..795fdfa15 100644 --- a/src/net/java/sip/communicator/service/certificate/CertificateService.java +++ b/src/net/java/sip/communicator/service/certificate/CertificateService.java @@ -250,4 +250,4 @@ public X509TrustManager getTrustManager( */ public void addCertificateToTrust(Certificate cert, String trustFor, int trustMode) throws CertificateException; -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/certificate/KeyStoreType.java b/src/net/java/sip/communicator/service/certificate/KeyStoreType.java index b292684cc..d015e395e 100644 --- a/src/net/java/sip/communicator/service/certificate/KeyStoreType.java +++ b/src/net/java/sip/communicator/service/certificate/KeyStoreType.java @@ -65,4 +65,4 @@ public boolean hasKeyStorePassword() { return hasKeyStorePassword; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/configuration/ConfigPropertyVetoException.java b/src/net/java/sip/communicator/service/configuration/ConfigPropertyVetoException.java deleted file mode 100644 index 733101e1c..000000000 --- a/src/net/java/sip/communicator/service/configuration/ConfigPropertyVetoException.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.configuration; - -import java.beans.*; - -/** - * A PropertyVetoException is thrown when a proposed change to a - * property represents an unacceptable value. - * - * @author Emil Ivov - */ -public class ConfigPropertyVetoException - extends RuntimeException -{ - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * A PropertyChangeEvent describing the vetoed change. - */ - private final PropertyChangeEvent evt; - - /** - * Constructs a PropertyVetoException with a - * detailed message. - * - * @param message Descriptive message - * @param evt A PropertyChangeEvent describing the vetoed change. - */ - public ConfigPropertyVetoException(String message, PropertyChangeEvent evt) - { - super(message); - - this.evt = evt; - } - - /** - * Gets the vetoed PropertyChangeEvent. - * - * @return A PropertyChangeEvent describing the vetoed change. - */ - public PropertyChangeEvent getPropertyChangeEvent() - { - return evt; - } -} diff --git a/src/net/java/sip/communicator/service/configuration/ConfigVetoableChangeListener.java b/src/net/java/sip/communicator/service/configuration/ConfigVetoableChangeListener.java deleted file mode 100644 index 075d56e25..000000000 --- a/src/net/java/sip/communicator/service/configuration/ConfigVetoableChangeListener.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ - -package net.java.sip.communicator.service.configuration; - -import java.beans.*; -import java.util.EventListener; - -/** - * This interface uses SC's own ProperteyVetoException. - */ -public interface ConfigVetoableChangeListener extends EventListener -{ - /** - * Fired before a Bean's property changes. - * - * @param e the change (containing the old and new values) - * @throws ConfigPropertyVetoException if the change is vetoed by the listener - */ - void vetoableChange(PropertyChangeEvent e) throws ConfigPropertyVetoException; -} diff --git a/src/net/java/sip/communicator/service/configuration/ConfigurationService.java b/src/net/java/sip/communicator/service/configuration/ConfigurationService.java deleted file mode 100644 index 9e91dc2ac..000000000 --- a/src/net/java/sip/communicator/service/configuration/ConfigurationService.java +++ /dev/null @@ -1,454 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.configuration; - -import java.beans.*; -import java.io.*; -import java.util.*; - -import net.java.sip.communicator.util.xml.*; - -/** - * The configuration services provides a centralized approach of storing - * persistent configuration data. - * - * @author Emil Ivov - * @author Lyubomir Marinov - * @author Dmitri Melnikov - */ -public interface ConfigurationService -{ - /** - * The name of the property that indicates the name of the directory where - * SIP Communicator is to store user specific data such as configuration - * files, message and call history as well as is bundle repository. - */ - public static final String PNAME_SC_HOME_DIR_NAME - = "net.java.sip.communicator.SC_HOME_DIR_NAME"; - - /** - * The name of the property that indicates the location of the directory - * where SIP Communicator is to store user specific data such as - * configuration files, message and call history as well as is bundle - * repository. - */ - public static final String PNAME_SC_HOME_DIR_LOCATION - = "net.java.sip.communicator.SC_HOME_DIR_LOCATION"; - - /** - * The name of the boolean system property which indicates whether the - * configuration file is to be considered read-only. The default value is - * false which means that the configuration file is considered - * writable. - */ - public static final String PNAME_CONFIGURATION_FILE_IS_READ_ONLY - = "net.java.sip.communicator.CONFIGURATION_FILE_IS_READ_ONLY"; - - /** - * The name of the system property that stores the name of the configuration - * file. - */ - public static final String PNAME_CONFIGURATION_FILE_NAME - = "net.java.sip.communicator.CONFIGURATION_FILE_NAME"; - - /** - * Sets the property with the specified name to the specified value. Calling - * this method would first trigger a PropertyChangeEvent that will - * be dispatched to all VetoableChangeListeners. In case no complaints - * (PropertyVetoException) have been received, the property will be actually - * changed and a PropertyChangeEvent will be dispatched. - *

- * @param propertyName the name of the property to change. - * @param property the new value of the specified property. - * @throws ConfigPropertyVetoException in case the changed has been refused by - * at least one propertychange listener. - */ - public void setProperty(String propertyName, Object property); - // throws PropertyVetoException; - - /** - * Sets the property with the specified name to the specified. Calling - * this method would first trigger a PropertyChangeEvent that will - * be dispatched to all VetoableChangeListeners. In case no complaints - * (PropertyVetoException) have been received, the property will be actually - * changed and a PropertyChangeEvent will be dispatched. This method also - * allows the caller to specify whether or not the specified property is a - * system one. - *

- * @param propertyName the name of the property to change. - * @param property the new value of the specified property. - * @param isSystem specifies whether or not the property being is a System - * property and should be resolved against the system - * property set - * @throws ConfigPropertyVetoException in case the changed has been refused by - * at least one propertychange listener. - */ - public void setProperty(String propertyName, - Object property, - boolean isSystem); - // throws PropertyVetoException; - - /** - * Sets a set of specific properties to specific values as a batch operation - * meaning that first VetoableChangeListeners are asked to - * approve the modifications of the specified properties to the specified - * values, then the modifications are performed if no complaints have been - * raised in the form of PropetyVetoException and finally - * PropertyChangeListeners are notified about the changes of - * each of the specified properties. The batch operations allows the - * ConfigurationService implementations to optimize, for - * example, the saving of the configuration which in this case can be - * performed only once for the setting of multiple properties. - * - * @param properties - * a Map of property names to their new values to be - * set - * @throws ConfigPropertyVetoException - * if a change in at least one of the properties has been - * refused by at least one of the - * VetoableChangeListeners - */ - public void setProperties(Map properties); - // throws PropertyVetoException; - - /** - * Returns the value of the property with the specified name or null if no - * such property exists. - * @param propertyName the name of the property that is being queried. - * @return the value of the property with the specified name. - */ - public Object getProperty(String propertyName); - - /** - * Removes the property with the specified name. Calling - * this method would first trigger a PropertyChangeEvent that will - * be dispatched to all VetoableChangeListeners. In case no complaints - * (PropertyVetoException) have been received, the property will be actually - * changed and a PropertyChangeEvent will be dispatched. - * All properties with prefix propertyName will also be removed. - *

- * @param propertyName the name of the property to change. - * @throws ConfigPropertyVetoException in case the changed has been refused by - * at least one propertychange listener. - */ - public void removeProperty(String propertyName); - // throws PropertyVetoException; - - /** - * Returns a java.util.List of Strings containing all - * property names. - * - * @return a java.util.Listcontaining all property names - */ - public List getAllPropertyNames(); - - /** - * Returns a java.util.List of Strings containing the - * all property names that have the specified prefix. Depending on the value - * of the exactPrefixMatch parameter the method will (when false) - * or will not (when exactPrefixMatch is true) include property names that - * have prefixes longer than the specified prefix param. - *

- * Example: - *

- * Imagine a configuration service instance containing 2 properties only:
- * - * net.java.sip.communicator.PROP1=value1
- * net.java.sip.communicator.service.protocol.PROP1=value2 - *
- *

- * A call to this method with a prefix="net.java.sip.communicator" and - * exactPrefixMatch=true would only return the first property - - * net.java.sip.communicator.PROP1, whereas the same call with - * exactPrefixMatch=false would return both properties as the second prefix - * includes the requested prefix string. - *

- * @param prefix a String containing the prefix (the non dotted non-caps - * part of a property name) that we're looking for. - * @param exactPrefixMatch a boolean indicating whether the returned - * property names should all have a prefix that is an exact match of the - * the prefix param or whether properties with prefixes that - * contain it but are longer than it are also accepted. - * @return a java.util.Listcontaining all property name String-s - * matching the specified conditions. - */ - public List getPropertyNamesByPrefix(String prefix, - boolean exactPrefixMatch); - - /** - * Returns a List of Strings containing the property names - * that have the specified suffix. A suffix is considered to be everything - * after the last dot in the property name. - *

- * For example, imagine a configuration service instance containing two - * properties only: - *

- * - * net.java.sip.communicator.PROP1=value1 - * net.java.sip.communicator.service.protocol.PROP1=value2 - * - *

- * A call to this method with suffix equal to "PROP1" will return - * both properties, whereas the call with suffix equal to - * "communicator.PROP1" or "PROP2" will return an empty List. Thus, - * if the suffix argument contains a dot, nothing will be found. - *

- * - * @param suffix the suffix for the property names to be returned - * @return a List of Strings containing the property names - * which contain the specified suffix - */ - public List getPropertyNamesBySuffix(String suffix); - - /** - * Returns the String value of the specified property and null in case no - * property value was mapped against the specified propertyName, or in - * case the returned property string had zero length or contained - * whitespaces only. - * - * @param propertyName the name of the property that is being queried. - * @return the result of calling the property's toString method and null in - * case there was no value mapped against the specified - * propertyName, or the returned string had zero length or - * contained whitespaces only. - */ - public String getString(String propertyName); - - /** - * Returns the String value of the specified property and null in case no - * property value was mapped against the specified propertyName, or in - * case the returned property string had zero length or contained - * whitespaces only. - * - * @param propertyName the name of the property that is being queried. - * @param defaultValue the value to be returned if the specified property - * name is not associated with a value in this - * ConfigurationService - * @return the result of calling the property's toString method and - * defaultValue in case there was no value mapped against - * the specified propertyName, or the returned string had zero - * length or contained whitespaces only. - */ - public String getString(String propertyName, String defaultValue); - - /** - * Gets the value of a specific property as a boolean. If the specified - * property name is associated with a value in this - * ConfigurationService, the string representation of the value - * is parsed into a boolean according to the rules of - * {@link Boolean#parseBoolean(String)} . Otherwise, - * defaultValue is returned. - * - * @param propertyName - * the name of the property to get the value of as a boolean - * @param defaultValue - * the value to be returned if the specified property name is not - * associated with a value in this - * ConfigurationService - * @return the value of the property with the specified name in this - * ConfigurationService as a boolean; - * defaultValue if the property with the specified name - * is not associated with a value in this - * ConfigurationService - */ - public boolean getBoolean(String propertyName, boolean defaultValue); - - /** - * Gets the value of a specific property as a signed decimal integer. If the - * specified property name is associated with a value in this - * ConfigurationService, the string representation of the value is - * parsed into a signed decimal integer according to the rules of - * {@link Integer#parseInt(String)} . If parsing the value as a signed - * decimal integer fails or there is no value associated with the specified - * property name, defaultValue is returned. - * - * @param propertyName the name of the property to get the value of as a - * signed decimal integer - * @param defaultValue the value to be returned if parsing the value of the - * specified property name as a signed decimal integer fails or there is no - * value associated with the specified property name in this - * ConfigurationService - * @return the value of the property with the specified name in this - * ConfigurationService as a signed decimal integer; - * defaultValue if parsing the value of the specified property name - * fails or no value is associated in this ConfigurationService - * with the specified property name - */ - public int getInt(String propertyName, int defaultValue); - - /** - * Gets the value of a specific property as a signed decimal long integer. - * If the specified property name is associated with a value in this - * ConfigurationService, the string representation of the value is - * parsed into a signed decimal long integer according to the rules of - * {@link Long#parseLong(String)} . If parsing the value as a signed - * decimal long integer fails or there is no value associated with the - * specified property name, defaultValue is returned. - * - * @param propertyName the name of the property to get the value of as a - * signed decimal long integer - * @param defaultValue the value to be returned if parsing the value of the - * specified property name as a signed decimal long integer fails or there - * is no value associated with the specified property name in this - * ConfigurationService - * @return the value of the property with the specified name in this - * ConfigurationService as a signed decimal long integer; - * defaultValue if parsing the value of the specified property name - * fails or no value is associated in this ConfigurationService - * with the specified property name - */ - public long getLong(String propertyName, long defaultValue); - - /** - * Adds a PropertyChangeListener to the listener list. The listener is - * registered for all properties in the current configuration. - *

- * @param listener the PropertyChangeListener to be added - */ - public void addPropertyChangeListener(PropertyChangeListener listener); - - /** - * Removes a PropertyChangeListener from the listener list. - *

- * @param listener the PropertyChangeListener to be removed - */ - public void removePropertyChangeListener(PropertyChangeListener listener); - - /** - * Adds a PropertyChangeListener to the listener list for a specific - * property. In case a property with the specified name does not exist the - * listener is still added and would only be taken into account from the - * moment such a property is set by someone. - *

- * @param propertyName one of the property names listed above - * @param listener the PropertyChangeListener to be added - */ - public void addPropertyChangeListener(String propertyName, - PropertyChangeListener listener); - - /** - * Removes a PropertyChangeListener from the listener list for a specific - * property. This method should be used to remove PropertyChangeListeners - * that were registered for a specific property. The method has no effect - * when called for a listener that was not registered for that specifiec - * property. - *

- * - * @param propertyName a valid property name - * @param listener the PropertyChangeListener to be removed - */ - public void removePropertyChangeListener(String propertyName, - PropertyChangeListener listener); - - /** - * Adds a VetoableChangeListener to the listener list. The listener is - * registered for all properties in the configuration. - *

- * @param listener the VetoableChangeListener to be added - */ - public void addVetoableChangeListener(ConfigVetoableChangeListener listener); - - /** - * Removes a VetoableChangeListener from the listener list. - *

- * - * @param listener the VetoableChangeListener to be removed - */ - public void removeVetoableChangeListener(ConfigVetoableChangeListener listener); - - /** - * Adds a VetoableChangeListener to the listener list for a specific - * property. - *

- * - * @param propertyName one of the property names listed above - * @param listener the VetoableChangeListener to be added - */ - public void addVetoableChangeListener(String propertyName, - ConfigVetoableChangeListener listener); - - /** - * Removes a VetoableChangeListener from the listener list for a specific - * property. - *

- * - * @param propertyName a valid property name - * @param listener the VetoableChangeListener to be removed - */ - public void removeVetoableChangeListener(String propertyName, - ConfigVetoableChangeListener listener); - - /** - * Store the current set of properties back to the configuration file. The - * name of the configuration file is queried from the system property - * net.java.sip.communicator.PROPERTIES_FILE_NAME, and is set to - * sip-communicator.xml in case the property does not contain a valid file - * name. The location might be one of three possibile, checked in the - * following order:
- * 1. The current directory.
- * 2. The sip-communicator directory in the user.home - * ($HOME/.sip-communicator) - * 3. A location in the classpath (such as the sip-communicator jar file). - *

- * In the last case the file is copied to the sip-communicator configuration - * directory right after being extracted from the classpath location. - * - * @throws IOException in case storing the configuration failed. - */ - public void storeConfiguration() - throws IOException; - - /** - * Deletes the current configuration and reloads it from the configuration - * file. The - * name of the configuration file is queried from the system property - * net.java.sip.communicator.PROPERTIES_FILE_NAME, and is set to - * sip-communicator.xml in case the property does not contain a valid file - * name. The location might be one of three possibile, checked in the - * following order:
- * 1. The current directory.
- * 2. The sip-communicator directory in the user.home - * ($HOME/.sip-communicator) - * 3. A location in the classpath (such as the sip-communicator jar file). - *

- * In the last case the file is copied to the sip-communicator configuration - * directory right after being extracted from the classpath location. - * @throws IOException in case reading the configuration failes - * @throws XMLException in case parsing the configuration file has failed - */ - public void reloadConfiguration() - throws IOException, XMLException; - - /** - * Removes all locally stored properties leaving an empty configuration. - * Implementations that use a file for storing properties may simply delete - * it when this method is called. - */ - public void purgeStoredConfiguration(); - - /** - * Returns the name of the directory where SIP Communicator is to store user - * specific data such as configuration files, message and call history - * as well as is bundle repository. - * - * @return the name of the directory where SIP Communicator is to store - * user specific data such as configuration files, message and call history - * as well as is bundle repository. - */ - public String getScHomeDirName(); - - /** - * Returns the location of the directory where SIP Communicator is to store - * user specific data such as configuration files, message and call history - * as well as is bundle repository. - * - * @return the location of the directory where SIP Communicator is to store - * user specific data such as configuration files, message and call history - * as well as is bundle repository. - */ - public String getScHomeDirLocation(); -} diff --git a/src/net/java/sip/communicator/service/contactsource/SourceContact.java b/src/net/java/sip/communicator/service/contactsource/SourceContact.java index b41b33c56..9d4536e99 100644 --- a/src/net/java/sip/communicator/service/contactsource/SourceContact.java +++ b/src/net/java/sip/communicator/service/contactsource/SourceContact.java @@ -91,4 +91,4 @@ public ContactDetail getPreferredContactDetail( * @return the byte array of the image or null if no image is available */ public byte[] getImage(); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/fileaccess/FailSafeTransaction.java b/src/net/java/sip/communicator/service/fileaccess/FailSafeTransaction.java deleted file mode 100644 index b294c8c7e..000000000 --- a/src/net/java/sip/communicator/service/fileaccess/FailSafeTransaction.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.fileaccess; - -import java.io.*; - -/** - * A failsafe transaction interface. By failsafe we mean here that the file - * concerned always stays in a coherent state. - * - * @author Benoit Pradelle - */ -public interface FailSafeTransaction { - /** - * Ensure that the file accessed is in a coherent state. This function is - * useful to do a failsafe read without starting a transaction. - * - * @throws IllegalStateException if the file doesn't exists anymore - * @throws IOException if an IOException occurs during the file restoration - */ - public void restoreFile() - throws IllegalStateException, IOException; - - /** - * Begins a new transaction. If a transaction is already active, commits the - * changes and begin a new transaction. - * A transaction can be closed by a commit or rollback operation. - * When the transaction begins, the file is restored to a coherent state if - * needed. - * - * @throws IllegalStateException if the file doesn't exists anymore - * @throws IOException if an IOException occurs during the transaction - * creation - */ - public void beginTransaction() - throws IllegalStateException, IOException; - - /** - * Closes the transaction and commit the changes. Everything written in the - * file during the transaction is saved. - * - * @throws IllegalStateException if the file doesn't exists anymore - * @throws IOException if an IOException occurs during the operation - */ - public void commit() - throws IllegalStateException, IOException; - - /** - * Closes the transation and cancel the changes. Everything written in the - * file during the transaction is NOT saved. - * @throws IllegalStateException if the file doesn't exists anymore - * @throws IOException if an IOException occurs during the operation - */ - public void rollback() - throws IllegalStateException, IOException; -} diff --git a/src/net/java/sip/communicator/service/fileaccess/FileAccessService.java b/src/net/java/sip/communicator/service/fileaccess/FileAccessService.java deleted file mode 100644 index a68b03309..000000000 --- a/src/net/java/sip/communicator/service/fileaccess/FileAccessService.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.fileaccess; - -import java.io.*; - -/** - * A service used to provide the basic functionality required to access the - * underlying file system. - * - * Note: Never store unencrypted sensitive information, such as passwords, - * personal data, credit card numbers, etc.. - * - * @author Alexander Pelov - */ -public interface FileAccessService { - - /** - * The key of the configuration property containing the user home dir - if - * it is not defined the system property is used - */ - public static final String CONFPROPERTYKEY_USER_HOME - = "net.java.sip.communicator.fileaccess.USER_HOME"; - - /** - * This method returns a created temporary file. After you close this file - * it is not guaranteed that you will be able to open it again nor that it - * will contain any information. - * - * Note: DO NOT store unencrypted sensitive information in this file - * - * @return The created temporary file - * @throws IOException - * If the file cannot be created - */ - File getTemporaryFile() throws IOException; - - /** - * This method returns a created temporary directory. Any file you create in - * it will be a temporary file. - * - * Note: If there is no opened file in this directory it may be deleted at - * any time. Note: DO NOT store unencrypted sensitive information in this - * directory - * - * @return The created directory - * @throws IOException - * If the directory cannot be created - */ - File getTemporaryDirectory() throws IOException; - - /** - * This method returns a file specific to the current user. It may not - * exist, but it is guaranteed that you will have the sufficient rights to - * create it. - * - * This file should not be considered secure because the implementor may - * return a file accesible to everyone. Generaly it will reside in current - * user's homedir, but it may as well reside in a shared directory. - * - * Note: DO NOT store unencrypted sensitive information in this file - * - * @param fileName - * The name of the private file you wish to access - * @return The file - * @throws Exception - * Thrown if there is no suitable location for the persistent - * file - */ - File getPrivatePersistentFile(String fileName) throws Exception; - - /** - * This method creates a directory specific to the current user. - * - * This directory should not be considered secure because the implementor - * may return a directory accessible to everyone. Generally, it will reside - * in current user's homedir, but it may as well reside in a shared - * directory. - * - * It is guaranteed that you will be able to create files in it. - * - * Note: DO NOT store unencrypted sensitive information in this file - * - * @param dirName - * The name of the private directory you wish to access. - * @return The created directory. - * @throws Exception - * Thrown if there is no suitable location for the persistent - * directory. - */ - File getPrivatePersistentDirectory(String dirName) throws Exception; - - /** - * This method creates a directory specific to the current user. - * - * {@link #getPrivatePersistentDirectory(String)} - * - * @param dirNames - * The name of the private directory you wish to access. - * @return The created directory. - * @throws Exception - * Thrown if there is no suitable location for the persistent - * directory. - */ - File getPrivatePersistentDirectory(String[] dirNames) throws Exception; - - /** - * Returns the default download directory depending on the operating system. - * - * @return the default download directory depending on the operating system - * @throws IOException if it I/O error occurred - */ - File getDefaultDownloadDirectory() throws IOException; - - /** - * Creates a failsafe transaction which can be used to safely store - * informations into a file. - * - * @param file The file concerned by the transaction, null if file is null. - * - * @return A new failsafe transaction related to the given file. - */ - FailSafeTransaction createFailSafeTransaction(File file); -} diff --git a/src/net/java/sip/communicator/service/globalshortcut/GlobalShortcutService.java b/src/net/java/sip/communicator/service/globalshortcut/GlobalShortcutService.java index f9f2cf373..6eb8f5e51 100644 --- a/src/net/java/sip/communicator/service/globalshortcut/GlobalShortcutService.java +++ b/src/net/java/sip/communicator/service/globalshortcut/GlobalShortcutService.java @@ -66,4 +66,4 @@ public void setSpecialKeyDetection(boolean enable, * @param enable enable or not global shortcut */ public void setEnable(boolean enable); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/gui/Container.java b/src/net/java/sip/communicator/service/gui/Container.java index adb64e4e0..24ef7ab07 100644 --- a/src/net/java/sip/communicator/service/gui/Container.java +++ b/src/net/java/sip/communicator/service/gui/Container.java @@ -234,4 +234,4 @@ else if (obj instanceof String) else return false; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/gui/LazyConfigurationForm.java b/src/net/java/sip/communicator/service/gui/LazyConfigurationForm.java index 05ae8fb7d..15843033f 100644 --- a/src/net/java/sip/communicator/service/gui/LazyConfigurationForm.java +++ b/src/net/java/sip/communicator/service/gui/LazyConfigurationForm.java @@ -10,6 +10,8 @@ import net.java.sip.communicator.service.gui.internal.*; import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; + /** * @author Lubomir Marinov * @author Yana Stamcheva diff --git a/src/net/java/sip/communicator/service/gui/UIService.java b/src/net/java/sip/communicator/service/gui/UIService.java index e2818283e..f2a7b3bfd 100644 --- a/src/net/java/sip/communicator/service/gui/UIService.java +++ b/src/net/java/sip/communicator/service/gui/UIService.java @@ -455,4 +455,4 @@ public SecurityAuthority getDefaultSecurityAuthority( * participants to be included into the newly created Chat */ public void startChat(String[] participants); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/gui/event/ChatListener.java b/src/net/java/sip/communicator/service/gui/event/ChatListener.java index 07ca99af6..85b2909dc 100644 --- a/src/net/java/sip/communicator/service/gui/event/ChatListener.java +++ b/src/net/java/sip/communicator/service/gui/event/ChatListener.java @@ -29,4 +29,4 @@ public interface ChatListener * @param chat the new Chat which has been created */ public void chatCreated(Chat chat); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/gui/event/ChatMenuListener.java b/src/net/java/sip/communicator/service/gui/event/ChatMenuListener.java index 15a81d989..916d2aa6d 100644 --- a/src/net/java/sip/communicator/service/gui/event/ChatMenuListener.java +++ b/src/net/java/sip/communicator/service/gui/event/ChatMenuListener.java @@ -28,4 +28,4 @@ public interface ChatMenuListener * @return elements that should be added to the menu */ List getMenuElements(Chat source, MouseEvent event); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/gui/gui.manifest.mf b/src/net/java/sip/communicator/service/gui/gui.manifest.mf index 6203f68a9..ea6378091 100644 --- a/src/net/java/sip/communicator/service/gui/gui.manifest.mf +++ b/src/net/java/sip/communicator/service/gui/gui.manifest.mf @@ -5,7 +5,7 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util Export-Package: net.java.sip.communicator.service.gui, net.java.sip.communicator.service.gui.event, diff --git a/src/net/java/sip/communicator/service/gui/internal/GuiServiceActivator.java b/src/net/java/sip/communicator/service/gui/internal/GuiServiceActivator.java index 15a53c256..94fecfc36 100644 --- a/src/net/java/sip/communicator/service/gui/internal/GuiServiceActivator.java +++ b/src/net/java/sip/communicator/service/gui/internal/GuiServiceActivator.java @@ -5,9 +5,9 @@ */ package net.java.sip.communicator.service.gui.internal; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/service/httputil/HttpUtilActivator.java b/src/net/java/sip/communicator/service/httputil/HttpUtilActivator.java index 75b751c0a..9c923ec2c 100644 --- a/src/net/java/sip/communicator/service/httputil/HttpUtilActivator.java +++ b/src/net/java/sip/communicator/service/httputil/HttpUtilActivator.java @@ -1,10 +1,12 @@ package net.java.sip.communicator.service.httputil; import net.java.sip.communicator.service.certificate.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.credentialsstorage.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; + +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/service/httputil/httputil.manifest.mf b/src/net/java/sip/communicator/service/httputil/httputil.manifest.mf index b3850e91d..e3f77a7a2 100644 --- a/src/net/java/sip/communicator/service/httputil/httputil.manifest.mf +++ b/src/net/java/sip/communicator/service/httputil/httputil.manifest.mf @@ -28,13 +28,13 @@ Import-Package: org.xml.sax, net.java.sip.communicator.util.xml, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, - net.java.sip.communicator.service.resources, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.service.certificate, net.java.sip.communicator.service.credentialsstorage, net.java.sip.communicator.service.keybindings, net.java.sip.communicator.service.netaddr, net.java.sip.communicator.service.netaddr.event, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, sun.awt.shell, sun.net.util, diff --git a/src/net/java/sip/communicator/service/keybindings/KeybindingsService.java b/src/net/java/sip/communicator/service/keybindings/KeybindingsService.java index afc382565..07d589de7 100644 --- a/src/net/java/sip/communicator/service/keybindings/KeybindingsService.java +++ b/src/net/java/sip/communicator/service/keybindings/KeybindingsService.java @@ -44,4 +44,4 @@ public interface KeybindingsService * Save the configuration file. */ public void saveGlobalShortcutFromConfiguration(); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/ldap/ldap.manifest.mf b/src/net/java/sip/communicator/service/ldap/ldap.manifest.mf index 1289e0548..4007ce802 100644 --- a/src/net/java/sip/communicator/service/ldap/ldap.manifest.mf +++ b/src/net/java/sip/communicator/service/ldap/ldap.manifest.mf @@ -4,6 +4,6 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 Import-Package: org.osgi.framework, javax.naming.directory, - net.java.sip.communicator.service.configuration + org.jitsi.service.configuration Export-Package: net.java.sip.communicator.service.ldap, net.java.sip.communicator.service.ldap.event diff --git a/src/net/java/sip/communicator/service/neomedia/AbstractMediaStream.java b/src/net/java/sip/communicator/service/neomedia/AbstractMediaStream.java deleted file mode 100644 index 779441aa0..000000000 --- a/src/net/java/sip/communicator/service/neomedia/AbstractMediaStream.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import java.beans.*; -import java.util.*; - -import net.java.sip.communicator.service.neomedia.format.*; - -/** - * Abstract base implementation of MediaStream to ease the - * implementation of the interface. - * - * @author Lyubomir Marinov - */ -public abstract class AbstractMediaStream - implements MediaStream -{ - /** - * The name of this stream, that some protocols may use for diagnostic - * purposes. - */ - private String name; - - /** - * The delegate of this instance which implements support for property - * change notifications for its - * {@link #addPropertyChangeListener(PropertyChangeListener)} and - * {@link #removePropertyChangeListener(PropertyChangeListener)}. - */ - private final PropertyChangeSupport propertyChangeSupport - = new PropertyChangeSupport(this); - - /** - * Adds a PropertyChangelistener to this stream which is to be - * notified upon property changes such as a SSRC ID which becomes known. - * - * @param listener the PropertyChangeListener to register for - * PropertyChangeEvents - * @see MediaStream#addPropertyChangeListener(PropertyChangeListener) - */ - public void addPropertyChangeListener(PropertyChangeListener listener) - { - propertyChangeSupport.addPropertyChangeListener(listener); - } - - /** - * Fires a new PropertyChangeEvent to the - * PropertyChangeListeners registered with this instance in order - * to notify about a change in the value of a specific property which had - * its old value modified to a specific new value. - * - * @param property the name of the property of this instance which had its - * value changed - * @param oldValue the value of the property with the specified name before - * the change - * @param newValue the value of the property with the specified name after - * the change - */ - protected void firePropertyChange( - String property, - Object oldValue, - Object newValue) - { - propertyChangeSupport.firePropertyChange(property, oldValue, newValue); - } - - /** - * Returns the name of this stream or null if no name has been - * set. A stream name is used by some protocols, for diagnostic purposes - * mostly. In XMPP for example this is the name of the content element that - * describes a stream. - * - * @return the name of this stream or null if no name has been - * set. - */ - public String getName() - { - return name; - } - - /** - * Determines whether a specific MediaFormat has specific values - * for its properties mediaType, encoding, - * clockRate and channels for MediaFormats with - * mediaType equal to {@link MediaType#AUDIO}. - * - * @param format the {@link MediaFormat} whose properties we'd like to - * examine - * @param mediaType the type we expect {@link MediaFormat} to have - * @param encoding the encoding we are looking for. - * @param clockRate the clock rate that we'd like the format to have. - * @param channels the number of channels that expect to find in this format - * @param formatParameters the format parameters expected to match these of - * the specified format - * @return true if the specified format has specific - * values for its properties mediaType, encoding, - * clockRate and channels; otherwise, false - */ - public static boolean matches( - MediaFormat format, - MediaType mediaType, - String encoding, double clockRate, int channels, - Map formatParameters) - { - // mediaType - // encoding - if (!format.getMediaType().equals(mediaType) - || !format.getEncoding().equals(encoding)) - return false; - - // clockRate - if (clockRate != MediaFormatFactory.CLOCK_RATE_NOT_SPECIFIED) - { - double formatClockRate = format.getClockRate(); - - if ((formatClockRate != MediaFormatFactory.CLOCK_RATE_NOT_SPECIFIED) - && (formatClockRate != clockRate)) - return false; - } - - // channels - if (MediaType.AUDIO.equals(mediaType)) - { - if (channels == MediaFormatFactory.CHANNELS_NOT_SPECIFIED) - channels = 1; - - int formatChannels = ((AudioMediaFormat) format).getChannels(); - - if (formatChannels == MediaFormatFactory.CHANNELS_NOT_SPECIFIED) - formatChannels = 1; - if (formatChannels != channels) - return false; - } - - // formatParameters - return format.formatParametersMatch(formatParameters); - } - - /** - * Removes the specified PropertyChangeListener from this stream so - * that it won't receive further property change events. - * - * @param listener the PropertyChangeListener to remove - * @see MediaStream#removePropertyChangeListener(PropertyChangeListener) - */ - public void removePropertyChangeListener(PropertyChangeListener listener) - { - propertyChangeSupport.removePropertyChangeListener(listener); - } - - /** - * Sets the name of this stream. Stream names are used by some protocols, - * for diagnostic purposes mostly. In XMPP for example this is the name of - * the content element that describes a stream. - * - * @param name the name of this stream or null if no name has been - * set. - */ - public void setName(String name) - { - this.name = name; - } -} diff --git a/src/net/java/sip/communicator/service/neomedia/AudioMediaStream.java b/src/net/java/sip/communicator/service/neomedia/AudioMediaStream.java deleted file mode 100644 index e09a879e0..000000000 --- a/src/net/java/sip/communicator/service/neomedia/AudioMediaStream.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import net.java.sip.communicator.service.neomedia.event.*; -import net.java.sip.communicator.service.protocol.*; - -/** - * Extends the MediaStream interface and adds methods specific to - * audio streaming. - * - * @author Emil Ivov - */ -public interface AudioMediaStream - extends MediaStream -{ - /** - * Sets listener as the SimpleAudioLevelListener - * registered to receive notifications for changes in the levels of the - * party that's at the other end of this stream. - * - * @param listener the SimpleAudioLevelListener that we'd like to - * register or null if we want to stop stream audio level - * measurements. - */ - public void setStreamAudioLevelListener(SimpleAudioLevelListener listener); - - /** - * Registers listener as the CsrcAudioLevelListener that - * will receive notifications for changes in the levels of conference - * participants that the remote party could be mixing. - * - * @param listener the CsrcAudioLevelListener that we'd like to - * register or null if we'd like to stop receiving notifications. - */ - public void setCsrcAudioLevelListener(CsrcAudioLevelListener listener); - - /** - * Sets listener as the SimpleAudioLevelListener - * registered to receive notifications for changes in the levels of the - * audio that this stream is sending out. - * - * @param listener the SimpleAudioLevelListener that we'd like to - * register or null if we want to stop local audio level - * measurements. - */ - public void setLocalUserAudioLevelListener( - SimpleAudioLevelListener listener); - - /** - * Starts sending the specified DTMFTone until the - * stopSendingDTMF() method is called (Excepts for INBAND DTMF, - * which stops by itself this is why where there is no need to call the - * stopSendingDTMF). Callers should keep in mind the fact that calling this - * method would most likely interrupt all audio transmission until the - * corresponding stop method is called. Also, calling this method - * successively without invoking the corresponding stop method between the - * calls will simply replace the DTMFTone from the first call with - * that from the second. - * - * @param tone the DTMFTone to start sending. - * @param dtmfMethod The kind of DTMF used (RTP, SIP-INOF or INBAND). - */ - public void startSendingDTMF(DTMFTone tone, DTMFMethod dtmfMethod); - - /** - * Interrupts transmission of a DTMFTone started with the - * startSendingDTMF method. This method has no effect if no tone - * is being currently sent. - * - * @param dtmfMethod the DTMFMethod to stop sending. - */ - public void stopSendingDTMF(DTMFMethod dtmfMethod); - - /** - * Registers a listener that would receive notification events if the - * remote party starts sending DTMF tones to us. - * - * @param listener the DTMFListener that we'd like to register. - */ - public void addDTMFListener(DTMFListener listener); - - /** - * Removes listener from the list of DTMFListeners - * registered to receive events for incoming DTMF tones. - * - * @param listener the listener that we'd like to unregister - */ - public void removeDTMFListener(DTMFListener listener); -} diff --git a/src/net/java/sip/communicator/service/neomedia/DTMFInbandTone.java b/src/net/java/sip/communicator/service/neomedia/DTMFInbandTone.java deleted file mode 100644 index 8956fc60e..000000000 --- a/src/net/java/sip/communicator/service/neomedia/DTMFInbandTone.java +++ /dev/null @@ -1,423 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -/** - * Manages the generation of the inband DMTF signal. A signal is identified by a - * value (1, 2, 3, 4, 5, 6, 7, 8, 9, *, #, A, B, C and D) and each signal is - * produced by the composition of 2 frequencies (as defined below). - * (cf. ITU recommendation Q.23) - * - * +------------------------------------------------+ - * | | 1209 Hz | 1336 Hz | 1477 Hz | 1633 Hz | - * +------------------------------------------------+ - * | 697 Hz | 1 | 2 | 3 | A | - * | 770 Hz | 4 | 5 | 6 | B | - * | 852 Hz | 7 | 8 | 9 | C | - * | 941 Hz | * | 0 | # | D | - * +------------------------------------------------+ - * - * @author Vincent Lucas - */ -public class DTMFInbandTone -{ - /** - * The first set of frequencies in Hz which composes an inband DTMF. - */ - private static final double[] frequencyList1 = - new double[] - { - 697.0, 770.0, 852.0, 941.0 - }; - - /** - * The second set of frequencies in Hz which composes an inband DTMF. - */ - private static final double[] frequencyList2 = - new double[] - { - 1209.0, 1336.0, 1477.0, 1633.0 - }; - - /** - * The "0" DTMF Inband Tone. - */ - public static final DTMFInbandTone DTMF_INBAND_0 = new DTMFInbandTone("0", - frequencyList1[3], - frequencyList2[1]); - - /** - * The "1" DTMF Inband Tone. - */ - public static final DTMFInbandTone DTMF_INBAND_1 = new DTMFInbandTone("1", - frequencyList1[0], - frequencyList2[0]); - - /** - * The "2" DTMF Inband Tone. - */ - public static final DTMFInbandTone DTMF_INBAND_2 = new DTMFInbandTone("2", - frequencyList1[0], - frequencyList2[1]); - - /** - * The "3" DTMF Inband Tone. - */ - public static final DTMFInbandTone DTMF_INBAND_3 = new DTMFInbandTone("3", - frequencyList1[0], - frequencyList2[2]); - - /** - * The "4" DTMF Inband Tone. - */ - public static final DTMFInbandTone DTMF_INBAND_4 = new DTMFInbandTone("4", - frequencyList1[1], - frequencyList2[0]); - - /** - * The "5" DTMF Inband Tone. - */ - public static final DTMFInbandTone DTMF_INBAND_5 = new DTMFInbandTone("5", - frequencyList1[1], - frequencyList2[1]); - - /** - * The "6" DTMF Inband Tone. - */ - public static final DTMFInbandTone DTMF_INBAND_6 = new DTMFInbandTone("6", - frequencyList1[1], - frequencyList2[2]); - - /** - * The "7" DTMF Inband Tone. - */ - public static final DTMFInbandTone DTMF_INBAND_7 = new DTMFInbandTone("7", - frequencyList1[2], - frequencyList2[0]); - - /** - * The "8" DTMF Inband Tone. - */ - public static final DTMFInbandTone DTMF_INBAND_8 = new DTMFInbandTone("8", - frequencyList1[2], - frequencyList2[1]); - - /** - * The "9" DTMF Inband Tone. - */ - public static final DTMFInbandTone DTMF_INBAND_9 = new DTMFInbandTone("9", - frequencyList1[2], - frequencyList2[2]); - - /** - * The "*" DTMF Inband Tone. - */ - public static final DTMFInbandTone DTMF_INBAND_STAR = - new DTMFInbandTone("*", - frequencyList1[3], - frequencyList2[0]); - - /** - * The "#" DTMF Inband Tone. - */ - public static final DTMFInbandTone DTMF_INBAND_SHARP = - new DTMFInbandTone("#", - frequencyList1[3], - frequencyList2[2]); - - /** - * The "A" DTMF Inband Tone. - */ - public static final DTMFInbandTone DTMF_INBAND_A = new DTMFInbandTone("A", - frequencyList1[0], - frequencyList2[3]); - - /** - * The "B" DTMF Inband Tone. - */ - public static final DTMFInbandTone DTMF_INBAND_B = new DTMFInbandTone("B", - frequencyList1[1], - frequencyList2[3]); - - /** - * The "C" DTMF Inband Tone. - */ - public static final DTMFInbandTone DTMF_INBAND_C = new DTMFInbandTone("C", - frequencyList1[2], - frequencyList2[3]); - - /** - * The "D" DTMF Inband Tone. - */ - public static final DTMFInbandTone DTMF_INBAND_D = new DTMFInbandTone("D", - frequencyList1[3], - frequencyList2[3]); - - /** - * The default duration of an inband DTMF tone in ms. - * 50 ms c.f. - * http://nemesis.lonestar.org/reference/telecom/signaling/dtmf.html - * which cites the norm ANSI T1.401-1988 (but unavailable to me). - * But when testing it at 50 ms, the asterisk servers miss some DTMF tone - * impulses. Thus, set it up 150 ms. - */ - private static final int toneDuration = 150; - - /** - * The default duration of an inband DTMF tone in ms. - * 45 ms c.f. - * http://nemesis.lonestar.org/reference/telecom/signaling/dtmf.html - * which cites the norm ANSI T1.401-1988 (but unavailable to me). - * Moreover the minimum duty cycle (signal tone + silence) for - * ANSI-compliance shall be greater or equal to 100 ms. - */ - private static final int interDigitInterval = 45; - - /** - * The value which identifies the current inband tone. Available values are - * (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, *, #, A, B, C and D). - */ - private String value; - - /** - * The first frequency which composes the current inband tone. - */ - private double frequency1; - - /** - * The second frequency which composes the current inband tone. - */ - private double frequency2; - - /** - * Creates a new instance of an inband tone. The value given is the main - * identifier which determines which are the two frequencies to used to - * generate this tone. - * - * @param value The identifier of the tone. Available values are (0, 1, 2, - * 3, 4, 5, 6, 7, 8, 9, *, #, A, B, C and D). - * @param frequency1 The first frequency which composes the tone. Available - * values corresponds to DTMFInbandTone.frequencyList1. - * @param frequency2 The second frequency which composes the tone. Available - * values corresponds to DTMFInbandTone.frequencyList2. - */ - public DTMFInbandTone(String value, double frequency1, double frequency2) - { - this.value = value; - this.frequency1 = frequency1; - this.frequency2 = frequency2; - } - - /** - * Returns this tone value as a string representation. - * - * @return this tone value. - */ - public String getValue() - { - return this.value; - } - - /** - * Returns the first frequency coded by this tone. - * - * @return the first frequency coded by this tone. - */ - public double getFrequency1() - { - return this.frequency1; - } - - /** - * Returns the second frequency coded by this tone. - * - * @return the second frequency coded by this tone. - */ - public double getFrequency2() - { - return this.frequency2; - } - - /** - * Generates a sample for the current tone signal. - * - * @param samplingFrequency The sampling frequency (codec clock rate) in Hz - * of the stream which will encapsulate this signal. - * @param sampleNumber The sample number of this signal to be produced. The - * sample number corresponds to the abscissa of the signal function. - * - * @return the sample generated. This sample corresponds to the ordinate of - * the signal function - */ - public double getAudioSampleContinuous( - double samplingFrequency, - int sampleNumber) - { - double u1 = 2.0 * Math.PI * this.frequency1 / samplingFrequency; - double u2 = 2.0 * Math.PI * this.frequency2 / samplingFrequency; - double audioSample; - - // The signal generated is composed of 2 sinusoidal signals, which - // ampltudes is between -1 and 1 (included). - audioSample = Math.sin(u1 * sampleNumber) * 0.5 + - Math.sin(u2 * sampleNumber) * 0.5; - - return audioSample; - } - - /** - * Generates a sample for the current tone signal converted into a discrete - * signal. - * - * @param samplingFrequency The sampling frequency (codec clock rate) in Hz - * of the stream which will encapsulate this signal. - * @param sampleNumber The sample number of this signal to be produced. The - * sample number corresponds to the abscissa of the signal function. - * @param sampleSizeInBits The size of each sample (8 for a byte, 16 for a - * short and 32 for an int) - * - * @return the sample generated. This sample corresponds to the ordinate of - * the signal function - */ - public int getAudioSampleDiscrete( - double samplingFrequency, - int sampleNumber, - int sampleSizeInBits) - { - // If the param sampleSizeInBits is equal to 8, then its corresponds to - // a Java byte which is 8 bits signed type which contains a number - // between -128 and 127. Thus, as the result of the continuous function - // is between -1 and 1, we multiply each audioSample by 127. This - // generates a signal between -127 and 127. - // Same operation if sampleSizeInBits is equal to 16, this function - // generates a signal between -32767 and 32767. - // As well as if sampleSizeInBits is equal to 32, this function - // generates a signal between -2147483647 and 2147483647. - double amplitudeCoefficient = Math.pow(2.0, sampleSizeInBits - 1) - 1.0; - double audioSampleContinuous; - int audioSampleDiscrete; - - audioSampleContinuous = this.getAudioSampleContinuous( - samplingFrequency, - sampleNumber); - audioSampleDiscrete = (int) - (audioSampleContinuous * amplitudeCoefficient); - - return audioSampleDiscrete; - } - - /** - * Generates a signal sample for the current tone signal and stores it into - * the byte data array. - * - * @param samplingFrequency The sampling frequency (codec clock rate) in Hz - * of the stream which will encapsulate this signal. - * @param sampleSizeInBits The size of each sample (8 for a byte, 16 for a - * short and 32 for an int) - * - * @return The data array containing the DTMF signal. - */ - public int[] getAudioSamples( - double samplingFrequency, - int sampleSizeInBits) - { - int sampleNumber = 0; - - int nbToneSamples = ((int) (samplingFrequency / 1000.0)) * - DTMFInbandTone.toneDuration; - int nbInterDigitSamples = ((int) (samplingFrequency / 1000.0)) * - DTMFInbandTone.interDigitInterval; - - int[] sampleData = - new int[nbInterDigitSamples + nbToneSamples + nbInterDigitSamples]; - - while(sampleNumber < nbInterDigitSamples) - { - sampleData[sampleNumber] = 0; - ++sampleNumber; - } - while(sampleNumber < nbInterDigitSamples + nbToneSamples) - { - sampleData[sampleNumber] = getAudioSampleDiscrete( - samplingFrequency, - sampleNumber, - sampleSizeInBits); - - ++sampleNumber; - } - while(sampleNumber < sampleData.length) - { - sampleData[sampleNumber] = 0; - ++sampleNumber; - } - - return sampleData; - } - - /** - * Maps between protocol and media inband DTMF objects. - * @param tone The DTMF tone as defined in the service protocol, which is - * only composed by a value as its identifier. - * - * @return the corresponding DTMF tone which contains a value as an - * identifier and two frequencies composing the inband tone. - */ - public static DTMFInbandTone - mapTone(net.java.sip.communicator.service.protocol.DTMFTone tone) - { - if(tone.equals( - net.java.sip.communicator.service.protocol.DTMFTone.DTMF_0)) - return DTMFInbandTone.DTMF_INBAND_0; - else if(tone.equals( - net.java.sip.communicator.service.protocol.DTMFTone.DTMF_1)) - return DTMFInbandTone.DTMF_INBAND_1; - else if(tone.equals( - net.java.sip.communicator.service.protocol.DTMFTone.DTMF_2)) - return DTMFInbandTone.DTMF_INBAND_2; - else if(tone.equals( - net.java.sip.communicator.service.protocol.DTMFTone.DTMF_3)) - return DTMFInbandTone.DTMF_INBAND_3; - else if(tone.equals( - net.java.sip.communicator.service.protocol.DTMFTone.DTMF_4)) - return DTMFInbandTone.DTMF_INBAND_4; - else if(tone.equals( - net.java.sip.communicator.service.protocol.DTMFTone.DTMF_5)) - return DTMFInbandTone.DTMF_INBAND_5; - else if(tone.equals( - net.java.sip.communicator.service.protocol.DTMFTone.DTMF_6)) - return DTMFInbandTone.DTMF_INBAND_6; - else if(tone.equals( - net.java.sip.communicator.service.protocol.DTMFTone.DTMF_7)) - return DTMFInbandTone.DTMF_INBAND_7; - else if(tone.equals( - net.java.sip.communicator.service.protocol.DTMFTone.DTMF_8)) - return DTMFInbandTone.DTMF_INBAND_8; - else if(tone.equals( - net.java.sip.communicator.service.protocol.DTMFTone.DTMF_9)) - return DTMFInbandTone.DTMF_INBAND_9; - else if(tone.equals( - net.java.sip.communicator.service.protocol.DTMFTone.DTMF_A)) - return DTMFInbandTone.DTMF_INBAND_A; - else if(tone.equals( - net.java.sip.communicator.service.protocol.DTMFTone.DTMF_B)) - return DTMFInbandTone.DTMF_INBAND_B; - else if(tone.equals( - net.java.sip.communicator.service.protocol.DTMFTone.DTMF_C)) - return DTMFInbandTone.DTMF_INBAND_C; - else if(tone.equals( - net.java.sip.communicator.service.protocol.DTMFTone.DTMF_D)) - return DTMFInbandTone.DTMF_INBAND_D; - else if(tone.equals( - net.java.sip.communicator.service.protocol.DTMFTone.DTMF_SHARP)) - return DTMFInbandTone.DTMF_INBAND_SHARP; - else if(tone.equals( - net.java.sip.communicator.service.protocol.DTMFTone.DTMF_STAR)) - return DTMFInbandTone.DTMF_INBAND_STAR; - - return null; - } -} diff --git a/src/net/java/sip/communicator/service/neomedia/DTMFMethod.java b/src/net/java/sip/communicator/service/neomedia/DTMFMethod.java deleted file mode 100644 index b589c0248..000000000 --- a/src/net/java/sip/communicator/service/neomedia/DTMFMethod.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -/** - * Enumerates all available DTMF methods. - * - * @author Vincent Lucas - */ -public enum DTMFMethod -{ - /** - * {@link #RTP_DTMF} if telephony-event are available; otherwise, - * {@link #INBAND_DTMF}. - */ - AUTO_DTMF, - - /** RTP DTMF as defined in RFC4733. */ - RTP_DTMF, - - /** SIP INFO DTMF. */ - SIP_INFO_DTMF, - - /** INBAND DTMF as defined in ITU-T recommendation Q.23. */ - INBAND_DTMF -} diff --git a/src/net/java/sip/communicator/service/neomedia/DTMFRtpTone.java b/src/net/java/sip/communicator/service/neomedia/DTMFRtpTone.java deleted file mode 100644 index 07bb772b9..000000000 --- a/src/net/java/sip/communicator/service/neomedia/DTMFRtpTone.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import net.java.sip.communicator.service.protocol.*; - -/** - * Represents all DTMF tones for RTP method (RFC4733). - * - * @author JM HEITZ - * @author Romain Philibert - * @author Emil Ivov - */ -public final class DTMFRtpTone -{ - /** - * The "0" DTMF Tone - */ - public static final DTMFRtpTone DTMF_0=new DTMFRtpTone("0", (byte)0); - - /** - * The "1" DTMF Tone - */ - public static final DTMFRtpTone DTMF_1=new DTMFRtpTone("1", (byte)1); - - /** - * The "2" DTMF Tone - */ - public static final DTMFRtpTone DTMF_2=new DTMFRtpTone("2", (byte)2); - - /** - * The "3" DTMF Tone - */ - public static final DTMFRtpTone DTMF_3=new DTMFRtpTone("3", (byte)3); - - /** - * The "4" DTMF Tone - */ - public static final DTMFRtpTone DTMF_4=new DTMFRtpTone("4", (byte)4); - - /** - * The "5" DTMF Tone - */ - public static final DTMFRtpTone DTMF_5=new DTMFRtpTone("5", (byte)5); - - /** - * The "6" DTMF Tone - */ - public static final DTMFRtpTone DTMF_6=new DTMFRtpTone("6", (byte)6); - - /** - * The "7" DTMF Tone - */ - public static final DTMFRtpTone DTMF_7=new DTMFRtpTone("7", (byte)7); - - /** - * The "8" DTMF Tone - */ - public static final DTMFRtpTone DTMF_8=new DTMFRtpTone("8", (byte)8); - - /** - * The "9" DTMF Tone - */ - public static final DTMFRtpTone DTMF_9=new DTMFRtpTone("9", (byte)9); - - /** - * The "*" DTMF Tone - */ - public static final DTMFRtpTone DTMF_STAR=new DTMFRtpTone("*", (byte)10); - - /** - * The "#" DTMF Tone - */ - public static final DTMFRtpTone DTMF_SHARP=new DTMFRtpTone("#", (byte)11); - - /** - * The "A" DTMF Tone - */ - public static final DTMFRtpTone DTMF_A=new DTMFRtpTone("A", (byte)12); - - /** - * The "B" DTMF Tone - */ - public static final DTMFRtpTone DTMF_B=new DTMFRtpTone("B", (byte)13); - - /** - * The "C" DTMF Tone - */ - public static final DTMFRtpTone DTMF_C=new DTMFRtpTone("C", (byte)14); - - /** - * The "D" DTMF Tone - */ - public static final DTMFRtpTone DTMF_D=new DTMFRtpTone("D", (byte)15); - - /** - * The value of the DTMF tone - */ - private final String value; - - /** - * The code of the tone, as specified by RFC 4733, and the we'll actually - * be sending over the wire. - */ - private final byte code; - - /** - * Creates a DTMF instance with the specified tone value. The method is - * private since one would only have to use predefined static instances. - * - * @param value one of the DTMF_XXX fields, indicating the value of the tone. - * @param code the of the DTMF tone that we'll actually be sending over the - * wire, as specified by RFC 4733. - */ - private DTMFRtpTone(String value, byte code) - { - this.value = value; - this.code = code; - } - - /** - * Returns the string representation of this DTMF tone. - * - * @return the String representation of this DTMF tone. - */ - public String getValue() - { - return this.value; - } - - /** - * Indicates whether some other object is "equal to" this tone. - * - * @param target the reference object with which to compare. - * - * @return true if target represents the same tone as this - * object. - */ - public boolean equals(Object target) - { - if(!(target instanceof DTMFRtpTone)) - { - return false; - } - DTMFRtpTone targetDTMFTone = (DTMFRtpTone)(target); - - return targetDTMFTone.value.equals(this.value); - } - - /** - * Returns a hash code value for the object. This method is - * supported for the benefit of hashtables such as those provided by - * java.util.Hashtable. The method would actually return the - * hashcode of the string representation of this DTMF tone. - * - * @return a hash code value for this object (same as calling - * getValue().hashCode()). - */ - public int hashCode() - { - return getValue().hashCode(); - } - - /** - * Returns the RFC 4733 code of this DTMF tone. - * - * @return the RFC 4733 code of this DTMF tone. - */ - public byte getCode() - { - return code; - } - - /** - * Maps between protocol and media DTMF objects. - * @param tone The DTMFTone to be mapped to an DTMFRtpTone. - * @return The DTMFRtpTone corresponding to the tone specified. - */ - public static DTMFRtpTone mapTone(DTMFTone tone) - { - if(tone.equals(DTMFTone.DTMF_0)) - return DTMFRtpTone.DTMF_0; - else if(tone.equals(DTMFTone.DTMF_1)) - return DTMFRtpTone.DTMF_1; - else if(tone.equals(DTMFTone.DTMF_2)) - return DTMFRtpTone.DTMF_2; - else if(tone.equals(DTMFTone.DTMF_3)) - return DTMFRtpTone.DTMF_3; - else if(tone.equals(DTMFTone.DTMF_4)) - return DTMFRtpTone.DTMF_4; - else if(tone.equals(DTMFTone.DTMF_5)) - return DTMFRtpTone.DTMF_5; - else if(tone.equals(DTMFTone.DTMF_6)) - return DTMFRtpTone.DTMF_6; - else if(tone.equals(DTMFTone.DTMF_7)) - return DTMFRtpTone.DTMF_7; - else if(tone.equals(DTMFTone.DTMF_8)) - return DTMFRtpTone.DTMF_8; - else if(tone.equals(DTMFTone.DTMF_9)) - return DTMFRtpTone.DTMF_9; - else if(tone.equals(DTMFTone.DTMF_A)) - return DTMFRtpTone.DTMF_A; - else if(tone.equals(DTMFTone.DTMF_B)) - return DTMFRtpTone.DTMF_B; - else if(tone.equals(DTMFTone.DTMF_C)) - return DTMFRtpTone.DTMF_C; - else if(tone.equals(DTMFTone.DTMF_D)) - return DTMFRtpTone.DTMF_D; - else if(tone.equals(DTMFTone.DTMF_SHARP)) - return DTMFRtpTone.DTMF_SHARP; - else if(tone.equals(DTMFTone.DTMF_STAR)) - return DTMFRtpTone.DTMF_STAR; - - return null; - } -} diff --git a/src/net/java/sip/communicator/service/neomedia/DefaultStreamConnector.java b/src/net/java/sip/communicator/service/neomedia/DefaultStreamConnector.java deleted file mode 100644 index fc7096df1..000000000 --- a/src/net/java/sip/communicator/service/neomedia/DefaultStreamConnector.java +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import java.net.*; - -import net.java.sip.communicator.impl.neomedia.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.util.*; - -/** - * Represents a default implementation of StreamConnector which is - * initialized with a specific pair of control and data DatagramSockets - * and which closes them (if they exist) when its {@link #close()} is invoked. - * - * @author Lubomir Marinov - */ -public class DefaultStreamConnector - implements StreamConnector -{ - - /** - * The Logger used by the DefaultStreamConnector class and - * its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(DefaultStreamConnector.class); - - /** - * The default number of binds that a Media Service Implementation should - * execute in case a port is already bound to (each retry would be on a - * new random port). - */ - public static final int BIND_RETRIES_DEFAULT_VALUE = 50; - - /** - * The name of the property containing the number of binds that a Media - * Service Implementation should execute in case a port is already - * bound to (each retry would be on a new port in the allowed boundaries). - */ - public static final String BIND_RETRIES_PROPERTY_NAME - = "net.java.sip.communicator.service.media.BIND_RETRIES"; - - /** - * The name of the property that contains the maximum port number that we'd - * like our RTP managers to bind upon. - */ - public static final String MAX_PORT_NUMBER_PROPERTY_NAME - = "net.java.sip.communicator.service.media.MAX_PORT_NUMBER"; - - /** - * The maximum port number DefaultStreamConnector instances are to - * attempt to bind to. - */ - private static int maxPort = -1; - - /** - * The name of the property that contains the minimum port number that we'd - * like our RTP managers to bind upon. - */ - public static final String MIN_PORT_NUMBER_PROPERTY_NAME - = "net.java.sip.communicator.service.media.MIN_PORT_NUMBER"; - - /** - * The minimum port number DefaultStreamConnector instances are to - * attempt to bind to. - */ - private static int minPort = -1; - - /** - * The local InetAddress this StreamConnector attempts to - * bind to on demand. - */ - private final InetAddress bindAddr; - - /** - * The DatagramSocket that a stream should use for control data - * (e.g. RTCP) traffic. - */ - protected DatagramSocket controlSocket; - - /** - * The DatagramSocket that a stream should use for data (e.g. RTP) - * traffic. - */ - protected DatagramSocket dataSocket; - - /** - * Initializes a new DefaultStreamConnector instance with no - * control and data DatagramSockets. - *

- * Suitable for extenders willing to delay the creation of the control and - * data sockets. For example, they could override - * {@link #getControlSocket()} and/or {@link #getDataSocket()} and create - * them on demand. - */ - public DefaultStreamConnector() - { - this(null, null); - } - - /** - * Creates a new DatagramSocket instance which is bound to the - * specified local InetAddress and its port is within the range - * defined by the ConfigurationService properties - * {@link #MIN_PORT_NUMBER_PROPERTY_NAME} and - * {@link #MAX_PORT_NUMBER_PROPERTY_NAME}. Attempts at most - * {@link #BIND_RETRIES_PROPERTY_NAME} times to bind. - * - * @param bindAddr the local InetAddress the new - * DatagramSocket is to bind to - * @return a new DatagramSocket instance bound to the specified - * local InetAddress - */ - private static synchronized DatagramSocket createDatagramSocket( - InetAddress bindAddr) - { - ConfigurationService cfg = NeomediaActivator.getConfigurationService(); - int bindRetries = BIND_RETRIES_DEFAULT_VALUE; - - if (cfg != null) - bindRetries = cfg.getInt(BIND_RETRIES_PROPERTY_NAME, bindRetries); - if (maxPort < 0) - { - maxPort = 6000; - if (cfg != null) - maxPort = cfg.getInt(MAX_PORT_NUMBER_PROPERTY_NAME, maxPort); - } - - for (int i = 0; i < bindRetries; i++) - { - if ((minPort < 0) || (minPort > maxPort)) - { - minPort = 5000; - if (cfg != null) - { - minPort - = cfg.getInt(MIN_PORT_NUMBER_PROPERTY_NAME, minPort); - } - } - - int port = minPort++; - - try - { - return - (bindAddr == null) - ? new DatagramSocket(port) - : new DatagramSocket(port, bindAddr); - } - catch (SocketException se) - { - logger.warn( - "Retrying a bind because of a failure to bind to address " - + bindAddr - + " and port " - + port, - se); - } - } - return null; - } - - /** - * Initializes a new DefaultStreamConnector instance with a - * specific bind InetAddress. The new instance is to attempt to - * bind on demand to the specified InetAddress in the port range - * defined by the ConfigurationService properties - * {@link #MIN_PORT_NUMBER_PROPERTY_NAME} and - * {@link #MAX_PORT_NUMBER_PROPERTY_NAME} at most - * {@link #BIND_RETRIES_PROPERTY_NAME} times. - * - * @param bindAddr the local InetAddress the new instance is to - * attempt to bind to - */ - public DefaultStreamConnector(InetAddress bindAddr) - { - this.bindAddr = bindAddr; - } - - /** - * Initializes a new DefaultStreamConnector instance which is to - * represent a specific pair of control and data DatagramSockets. - * - * @param dataSocket the DatagramSocket to be used for data (e.g. - * RTP) traffic - * @param controlSocket the DatagramSocket to be used for control - * data (e.g. RTCP) traffic - */ - public DefaultStreamConnector( - DatagramSocket dataSocket, - DatagramSocket controlSocket) - { - this.controlSocket = controlSocket; - this.dataSocket = dataSocket; - this.bindAddr = null; - } - - /** - * Releases the resources allocated by this instance in the course of its - * execution and prepares it to be garbage collected. - * - * @see StreamConnector#close() - */ - public void close() - { - if (controlSocket != null) - controlSocket.close(); - if (dataSocket != null) - dataSocket.close(); - } - - /** - * Returns a reference to the DatagramSocket that a stream should - * use for control data (e.g. RTCP) traffic. - * - * @return a reference to the DatagramSocket that a stream should - * use for control data (e.g. RTCP) traffic - * @see StreamConnector#getControlSocket() - */ - public DatagramSocket getControlSocket() - { - if ((controlSocket == null) && (bindAddr != null)) - controlSocket = createDatagramSocket(bindAddr); - return controlSocket; - } - - /** - * Returns a reference to the DatagramSocket that a stream should - * use for data (e.g. RTP) traffic. - * - * @return a reference to the DatagramSocket that a stream should - * use for data (e.g. RTP) traffic - * @see StreamConnector#getDataSocket() - */ - public DatagramSocket getDataSocket() - { - if ((dataSocket == null) && (bindAddr != null)) - dataSocket = createDatagramSocket(bindAddr); - return dataSocket; - } - - /** - * Returns a reference to the Socket that a stream should - * use for data (e.g. RTP) traffic. - * - * @return a reference to the Socket that a stream should - * use for data (e.g. RTP) traffic. - */ - public Socket getDataTCPSocket() - { - return null; - } - - /** - * Returns a reference to the Socket that a stream should - * use for control data (e.g. RTCP). - * - * @return a reference to the Socket that a stream should - * use for control data (e.g. RTCP). - */ - public Socket getControlTCPSocket() - { - return null; - } - - /** - * Returns the protocol of this StreamConnector. - * - * @return the protocol of this StreamConnector - */ - public Protocol getProtocol() - { - return Protocol.UDP; - } - - /** - * Notifies this instance that utilization of its DatagramSockets - * for data and/or control traffic has started. - * - * @see StreamConnector#started() - */ - public void started() - { - } - - /** - * Notifies this instance that utilization of its DatagramSockets - * for data and/or control traffic has temporarily stopped. This instance - * should be prepared to be started at a later time again though. - * - * @see StreamConnector#stopped() - */ - public void stopped() - { - } -} diff --git a/src/net/java/sip/communicator/service/neomedia/DefaultTCPStreamConnector.java b/src/net/java/sip/communicator/service/neomedia/DefaultTCPStreamConnector.java deleted file mode 100644 index 169ce2c25..000000000 --- a/src/net/java/sip/communicator/service/neomedia/DefaultTCPStreamConnector.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import java.io.*; -import java.net.*; - -import net.java.sip.communicator.util.*; - -/** - * Represents a default implementation of StreamConnector which is - * initialized with a specific pair of control and data Sockets - * and which closes them (if they exist) when its {@link #close()} is invoked. - * - * @author Lubomir Marinov - * @author Sebastien Vincent - */ -public class DefaultTCPStreamConnector - implements StreamConnector -{ - - /** - * The Logger used by the DefaultTCPStreamConnector class and - * its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(DefaultTCPStreamConnector.class); - - /** - * The Socket that a stream should use for control data - * (e.g. RTCP) traffic. - */ - protected Socket controlSocket; - - /** - * The Socket that a stream should use for data (e.g. RTP) - * traffic. - */ - protected Socket dataSocket; - - /** - * Initializes a new DefaultTCPStreamConnector instance with no - * control and data Sockets. - *

- * Suitable for extenders willing to delay the creation of the control and - * data sockets. For example, they could override - * {@link #getControlSocket()} and/or {@link #getDataSocket()} and create - * them on demand. - */ - public DefaultTCPStreamConnector() - { - this(null, null); - } - - /** - * Initializes a new DefaultTCPStreamConnector instance which is to - * represent a specific pair of control and data Sockets. - * - * @param dataSocket the Socket to be used for data (e.g. - * RTP) traffic - * @param controlSocket the Socket to be used for control - * data (e.g. RTCP) traffic - */ - public DefaultTCPStreamConnector( - Socket dataSocket, - Socket controlSocket) - { - this.controlSocket = controlSocket; - this.dataSocket = dataSocket; - } - - /** - * Releases the resources allocated by this instance in the course of its - * execution and prepares it to be garbage collected. - * - * @see StreamConnector#close() - */ - public void close() - { - try - { - if (controlSocket != null) - controlSocket.close(); - if (dataSocket != null) - dataSocket.close(); - } - catch(IOException ioe) - { - logger.debug("Failed to close TCP socket", ioe); - } - } - - /** - * Returns a reference to the DatagramSocket that a stream should - * use for control data (e.g. RTCP) traffic. - * - * @return a reference to the DatagramSocket that a stream should - * use for control data (e.g. RTCP) traffic - * @see StreamConnector#getControlSocket() - */ - public DatagramSocket getControlSocket() - { - return null; - } - - /** - * Returns a reference to the DatagramSocket that a stream should - * use for data (e.g. RTP) traffic. - * - * @return a reference to the DatagramSocket that a stream should - * use for data (e.g. RTP) traffic - * @see StreamConnector#getDataSocket() - */ - public DatagramSocket getDataSocket() - { - return null; - } - - /** - * Returns a reference to the Socket that a stream should - * use for data (e.g. RTP) traffic. - * - * @return a reference to the Socket that a stream should - * use for data (e.g. RTP) traffic. - */ - public Socket getDataTCPSocket() - { - return dataSocket; - } - - /** - * Returns a reference to the Socket that a stream should - * use for control data (e.g. RTCP). - * - * @return a reference to the Socket that a stream should - * use for control data (e.g. RTCP). - */ - public Socket getControlTCPSocket() - { - return controlSocket; - } - - /** - * Returns the protocol of this StreamConnector. - * - * @return the protocol of this StreamConnector - */ - public Protocol getProtocol() - { - return Protocol.TCP; - } - - /** - * Notifies this instance that utilization of its Sockets - * for data and/or control traffic has started. - * - * @see StreamConnector#started() - */ - public void started() - { - } - - /** - * Notifies this instance that utilization of its Sockets - * for data and/or control traffic has temporarily stopped. This instance - * should be prepared to be started at a later time again though. - * - * @see StreamConnector#stopped() - */ - public void stopped() - { - } -} \ No newline at end of file diff --git a/src/net/java/sip/communicator/service/neomedia/MediaDirection.java b/src/net/java/sip/communicator/service/neomedia/MediaDirection.java deleted file mode 100644 index 4d44fe7f8..000000000 --- a/src/net/java/sip/communicator/service/neomedia/MediaDirection.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -/** - * The MediaDirections enumeration contains a list of media directions - * that indicate read/write capabilities of different entities in this - * MediaService such as for example devices. - * - * @author Emil Ivov - */ -public enum MediaDirection -{ - /** - * Indicates that the related entity does not support neither input - * nor output (i.e. neither send nor receive) operations. - */ - INACTIVE("inactive"), - - /** - * Represents a direction from the entity that this direction pertains to - * to the outside. When applied to a MediaDevice the direction - * indicates that the device is a read-only one. In the case of a stream - * a SENDONLY direction indicates that the stream is only sending - * data to the remote party without receiving. - */ - SENDONLY("sendonly"), - - /** - * Represents a direction pointing to the entity that this object pertains - * to and from the outside. When applied to a MediaDevice the - * direction indicates that the device is a write-only one. In the case of a - * MediaStream a RECVONLY direction indicates that the - * stream is only receiving data from the remote party without sending - * any. - */ - RECVONLY("recvonly"), - - /** - * Indicates that the related entity supports both input and output (send - * and receive) operations. - */ - SENDRECV("sendrecv"); - - /** - * The name of this direction. - */ - private final String directionName; - - /** - * Creates a MediaDirection instance with the specified name. - * - * @param directionName the name of the MediaDirections we'd like - * to create. - */ - private MediaDirection(String directionName) - { - this.directionName = directionName; - } - - /** - * Returns the name of this MediaDirection (e.g. "sendonly" or - * "sendrecv"). The name returned by this method is meant for use by - * session description mechanisms such as SIP/SDP or XMPP/Jingle. - * - * @return the name of this MediaDirection (e.g. "sendonly", - * "recvonly", "sendrecv"). - */ - @Override - public String toString() - { - return directionName; - } - - /** - * Applies an extra direction constraint to this MediaDirection - * or in other words performs an and operation. This method is - * primarily meant for use by the - * getReverseMediaDirection(MediaDirection) method while working - * on Offer/Answer media negotiation.. - * - * @param direction that direction constraint that we'd like to apply to - * this MediaDirection - * - * @return the new MediaDirection obtained after applying the - * direction constraint to this MediaDirection. - */ - public MediaDirection and(MediaDirection direction) - { - if (this == SENDRECV) - { - return direction; - } - else if( this == SENDONLY) - { - if (direction == SENDONLY || direction == SENDRECV) - return SENDONLY; - else - return INACTIVE; - } - else if( this == RECVONLY) - { - if (direction == RECVONLY || direction == SENDRECV) - return RECVONLY; - else - return INACTIVE; - } - else - return INACTIVE; - } - - /** - * Reverses a direction constraint on this MediaDirection - * or in other words performs an or operation. This method is - * meant for use in cases like putting a stream off hold or in other words - * reversing the SENDONLY constraint. - * - * @param direction the direction that we'd like to enable (i.e. add) to - * this MediaDirection - * - * @return the new MediaDirection obtained after adding the - * specified direction this MediaDirection. - */ - public MediaDirection or(MediaDirection direction) - { - if (this == SENDRECV) - { - return this; - } - else if( this == SENDONLY) - { - if( direction.allowsReceiving()) - return SENDRECV; - else - return this; - } - else if( this == RECVONLY) - { - if( direction.allowsSending()) - return SENDRECV; - else - return this; - } - else // INACTIVE - return direction; - } - - /** - * Returns the MediaDirection value corresponding to a remote - * party's perspective of this MediaDirection. In other words, - * if I say I'll be sending only, for you this means that you'll be - * receiving only. If however, I say I'll be both sending and receiving - * (i.e. SENDRECV) then it means you'll be doing the same (i.e. - * again SENDRECV). - * - * @return the MediaDirection value corresponding to a remote - * party's perspective of this MediaDirection. - */ - public MediaDirection getReverseDirection() - { - if (this == SENDRECV) - { - return SENDRECV; - } - else if(this == SENDONLY) - { - return RECVONLY; - } - else if (this == RECVONLY) - { - return SENDONLY; - } - else - { - return INACTIVE; - } - } - - /** - * Returns the MediaDirection value corresponding to a remote - * party's perspective of this MediaDirection applying a remote - * party constraint. In other words, if I say I'll only be sending media - * (i.e. SENDONLY) and you know that you can both send and receive - * (i.e. SENDRECV) then to you this mean that you'll be only - * receiving media (i.e. RECVONLY). If however I say that I can - * only receive a particular media type (i.e. RECVONLY) and you - * are in the same situation then this means that neither of us would be - * sending nor receiving and the stream would appear INACTIVE to - * you (and me for that matter). The method is meant for use during - * Offer/Answer SDP negotiation. - * - * @param remotePartyDir the remote party MediaDirection constraint - * that we'd have to consider when trying to obtain a - * MediaDirection corresponding to remoteParty's constraint. - * - * @return the MediaDirection value corresponding to a remote - * party's perspective of this MediaDirection applying a remote - * party constraint. - */ - public MediaDirection getDirectionForAnswer(MediaDirection remotePartyDir) - { - return this.and(remotePartyDir.getReverseDirection()); - } - - /** - * Determines whether the directions specified by this - * MediaDirection instance allow for outgoing (i.e. sending) - * streams or in other words whether this is a SENDONLY or a - * SENDRECV instance - * - * @return true if this MediaDirection instance includes - * the possibility of sending and false otherwise. - */ - public boolean allowsSending() - { - return this == SENDONLY || this == SENDRECV; - } - - /** - * Determines whether the directions specified by this - * MediaDirection instance allow for incoming (i.e. receiving) - * streams or in other words whether this is a RECVONLY or a - * SENDRECV instance - * - * @return true if this MediaDirection instance includes - * the possibility of receiving and false otherwise. - */ - public boolean allowsReceiving() - { - return this == RECVONLY || this == SENDRECV; - } - - /** - * Returns a MediaDirection value corresponding to the specified - * mediaDirectionStr or in other words SENDONLY for - * "sendonly", RECVONLY for "recvonly", SENDRECV for - * "sendrecv", and INACTIVE for "inactive". - * - * @param mediaDirectionStr the direction String that we'd like to - * parse. - * @return a MediaDirection value corresponding to the specified - * mediaDirectionStr. - * - * @throws IllegalArgumentException in case mediaDirectionStr is - * not a valid media direction. - */ - public static MediaDirection parseString(String mediaDirectionStr) - throws IllegalArgumentException - { - for (MediaDirection value : values()) - if (value.toString().equals(mediaDirectionStr)) - return value; - - throw new IllegalArgumentException( - mediaDirectionStr + " is not a valid media direction"); - } -} diff --git a/src/net/java/sip/communicator/service/neomedia/MediaException.java b/src/net/java/sip/communicator/service/neomedia/MediaException.java deleted file mode 100644 index f60c3aeeb..000000000 --- a/src/net/java/sip/communicator/service/neomedia/MediaException.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -/** - * Implements an Exception thrown by the neomedia service interfaces - * and their implementations. MediaException carries an error code in - * addition to the standard Exception properties which gives more - * information about the specifics of the particular MediaException. - * - * @author Lubomir Marinov - */ -public class MediaException - extends Exception -{ - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * The error code value which specifies that the MediaException - * carrying it does not give more information about its specifics. - */ - public static final int GENERAL_ERROR = 1; - - /** - * The error code carried by this MediaException which gives more - * information about the specifics of this MediaException. - */ - private final int errorCode; - - /** - * Initializes a new MediaException instance with a specific - * detailed message and {@link #GENERAL_ERROR} error code. - * - * @param message the detailed message to initialize the new instance with - */ - public MediaException(String message) - { - this(message, GENERAL_ERROR); - } - - /** - * Initializes a new MediaException instance with a specific - * detailed message and a specific error code. - * - * @param message the detailed message to initialize the new instance with - * @param errorCode the error code which is to give more information about - * the specifics of the new instance - */ - public MediaException(String message, int errorCode) - { - super(message); - - this.errorCode = errorCode; - } - - /** - * Initializes a new MediaException instance with a specific - * detailed message, {@link #GENERAL_ERROR} error code and a specific - * Throwable cause. - * - * @param message the detailed message to initialize the new instance with - * @param cause the Throwable which is to be carried by the new - * instance and which is to be reported as the cause for throwing the new - * instance. If cause is null, the cause for throwing the - * new instance is considered to be unknown. - */ - public MediaException(String message, Throwable cause) - { - this(message, GENERAL_ERROR, cause); - } - - /** - * Initializes a new MediaException instance with a specific - * detailed message, a specific error code and a specific Throwable - * cause. - * - * @param message the detailed message to initialize the new instance with - * @param errorCode the error code which is to give more information about - * the specifics of the new instance - * @param cause the Throwable which is to be carried by the new - * instance and which is to be reported as the cause for throwing the new - * instance. If cause is null, the cause for throwing the - * new instance is considered to be unknown. - */ - public MediaException(String message, int errorCode, Throwable cause) - { - super(message, cause); - - this.errorCode = errorCode; - } - - /** - * Gets the error code carried by this MediaException which gives - * more information about the specifics of this MediaException. - * - * @return the error code carried by this MediaException which - * gives more information about the specifics of this - * MediaException - */ - public int getErrorCode() - { - return errorCode; - } -} diff --git a/src/net/java/sip/communicator/service/neomedia/MediaService.java b/src/net/java/sip/communicator/service/neomedia/MediaService.java deleted file mode 100644 index a2269a965..000000000 --- a/src/net/java/sip/communicator/service/neomedia/MediaService.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import java.beans.*; -import java.util.*; - -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.format.*; - -/** - * The MediaService service is meant to be a wrapper of media libraries - * such as JMF, FMJ, FFMPEG, and/or others. It takes care of all media play and - * capture as well as media transport (e.g. over RTP). - * - * @author Emil Ivov - * @author Lyubomir Marinov - */ -public interface MediaService -{ - /** - * The name of the property of MediaService the value of which - * corresponds to the value returned by - * {@link #getDefaultDevice(MediaType, MediaUseCase)}. The oldValue - * and the newValue of the fired PropertyChangeEvent are - * not to be relied on and instead a call to getDefaultDevice is to - * be performed to retrieve the new value. - */ - public static final String DEFAULT_DEVICE = "defaultDevice"; - - /** - * Returns the default MediaDevice for the specified media - * type. - * - * @param mediaType a MediaType value indicating the kind of device - * that we are trying to obtain. - * @param useCase MediaUseCase value indicating for the use-case of - * device that we are trying to obtain. - * - * @return the currently default MediaDevice for the specified - * MediaType, or null if no such device exists. - */ - public MediaDevice getDefaultDevice( - MediaType mediaType, - MediaUseCase useCase); - - /** - * Returns a list containing all devices known to this service - * implementation and handling the specified MediaType. - * - * @param mediaType the media type (i.e. AUDIO or VIDEO) that we'd like - * to obtain the device list for. - * @param useCase MediaUseCase value indicating for the use-case of - * device that we are trying to obtain. - * - * @return the list of MediaDevices currently known to handle the - * specified mediaType. - */ - public List getDevices(MediaType mediaType, - MediaUseCase useCase); - - /** - * Create a MediaStream which will use a specific - * MediaDevice for capture and playback of media. The new instance - * will not have a StreamConnector at the time of its construction - * and a StreamConnector will be specified later on in order to - * enable the new instance to send and receive media. - * - * @param device the MediaDevice to be used by the new instance for - * capture and playback of media - * @return a newly-created MediaStream which will use the specified - * device for capture and playback of media - */ - public MediaStream createMediaStream(MediaDevice device); - - /** - * Creates a MediaStream that will be using the specified - * MediaDevice for both capture and playback of media exchanged - * via the specified StreamConnector. - * - * @param connector the StreamConnector the stream should use for - * sending and receiving media or null if the stream is to not have - * a StreamConnector configured at initialization time and a - * StreamConnector is to be specified later on - * @param device the device to be used for both capture and playback of - * media exchanged via the specified StreamConnector - * - * @return the newly created MediaStream. - */ - public MediaStream createMediaStream(StreamConnector connector, - MediaDevice device); - - /** - * Creates a MediaStream that will be using the specified - * MediaDevice for both capture and playback of media exchanged - * via the specified StreamConnector. - * - * @param connector the StreamConnector the stream should use for - * sending and receiving media or null if the stream is to not have - * a StreamConnector configured at initialization time and a - * StreamConnector is to be specified later on - * @param device the device to be used for both capture and playback of - * media exchanged via the specified StreamConnector - * @param zrtpControl a control which is already created, used to control - * the ZRTP operations. - * - * @return the newly created MediaStream. - */ - public MediaStream createMediaStream(StreamConnector connector, - MediaDevice device, - SrtpControl zrtpControl); - - /** - * Creates a new MediaDevice which uses a specific - * MediaDevice to capture and play back media and performs mixing - * of the captured media and the media played back by any other users of the - * returned MediaDevice. For the AUDIO MediaType, - * the returned device is commonly referred to as an audio mixer. The - * MediaType of the returned MediaDevice is the same as - * the MediaType of the specified device. - * - * @param device the MediaDevice which is to be used by the - * returned MediaDevice to actually capture and play back media - * @return a new MediaDevice instance which uses device to - * capture and play back media and performs mixing of the captured media and - * the media played back by any other users of the returned - * MediaDevice instance - */ - public MediaDevice createMixer(MediaDevice device); - - /** - * Gets the MediaFormatFactory through which MediaFormat - * instances may be created for the purposes of working with the - * MediaStreams created by this MediaService. - * - * @return the MediaFormatFactory through which - * MediaFormat instances may be created for the purposes of working - * with the MediaStreams created by this MediaService - */ - public MediaFormatFactory getFormatFactory(); - - /** - * Initializes a new ZrtpControl instance which is to control all - * ZRTP options. - * - * @return a new ZrtpControl instance which is to control all ZRTP - * options - */ - public ZrtpControl createZrtpControl(); - - /** - * Initializes a new SDesControl instance which is to control all - * SDes options. - * - * @return a new SDesControl instance which is to control all SDes - * options - */ - public SDesControl createSDesControl(); - - /** - * Gets the VolumeControl which controls the volume level of audio - * output/playback. - * - * @return the VolumeControl which controls the volume level of - * audio output/playback - */ - public VolumeControl getOutputVolumeControl(); - - /** - * Gets the VolumeControl which controls the volume level of audio - * input/capture. - * - * @return the VolumeControl which controls the volume level of - * audio input/capture - */ - public VolumeControl getInputVolumeControl(); - - /** - * Get available ScreenDevices. - * - * @return screens - */ - public List getAvailableScreenDevices(); - - /** - * Get default ScreenDevice device. - * - * @return default screen device - */ - public ScreenDevice getDefaultScreenDevice(); - - /** - * Creates a new Recorder instance that can be used to record a - * call which captures and plays back media using a specific - * MediaDevice. - * - * @param device the MediaDevice which is used for media capture - * and playback by the call to be recorded - * @return a new Recorder instance that can be used to record a - * call which captures and plays back media using the specified - * MediaDevice - */ - public Recorder createRecorder(MediaDevice device); - - /** - * Returns a {@link Map} that binds indicates whatever preferences the - * media service implementation may have for the RTP payload type numbers - * that get dynamically assigned to {@link MediaFormat}s with no static - * payload type. The method is useful for formats such as "telephone-event" - * for example that is statically assigned the 101 payload type by some - * legacy systems. Signalling protocol implementations such as SIP and XMPP - * should make sure that, whenever this is possible, they assign to formats - * the dynamic payload type returned in this {@link Map}. - * - * @return a {@link Map} binding some formats to a preferred dynamic RTP - * payload type number. - */ - public Map getDynamicPayloadTypePreferences(); - - /** - * Creates a preview component for the specified device(video device) used - * to show video preview from it. - * - * @param device the video device - * @param preferredWidth the width we prefer for the component - * @param preferredHeight the height we prefer for the component - * @return the preview component. - */ - public Object getVideoPreviewComponent( - MediaDevice device, int preferredWidth, int preferredHeight); - - /** - * Get a MediaDevice for a part of desktop streaming/sharing. - * - * @param width width of the part - * @param height height of the part - * @param x origin of the x coordinate (relative to the full desktop) - * @param y origin of the y coordinate (relative to the full desktop) - * @return MediaDevice representing the part of desktop or null - * if problem - */ - public MediaDevice getMediaDeviceForPartialDesktopStreaming( - int width, int height, int x, int y); - - /** - * If the MediaDevice corresponds to partial desktop streaming - * device. - * - * @param mediaDevice MediaDevice - * @return true if MediaDevice is a partial desktop streaming - * device, false otherwise - */ - public boolean isPartialStreaming(MediaDevice mediaDevice); - - /** - * Get origin for desktop streaming device. - * - * @param mediaDevice media device - * @return origin - */ - public java.awt.Point getOriginForDesktopStreamingDevice( - MediaDevice mediaDevice); - - /** - * Those interested in Recorder events add listener through MediaService. - * This way they don't need to have access to the Recorder instance. - * Adds a new Recorder.Listener to the list of listeners - * interested in notifications from a Recorder. - * - * @param listener the new Recorder.Listener to be added to the - * list of listeners interested in notifications from Recorders. - */ - public void addRecorderListener(Recorder.Listener listener); - - /** - * Removes an existing Recorder.Listener from the list of listeners - * interested in notifications from Recorders. - * - * @param listener the existing Listener to be removed from the - * list of listeners interested in notifications from Recorders - */ - public void removeRecorderListener(Recorder.Listener listener); - - /** - * Gives access to currently registered Recorder.Listeners. - * @return currently registered Recorder.Listeners. - */ - public Iterator getRecorderListeners(); - - /** - * Initializes a new RTPTranslator which is to forward RTP and RTCP - * traffic between multiple MediaStreams. - * - * @return a new RTPTranslator which is to forward RTP and RTCP - * traffic between multiple MediaStreams - */ - public RTPTranslator createRTPTranslator(); - - /** - * Adds a PropertyChangeListener to be notified about changes in - * the values of the properties of this instance. - * - * @param listener the PropertyChangeListener to be notified about - * changes in the values of the properties of this instance - */ - public void addPropertyChangeListener(PropertyChangeListener listener); - - /** - * Removes a PropertyChangeListener to no longer be notified about - * changes in the values of the properties of this instance. - * - * @param listener the PropertyChangeListener to no longer be - * notified about changes in the values of the properties of this instance - */ - public void removePropertyChangeListener(PropertyChangeListener listener); -} diff --git a/src/net/java/sip/communicator/service/neomedia/MediaStream.java b/src/net/java/sip/communicator/service/neomedia/MediaStream.java deleted file mode 100644 index 00dcc7617..000000000 --- a/src/net/java/sip/communicator/service/neomedia/MediaStream.java +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import java.net.*; -import java.util.*; -import java.beans.*; - -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.format.*; - -/** - * The MediaStream class represents a (generally) bidirectional RTP - * stream between exactly two parties. The class reflects one media stream, in - * the SDP sense of the word. MediaStream instances are created through - * the openMediaStream() method of the MediaService. - * - * @author Emil Ivov - * @author Lyubomir Marinov - */ -public interface MediaStream -{ - - /** - * The name of the property which indicates whether the remote SSRC is - * currently available. - */ - public static final String PNAME_LOCAL_SSRC = "localSSRCAvailable"; - - /** - * The name of the property which indicates whether the local SSRC is - * currently available. - */ - public static final String PNAME_REMOTE_SSRC = "remoteSSRCAvailable"; - - /** - * Starts capturing media from this stream's MediaDevice and then - * streaming it through the local StreamConnector toward the - * stream's target address and port. The method also puts the - * MediaStream in a listening state that would make it play all - * media received from the StreamConnector on the stream's - * MediaDevice. - */ - public void start(); - - /** - * Stops all streaming and capturing in this MediaStream and closes - * and releases all open/allocated devices/resources. This method has no - * effect on an already closed stream and is simply ignored. - */ - public void stop(); - - /** - * Releases the resources allocated by this instance in the course of its - * execution and prepares it to be garbage collected. - */ - public void close(); - - /** - * Sets the MediaFormat that this MediaStream should - * transmit in. - * - * @param format the MediaFormat that this MediaStream - * should transmit in. - */ - public void setFormat(MediaFormat format); - - /** - * Returns the MediaFormat that this stream is currently - * transmitting in. - * - * @return the MediaFormat that this stream is currently - * transmitting in. - */ - public MediaFormat getFormat(); - - /** - * Sets the StreamConnector to be used by this MediaStream - * for sending and receiving media. - * - * @param connector the StreamConnector to be used by this - * MediaStream for sending and receiving media - */ - public void setConnector(StreamConnector connector); - - /** - * Sets the device that this stream should use to play back and capture - * media. - * - * @param device the MediaDevice that this stream should use to - * play back and capture media. - */ - public void setDevice(MediaDevice device); - - /** - * Gets the device that this stream uses to play back and capture media. - * - * @return the MediaDevice that this stream uses to play back and - * capture media. - */ - public MediaDevice getDevice(); - - /** - * Returns the synchronization source (SSRC) identifier of the remote - * participant or -1 if that identifier is not yet known at this - * point. - * - * @return the synchronization source (SSRC) identifier of the remote - * participant or -1 if that identifier is not yet known at this - * point. - */ - public long getRemoteSourceID(); - - /** - * Gets the synchronization source (SSRC) identifiers of the remote peers. - * - * @return the synchronization source (SSRC) identifiers of the remote peers - * @see MediaStream#getRemoteSourceIDs() - */ - public List getRemoteSourceIDs(); - - /** - * Returns the synchronization source (SSRC) identifier of the local - * participant or -1 if that identifier is not yet known at this - * point. - * - * @return the synchronization source (SSRC) identifier of the local - * participant or -1 if that identifier is not yet known at this - * point. - */ - public long getLocalSourceID(); - - /** - * Returns the address that this stream is sending RTCP traffic to. - * - * @return an InetSocketAddress instance indicating the address - * that we are sending RTCP packets to. - */ - public InetSocketAddress getRemoteControlAddress(); - - /** - * Returns the address that this stream is sending RTP traffic to. - * - * @return an InetSocketAddress instance indicating the address - * that we are sending RTP packets to. - */ - public InetSocketAddress getRemoteDataAddress(); - - /** - * Returns the transport protocol used by the streams. - * - * @return the transport protocol (UDP or TCP) used by the streams. null if - * the stream connector is not instanciated. - */ - public StreamConnector.Protocol getTransportProtocol(); - - /** - * Adds a property change listener to this stream so that it would be - * notified upon property change events like for example an SSRC ID which - * becomes known. - * - * @param listener the listener that we'd like to register for - * PropertyChangeEvents - */ - public void addPropertyChangeListener(PropertyChangeListener listener); - - /** - * Removes the specified property change listener from this stream - * so that it won't receive further property change events. - * - * @param listener the listener that we'd like to remove. - */ - public void removePropertyChangeListener(PropertyChangeListener listener); - - /** - * Sets the target of this MediaStream to which it is to send and - * from which it is to receive data (e.g. RTP) and control data (e.g. RTCP). - * - * @param target the MediaStreamTarget describing the data - * (e.g. RTP) and the control data (e.g. RTCP) locations to which this - * MediaStream is to send and from which it is to receive - */ - public void setTarget(MediaStreamTarget target); - - /** - * Returns the target of this MediaStream to which it is to send - * and from which it is to receive data (e.g. RTP) and control data (e.g. - * RTCP). - * - * @return the MediaStreamTarget describing the data - * (e.g. RTP) and the control data (e.g. RTCP) locations to which this - * MediaStream is to send and from which it is to receive - * @see MediaStream#setTarget(MediaStreamTarget) - */ - public MediaStreamTarget getTarget(); - - /** - * Adds a new association in this MediaStream of the specified RTP - * payload type with the specified MediaFormat in order to allow it - * to report rtpPayloadType in RTP flows sending and receiving - * media in format. Usually, rtpPayloadType will be in the - * range of dynamic RTP payload types. - * - * @param rtpPayloadType the RTP payload type to be associated in this - * MediaStream with the specified MediaFormat - * @param format the MediaFormat to be associated in this - * MediaStream with rtpPayloadType - */ - public void addDynamicRTPPayloadType( - byte rtpPayloadType, - MediaFormat format); - - /** - * Gets the existing associations in this MediaStream of RTP - * payload types to MediaFormats. The returned Map - * only contains associations previously added in this instance with - * {@link #addDynamicRTPPayloadType(byte, MediaFormat)} and not globally or - * well-known associations reported by - * {@link MediaFormat#getRTPPayloadType()}. - * - * @return a Map of RTP payload type expressed as Byte to - * MediaFormat describing the existing (dynamic) associations in - * this instance of RTP payload types to MediaFormats. The - * Map represents a snapshot of the existing associations at the - * time of the getDynamicRTPPayloadTypes() method call and - * modifications to it are not reflected on the internal storage - */ - public Map getDynamicRTPPayloadTypes(); - - /** - * Adds or updates an association in this MediaStream mapping the - * specified extensionID to rtpExtension and enabling or - * disabling its use according to the direction attribute of - * rtpExtension. - * - * @param extensionID the ID that is mapped to rtpExtension for - * the lifetime of this MediaStream. - * @param rtpExtension the RTPExtension that we are mapping to - * extensionID. - */ - public void addRTPExtension(byte extensionID, RTPExtension rtpExtension); - - /** - * Returns a map containing all currently active RTPExtensions in - * use by this stream. - * - * @return a map containing all currently active RTPExtensions in - * use by this stream. - */ - public Map getActiveRTPExtensions(); - - /** - * Sets the direction in which media in this MediaStream is to be - * streamed. If this MediaStream is not currently started, calls to - * {@link #start()} later on will start it only in the specified - * direction. If it is currently started in a direction different - * than the specified, directions other than the specified will be stopped. - * - * @param direction the MediaDirection in which this - * MediaStream is to stream media when it is started - */ - public void setDirection(MediaDirection direction); - - /** - * Gets the direction in which this MediaStream is allowed to - * stream media. - * - * @return the MediaDirection in which this MediaStream is - * allowed to stream media - */ - public MediaDirection getDirection(); - - /** - * Determines whether {@link #start()} has been called on this - * MediaStream without {@link #stop()} or {@link #close()} - * afterwards. - * - * @return true if {@link #start()} has been called on this - * MediaStream without {@link #stop()} or {@link #close()} - * afterwards - */ - public boolean isStarted(); - - /** - * Causes this MediaStream to stop transmitting the media being fed - * from this stream's MediaDevice and transmit "silence" instead. - * "Silence" for video is understood as video data which is not the captured - * video data and may represent, for example, a black image. - * - * @param mute true if we are to start transmitting "silence" and - * false if we are to use media from this stream's - * MediaDevice again. - */ - public void setMute(boolean mute); - - /** - * Determines whether this MediaStream is set to transmit "silence" - * instead of the media being fed from its MediaDevice. "Silence" - * for video is understood as video data which is not the captured video - * data and may represent, for example, a black image. - * - * @return true if this MediaStream is set to transmit - * "silence" instead of the media fed from its MediaDevice; - * false, otherwise - */ - public boolean isMute(); - - /** - * Returns the name of this stream or null if no name has been - * set. A stream name is used by some protocols, for diagnostic purposes - * mostly. In XMPP for example this is the name of the content element that - * describes a stream. - * - * @return the name of this stream or null if no name has been - * set. - */ - public String getName(); - - /** - * Sets the name of this stream. Stream names are used by some protocols, - * for diagnostic purposes mostly. In XMPP for example this is the name of - * the content element that describes a stream. - * - * @param name the name of this stream or null if no name has been - * set. - */ - public void setName(String name); - - /** - * The ZrtpControl which controls the ZRTP for this stream. - * - * @return the ZrtpControl which controls the ZRTP for this stream - */ - public SrtpControl getSrtpControl(); - - /** - * Sets the RTPTranslator which is to forward RTP and RTCP traffic - * between this and other MediaStreams. - * - * @param rtpTranslator the RTPTranslator which is to forward RTP - * and RTCP traffic between this and other MediaStreams - */ - public void setRTPTranslator(RTPTranslator rtpTranslator); - - /** - * Returns a MediaStreamStats object used to get statistics about this - * MediaStream. - * - * @return the MediaStreamStats object used to compute the statistics about - * this MediaStream. - */ - public MediaStreamStats getMediaStreamStats(); -} diff --git a/src/net/java/sip/communicator/service/neomedia/MediaStreamStats.java b/src/net/java/sip/communicator/service/neomedia/MediaStreamStats.java deleted file mode 100644 index 3d1c68b69..000000000 --- a/src/net/java/sip/communicator/service/neomedia/MediaStreamStats.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import java.awt.*; -import net.sf.fmj.media.rtp.*; - -/** - * Class used to compute stats concerning a MediaStream. - * - * @author Vincent Lucas - */ -public interface MediaStreamStats -{ - /** - * Computes and updates information for a specific stream. - */ - public void updateStats(); - - /** - * Returns the MediaStream enconding. - * - * @return the encoding used by the stream. - */ - public String getEncoding(); - - /** - * Returns the MediaStream enconding rate (in Hz).. - * - * @return the encoding rate used by the stream. - */ - public String getEncodingClockRate(); - - /** - * Returns the upload video size if this stream uploads a video, or null if - * not. - * - * @return the upload video size if this stream uploads a video, or null if - * not. - */ - public Dimension getUploadVideoSize(); - - /** - * Returns the download video size if this stream downloads a video, or - * null if not. - * - * @return the download video size if this stream downloads a video, or null - * if not. - */ - public Dimension getDownloadVideoSize(); - - /** - * Returns the local IP address of the MediaStream. - * - * @return the local IP address of the stream. - */ - public String getLocalIPAddress(); - - /** - * Returns the local port of the MediaStream. - * - * @return the local port of the stream. - */ - public int getLocalPort(); - - /** - * Returns the remote IP address of the MediaStream. - * - * @return the remote IP address of the stream. - */ - public String getRemoteIPAddress(); - - /** - * Returns the remote port of the MediaStream. - * - * @return the remote port of the stream. - */ - public int getRemotePort(); - - /** - * Returns the percent loss of the download stream. - * - * @return the last loss rate computed (in %). - */ - public double getDownloadPercentLoss(); - - /** - * Returns the percent loss of the upload stream. - * - * @return the last loss rate computed (in %). - */ - public double getUploadPercentLoss(); - - /** - * Returns the bandwidth used by this download stream. - * - * @return the last used download bandwidth computed (in Kbit/s). - */ - public double getDownloadRateKiloBitPerSec(); - - /** - * Returns the bandwidth used by this download stream. - * - * @return the last used upload bandwidth computed (in Kbit/s). - */ - public double getUploadRateKiloBitPerSec(); - - /** - * Returns the jitter average of this download stream. - * - * @return the last jitter average computed (in ms). - */ - public double getDownloadJitterMs(); - - /** - * Returns the jitter average of this upload stream. - * - * @return the last jitter average computed (in ms). - */ - public double getUploadJitterMs(); - - /** - * Updates this stream stats with the new feedback sent. - * - * @param feedback The last RTCP feedback sent by the MediaStream. - */ - public void updateNewSentFeedback(RTCPFeedback feedback); - - /** - * Updates this stream stats with the new feedback received. - * - * @param feedback The last RTCP feedback received by the MediaStream. - */ - public void updateNewReceivedFeedback(RTCPFeedback feedback); -} diff --git a/src/net/java/sip/communicator/service/neomedia/MediaStreamTarget.java b/src/net/java/sip/communicator/service/neomedia/MediaStreamTarget.java deleted file mode 100644 index 64488e84f..000000000 --- a/src/net/java/sip/communicator/service/neomedia/MediaStreamTarget.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import java.net.*; - -/** - * The MediaStreamTarget contains a pair of host:port couples - * indicating data (RTP) and control (RTCP) locations. - * - * @author Emil Ivov - * @author Lyubomir Marinov - */ -public class MediaStreamTarget -{ - /** - * The data (RTP) address of the target. - */ - private final InetSocketAddress rtpTarget; - - /** - * The control (RTCP) address of the target. - */ - private final InetSocketAddress rtcpTarget; - - /** - * Creates an instance of this MediaStreamTarget containing the - * specified RTP and RTCP target host:port couples. - * - * @param rtpTarget the InetSocketAddress that this - * MediaStreamTarget is supposed to indicate as a data address. - * @param rtcpTarget the InetSocketAddress that this - * MediaStreamTarget is supposed to indicate as a control address. - */ - public MediaStreamTarget(InetSocketAddress rtpTarget, - InetSocketAddress rtcpTarget) - { - this.rtpTarget = rtpTarget; - this.rtcpTarget = rtcpTarget; - } - - /** - * Determines whether two specific InetSocketAddress instances are - * equal. - * - * @param addr1 one of the InetSocketAddress instances to be - * compared - * @param addr2 the other InetSocketAddress instance to be compared - * @return true if addr1 is equal to addr2; - * otherwise, false - */ - private boolean addressesAreEqual( - InetSocketAddress addr1, - InetSocketAddress addr2) - { - return (addr1 == null) ? (addr2 == null) : addr1.equals(addr2); - } - - /** - * Determines whether this MediaStreamTarget is equal to a specific - * Object. - * - * @param obj the Object to be compared to this - * MediaStreamTarget - * @return true if this MediaStreamTarget is equal to the - * specified obj; otherwise, false - */ - @Override - public boolean equals(Object obj) - { - if (this == obj) - return true; - - if (!getClass().isInstance(obj)) - return false; - - MediaStreamTarget mediaStreamTarget = (MediaStreamTarget) obj; - - return - addressesAreEqual( - getControlAddress(), - mediaStreamTarget.getControlAddress()) - && addressesAreEqual( - getDataAddress(), - mediaStreamTarget.getDataAddress()); - } - - /** - * Returns the InetSocketAddress that this MediaTarget is - * pointing to for all media (RTP) traffic. - * - * @return the InetSocketAddress that this MediaTarget is - * pointing to for all media (RTP) traffic. - */ - public InetSocketAddress getDataAddress() - { - return rtpTarget; - } - - /** - * Returns the InetSocketAddress that this MediaTarget is - * pointing to for all media (RTP) traffic. - * - * @return the InetSocketAddress that this MediaTarget is - * pointing to for all media (RTP) traffic. - */ - public InetSocketAddress getControlAddress() - { - return rtcpTarget; - } - - /** - * Returns a hash code for this MediaStreamTarget instance which is - * suitable for use in hash tables. - * - * @return a hash code for this MediaStreamTarget instance which is - * suitable for use in hash tables - */ - @Override - public int hashCode() - { - int hashCode = 0; - - InetSocketAddress controlAddress = getControlAddress(); - if (controlAddress != null) - hashCode |= controlAddress.hashCode(); - - InetSocketAddress dataAddress = getDataAddress(); - if (dataAddress != null) - hashCode |= dataAddress.hashCode(); - - return hashCode; - } - - /** - * Returns a human-readable representation of this - * MediaStreamTarget instance in the form of a String - * value. - * - * @return a String value which gives a human-readable - * representation of this MediaStreamTarget instance - */ - @Override - public String toString() - { - return - getClass().getSimpleName() - + " with dataAddress " - + getDataAddress() - + " and controlAddress " - + getControlAddress(); - } -} diff --git a/src/net/java/sip/communicator/service/neomedia/MediaType.java b/src/net/java/sip/communicator/service/neomedia/MediaType.java deleted file mode 100644 index 8720cdc1d..000000000 --- a/src/net/java/sip/communicator/service/neomedia/MediaType.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -/** - * The MediaType enumeration contains a list of media types - * currently known to and handled by the MediaService. - * - * @author Emil Ivov - */ -public enum MediaType -{ - /** - * Represents an AUDIO media type. - */ - AUDIO("audio"), - - /** - * Represents a VIDEO media type. - */ - VIDEO("video"); - - /** - * The name of this MediaType. - */ - private final String mediaTypeName; - - /** - * Creates a MediaType instance with the specified name. - * - * @param mediaTypeName the name of the MediaType we'd like to - * create. - */ - private MediaType(String mediaTypeName) - { - this.mediaTypeName = mediaTypeName; - } - - /** - * Returns the name of this MediaType (e.g. "audio" or "video"). The name - * returned by this method is meant for use by session description - * mechanisms such as SIP/SDP or XMPP/Jingle. - * - * @return the name of this MediaType (e.g. "audio" or "video"). - */ - @Override - public String toString() - { - return mediaTypeName; - } - - /** - * Returns a MediaType value corresponding to the specified - * mediaTypeName or in other words MediaType.AUDIO for - * "audio" and MediaType.VIDEO for "video". - * - * @param mediaTypeName the name that we'd like to parse. - * @return a MediaType value corresponding to the specified - * mediaTypeName. - * - * @throws IllegalArgumentException in case mediaTypeName is not a - * valid or currently supported media type. - */ - public static MediaType parseString(String mediaTypeName) - throws IllegalArgumentException - { - if(AUDIO.toString().equals(mediaTypeName)) - return AUDIO; - - if(VIDEO.toString().equals(mediaTypeName)) - return VIDEO; - - throw new IllegalArgumentException( - mediaTypeName + " is not a currently supported MediaType"); - } -} diff --git a/src/net/java/sip/communicator/service/neomedia/MediaTypeSrtpControl.java b/src/net/java/sip/communicator/service/neomedia/MediaTypeSrtpControl.java deleted file mode 100644 index 0dd9a1eff..000000000 --- a/src/net/java/sip/communicator/service/neomedia/MediaTypeSrtpControl.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -/** - * Utility class to combine MediaType and SrtpControlType as a - * map key. - * - * @author Ingo Bauersachs - */ -public class MediaTypeSrtpControl implements Comparable -{ - /** - * The media type. - */ - public final MediaType mediaType; - - /** - * The SRTP control type. - */ - public final SrtpControlType srtpControlType; - - /** - * Creates a new instance of this class. - * @param mt The MediaType for this key. - * @param sct The SrtpControlType for this key. - */ - public MediaTypeSrtpControl(MediaType mt, SrtpControlType sct) - { - mediaType = mt; - srtpControlType = sct; - } - - @Override - public boolean equals(Object obj) - { - if(obj == null || obj.getClass() != MediaTypeSrtpControl.class) - return false; - - MediaTypeSrtpControl other = (MediaTypeSrtpControl)obj; - return mediaType == other.mediaType - && srtpControlType == other.srtpControlType; - } - - @Override - public int hashCode() - { - return mediaType.hashCode() ^ srtpControlType.hashCode(); - } - - public int compareTo(MediaTypeSrtpControl o) - { - return getWeight() == o.getWeight() ? - 0 : - getWeight() < o.getWeight() ? - -1 : 1; - } - - private int getWeight() - { - int mtWeight = 0; - switch(mediaType) - { - case AUDIO: - mtWeight = 1; - break; - case VIDEO: - mtWeight = 2; - break; - } - int stWeight = 0; - switch(srtpControlType) - { - case ZRTP: - stWeight = 1; - break; - case MIKEY: - stWeight = 2; - break; - case SDES: - stWeight = 3; - break; - } - return mtWeight * 10 + stWeight; - } -} diff --git a/src/net/java/sip/communicator/service/neomedia/MediaUseCase.java b/src/net/java/sip/communicator/service/neomedia/MediaUseCase.java deleted file mode 100644 index b65158cff..000000000 --- a/src/net/java/sip/communicator/service/neomedia/MediaUseCase.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -/** - * The MediaUseCase enumeration contains a list of use-cases for media - * related. Typically it can be used to differentiate a video call (video comes - * from webcam) and desktop session (video comes from desktop). - * - * @author Sebastien Vincent - */ -public enum MediaUseCase -{ - /** - * Represents any usecase. - */ - ANY("any"), - - /** - * Represents a standard call (voice/video). - */ - CALL("call"), - - /** - * Represents a desktop streaming/sharing session. - */ - DESKTOP("desktop"); - - /** - * Name of this MediaUseCase. - */ - private final String mediaUseCase; - - /** - * Constructor. - * - * @param mediaUseCase type of MediaUseCase we'd like to create - */ - private MediaUseCase(String mediaUseCase) - { - this.mediaUseCase = mediaUseCase; - } - - /** - * Returns the name of this MediaUseCase. - * - * @return the name of this MediaUseCase. - */ - @Override - public String toString() - { - return mediaUseCase; - } - - /** - * Returns a MediaUseCase value corresponding to the specified - * mediaUseCase. - * - * @param mediaUseCase the name that we'd like to parse. - * @return a MediaUseCase value corresponding to the specified - * mediaUseCase. - * - * @throws IllegalArgumentException in case mediaUseCase is not a - * valid or currently supported media usecase. - */ - public static MediaUseCase parseString(String mediaUseCase) - throws IllegalArgumentException - { - if(CALL.toString().equals(mediaUseCase)) - return CALL; - if(ANY.toString().equals(mediaUseCase)) - return ANY; - if(DESKTOP.toString().equals(mediaUseCase)) - return DESKTOP; - - throw new IllegalArgumentException( - mediaUseCase + " is not a currently supported MediaUseCase"); - } -} diff --git a/src/net/java/sip/communicator/service/neomedia/QualityControl.java b/src/net/java/sip/communicator/service/neomedia/QualityControl.java deleted file mode 100644 index a210f695e..000000000 --- a/src/net/java/sip/communicator/service/neomedia/QualityControl.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import net.java.sip.communicator.service.protocol.*; - -/** - * The quality controls we use to control other party video presets. - * @author Damian Minkov - */ -public interface QualityControl -{ - /** - * The currently used quality preset announced as receive by remote party. - * @return the current quality preset. - */ - public QualityPreset getRemoteReceivePreset(); - - /** - * The minimum preset that the remote party is sending and we are receiving. - * @return the minimum remote preset. - */ - public QualityPreset getRemoteSendMinPreset(); - - /** - * The maximum preset that the remote party is sending and we are receiving. - * @return the maximum preset announced from remote party as send. - */ - public QualityPreset getRemoteSendMaxPreset(); - - /** - * Changes remote send preset. This doesn't have impact of current stream. - * But will have on next media changes. - * With this we can try to change the resolution that the remote part - * is sending. - * @param preset the new preset value. - */ - public void setRemoteSendMaxPreset(QualityPreset preset); - - /** - * Changes remote send preset and protocols who can handle the changes - * will implement this for re-inviting the other party or just sending that - * media has changed. - * @param preset the new preset. - * @throws OperationFailedException - */ - public void setPreferredRemoteSendMaxPreset(QualityPreset preset) - throws OperationFailedException; -} diff --git a/src/net/java/sip/communicator/service/neomedia/QualityPreset.java b/src/net/java/sip/communicator/service/neomedia/QualityPreset.java deleted file mode 100644 index efd91d988..000000000 --- a/src/net/java/sip/communicator/service/neomedia/QualityPreset.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import java.awt.*; - -/** - * Predefined quality preset used to specify some video settings during an - * existing call or when starting a new call. - * - * @author Damian Minkov - * @author Lyubomir Marinov - */ -public class QualityPreset - implements Comparable -{ - /** - * 720p HD - */ - public static final QualityPreset HD_QUALITY - = new QualityPreset(new Dimension(1280, 720), 30); - - /** - * Low - */ - public static final QualityPreset LO_QUALITY - = new QualityPreset(new Dimension(320, 240), 15); - - /** - * SD - */ - public static final QualityPreset SD_QUALITY - = new QualityPreset(new Dimension(640, 480), 20); - - /** - * The frame rate to use. - */ - private final float frameRate; - - /** - * The resolution to use. - */ - private final Dimension resolution; - - /** - * Initializes a new quality preset with a specific resolution and - * a specific frameRate. - * - * @param resolution the resolution - * @param frameRate the frame rate - */ - public QualityPreset(Dimension resolution, float frameRate) - { - this.frameRate = frameRate; - this.resolution = resolution; - } - - /** - * Initializes a new quality preset with a specific resolution and - * an unspecified frameRate. - * - * @param resolution the resolution - */ - public QualityPreset(Dimension resolution) - { - this(resolution, -1 /* unspecified */); - } - - /** - * Returns this preset frame rate. - * @return the frame rate. - */ - public float getFameRate() - { - return frameRate; - } - - /** - * Returns this preset resolution. - * @return the resolution. - */ - public Dimension getResolution() - { - return resolution; - } - - /** - * Compares to presets and its dimensions. - * @param o object to compare to. - * @return a negative integer, zero, or a positive integer as this object is - * less than, equal to, or greater than the specified object. - */ - public int compareTo(QualityPreset o) - { - if(resolution == null) - return -1; - else if(o == null) - return 1; - else if(resolution.equals(o.resolution)) - return 0; - else if((resolution.height < o.resolution.height) - && (resolution.width < o.resolution.width)) - return -1; - else - return 1; - } -} diff --git a/src/net/java/sip/communicator/service/neomedia/RTPExtension.java b/src/net/java/sip/communicator/service/neomedia/RTPExtension.java deleted file mode 100644 index 02fab5ab4..000000000 --- a/src/net/java/sip/communicator/service/neomedia/RTPExtension.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import java.net.*; - -/** - * RTP extensions are defined by RFC 5285 and they allow attaching additional - * information to some or all RTP packets of an RTP stream. This class describes - * RTP extensions in a way that makes them convenient for use in SDP - * generation/parsing. - * - * @author Emil Ivov - */ -public class RTPExtension -{ - /** - * The direction that this extension will be transmitted in. - */ - private MediaDirection direction = MediaDirection.SENDRECV; - - /** - * The URI identifier of this extension. - */ - private final URI extensionURI; - - /** - * Extension specific attributes. - */ - private String extensionAttributes = null; - - /** - * The URN identifying the RTP extension that allows mixers to send to - * conference participants the audio levels of all contributing sources. - */ - public static final String CSRC_AUDIO_LEVEL_URN - = "urn:ietf:params:rtp-hdrext:csrc-audio-level"; - - /** - * The URN identifying the RTP extension that allows clients to send to - * conference mixers the audio level of their packet payload. - */ - public static final String SSRC_AUDIO_LEVEL_URN - = "urn:ietf:params:rtp-hdrext:ssrc-audio-level"; - - /** - * Creates an RTPExtension instance for the specified - * extensionURI using a default SENDRECV direction and no - * extension attributes. - * - * @param extensionURI the URI (possibly a URN) of the RTP - * extension that we'd like to create. - */ - public RTPExtension(URI extensionURI) - { - this(extensionURI, MediaDirection.SENDRECV); - } - - /** - * Creates an RTPExtension instance for the specified - * extensionURI and direction. - * - * @param extensionURI the URI (possibly a URN) of the RTP - * extension that we'd like to create. - * @param direction a MediaDirection instance indication how this - * extension will be transmitted. - */ - public RTPExtension(URI extensionURI, MediaDirection direction) - { - this(extensionURI, direction, null); - } - - /** - * Creates an RTPExtension instance for the specified - * extensionURI using a default SENDRECV direction and - * extensionAttributes. - * - * @param extensionURI the URI (possibly a URN) of the RTP - * extension that we'd like to create. - * @param extensionAttributes any attributes that we'd like to add to this - * extension. - */ - public RTPExtension(URI extensionURI, String extensionAttributes) - { - this(extensionURI, MediaDirection.SENDRECV, extensionAttributes); - } - - /** - * Creates an RTPExtension instance for the specified - * extensionURI and direction and sets the specified - * extensionAttributes. - * - * @param extensionURI the URI (possibly a URN) of the RTP - * extension that we'd like to create. - * @param direction a MediaDirection instance indication how this - * extension will be transmitted. - * @param extensionAttributes any attributes that we'd like to add to this - * extension. - */ - public RTPExtension(URI extensionURI, - MediaDirection direction, - String extensionAttributes) - { - this.extensionURI = extensionURI; - this.direction = direction; - this.extensionAttributes = extensionAttributes; - } - - /** - * Returns the direction that the corresponding MediaDevice - * supports for this extension. By default RTP extension headers inherit - * the direction of a stream. When explicitly specified SENDONLY - * direction indicates an ability to attach the extension in outgoing RTP - * packets; a RECVONLY direction indicates a desire to receive - * the extension in incoming packets; a SENDRECV direction - * indicates both. An INACTIVE direction indicates neither, but - * later re-negotiation may make an extension active. - * - * @return the direction that the corresponding MediaDevice - * supports for this extension. - */ - public MediaDirection getDirection() - { - return direction; - } - - /** - * Returns the URI that identifies the format and meaning of this - * extension. - * - * @return the URI (possibly a URN) that identifies the format and - * meaning of this extension. - */ - public URI getURI() - { - return extensionURI; - } - - /** - * Returns the extension attributes associated with this - * RTPExtension or null if this extension does not have - * any. - * - * @return A String containing the extension attributes associated - * with this RTPExtension or null if this extension does - * not have any. - */ - public String getExtensionAttributes() - { - return extensionAttributes; - } - - /** - * Returns a String representation of this RTPExtension's - * URI. - * - * @return a String representation of this RTPExtension's - * URI. - */ - @Override - public String toString() - { - return extensionURI.toString() + ";" + getDirection(); - } - - /** - * Returns true if and only if o is an instance of - * RTPExtension and o's URI is equal to this - * extension's URI. The method returns false otherwise. - * - * @param o the Object that we'd like to compare to this - * RTPExtension. - * - * @return true when o's URI is equal to this - * extension's URI and false otherwise. - */ - @Override - public boolean equals(Object o) - { - return (o instanceof RTPExtension) - && ((RTPExtension)o).getURI().equals(getURI()); - } - - /** - * Returns the hash code of this extension instance which is actually the - * hash code of the URI that this extension is encapsulating. - * - * @return the hash code of this extension instance which is actually the - * hash code of the URI that this extension is encapsulating. - */ - @Override - public int hashCode() - { - return getURI().hashCode(); - } -} diff --git a/src/net/java/sip/communicator/service/neomedia/RTPTranslator.java b/src/net/java/sip/communicator/service/neomedia/RTPTranslator.java deleted file mode 100644 index 5313b36b9..000000000 --- a/src/net/java/sip/communicator/service/neomedia/RTPTranslator.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -/** - * Represents an RTP translator which forwards RTP and RTCP traffic between - * multiple MediaStreams. - * - * @author Lyubomir Marinov - */ -public interface RTPTranslator -{ - /** - * Releases the resources allocated by this instance in the course of its - * execution and prepares it to be garbage collected. - */ - public void dispose(); -} diff --git a/src/net/java/sip/communicator/service/neomedia/Recorder.java b/src/net/java/sip/communicator/service/neomedia/Recorder.java deleted file mode 100644 index b7d5862e2..000000000 --- a/src/net/java/sip/communicator/service/neomedia/Recorder.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import java.io.*; -import java.util.*; - -/** - * The call recording interface. Provides the capability to start and stop call - * recording. - * - * @author Dmitri Melnikov - * @author Lubomir Marinov - */ -public interface Recorder -{ - /** - * The name of the configuration property the value of which specifies the - * full path to the directory with media recorded by Recorder (e.g. - * the media being sent and received in a Call). - */ - public static final String SAVED_CALLS_PATH - = "net.java.sip.communicator.impl.neomedia.SAVED_CALLS_PATH"; - - /** - * The name of the configuration property the value of which specifies the - * format in which media is to be recorded by Recorder (e.g. the - * media being sent and received in a Call). - */ - public static final String FORMAT - = "net.java.sip.communicator.impl.neomedia.Recorder.FORMAT"; - - /** - * Adds a new Listener to the list of listeners interested in - * notifications from this Recorder. - * - * @param listener the new Listener to be added to the list of - * listeners interested in notifications from this Recorder - */ - public void addListener(Listener listener); - - /** - * Gets a list of the formats in which this Recorder supports - * recording media. - * - * @return a List of the formats in which this Recorder - * supports recording media - */ - public List getSupportedFormats(); - - /** - * Removes an existing Listener from the list of listeners - * interested in notifications from this Recorder. - * - * @param listener the existing Listener to be removed from the - * list of listeners interested in notifications from this Recorder - */ - public void removeListener(Listener listener); - - /** - * Starts the recording of the media associated with this Recorder - * (e.g. the media being sent and received in a Call) into a file - * with a specific name. - * - * @param format the format into which the media associated with this - * Recorder is to be recorded into the specified file - * @param filename the name of the file into which the media associated with - * this Recorder is to be recorded - * @throws IOException if anything goes wrong with the input and/or output - * performed by this Recorder - * @throws MediaException if anything else goes wrong while starting the - * recording of media performed by this Recorder - */ - public void start(String format, String filename) - throws IOException, - MediaException; - - /** - * Stops the recording of the media associated with this Recorder - * (e.g. the media being sent and received in a Call) if it has - * been started and prepares this Recorder for garbage collection. - */ - public void stop(); - - /** - * Represents a listener interested in notifications from a Recorder. - * - * @author Lubomir Marinov - */ - public interface Listener - { - /** - * Notifies this Listener that a specific Recorder has - * stopped recording the media associated with it. - * - * @param recorder the Recorder which has stopped recording its - * associated media - */ - public void recorderStopped(Recorder recorder); - } - - /** - * Put the recorder in mute state. It won't record the local input. - * This is used when the local call is muted and we don't won't to record - * the local input. - * @param mute the new value of the mute property - */ - public void setMute(boolean mute); - - /** - * Returns the filename we are last started or stopped recording to, - * null if not started. - * @return the filename we are last started or stopped recording to, - * null if not started. - */ - public String getFilename(); -} diff --git a/src/net/java/sip/communicator/service/neomedia/SDesControl.java b/src/net/java/sip/communicator/service/neomedia/SDesControl.java deleted file mode 100644 index a0559b8a3..000000000 --- a/src/net/java/sip/communicator/service/neomedia/SDesControl.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import ch.imvs.sdes4j.srtp.SrtpCryptoAttribute; - -/** - * SDES based SRTP MediaStream encryption control. - * - * @author Ingo Bauersachs - */ -public interface SDesControl - extends SrtpControl -{ - /** - * Name of the config setting that supplies the default enabled cipher - * suites. Cipher suites are comma-separated. - */ - public static final String SDES_CIPHER_SUITES = - "net.java.sip.communicator.service.neomedia.SDES_CIPHER_SUITES"; - - /** - * Set the enabled SDES ciphers. - * - * @param ciphers The list of enabled ciphers. - */ - public void setEnabledCiphers(Iterable ciphers); - - /** - * Gets all supported cipher suites. - * - * @return all supported cipher suites. - */ - public Iterable getSupportedCryptoSuites(); - - /** - * Gets the encoded SDES crypto-attributes for all enabled ciphers when the - * control is used as the initiator. - * - * @return the encoded SDES crypto-attributes for all enabled ciphers. - */ - public String[] getInitiatorCryptoAttributes(); - - /** - * Chooses a supported crypto attribute from the peer's list of supplied - * attributes and creates the local crypto attribute. Used when the control - * is running in the role as responder. - * - * @param peerAttributes The peer's crypto attribute offering. - * @return The local crypto attribute for the answer of the offer or null if - * no matching cipher suite could be found. - */ - public String responderSelectAttribute(Iterable peerAttributes); - - /** - * Select the local crypto attribute from the initial offering (@see - * {@link #getInitiatorCryptoAttributes()}) based on the peer's first - * matching cipher suite. - * - * @param peerAttributes The peer's crypto offers. - * @return True when a matching cipher suite was found, false otherwise. - */ - public boolean initiatorSelectAttribute(Iterable peerAttributes); - - /** - * Gets the crypto attribute of the incoming MediaStream. - * @return the crypto attribute of the incoming MediaStream. - */ - public SrtpCryptoAttribute getInAttribute(); - - /** - * Gets the crypto attribute of the outgoing MediaStream. - * @return the crypto attribute of the outgoing MediaStream. - */ - public SrtpCryptoAttribute getOutAttribute(); -} diff --git a/src/net/java/sip/communicator/service/neomedia/SrtpControl.java b/src/net/java/sip/communicator/service/neomedia/SrtpControl.java deleted file mode 100644 index 6d04d9251..000000000 --- a/src/net/java/sip/communicator/service/neomedia/SrtpControl.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import net.java.sip.communicator.impl.neomedia.AbstractRTPConnector; -import net.java.sip.communicator.impl.neomedia.transform.TransformEngine; -import net.java.sip.communicator.service.neomedia.event.*; - -/** - * Controls SRTP encryption in the MediaStream. - * - * @author Damian Minkov - */ -public interface SrtpControl -{ - /** - * Cleans up the current SRTP control and its engine. - */ - public void cleanup(); - - /** - * Sets a SrtpListener that will listen for security events. - * - * @param srtpListener the SrtpListener that will receive the - * events - */ - public void setSrtpListener(SrtpListener srtpListener); - - /** - * Returns the SrtpListener which listens for security events. - * - * @return the SrtpListener which listens for security events - */ - public SrtpListener getSrtpListener(); - - /** - * Gets the default secure/insecure communication status for the supported - * call sessions. - * - * @return default secure communication status for the supported - * call sessions. - */ - public boolean getSecureCommunicationStatus(); - - /** - * When in multistream mode, enables the master session. - * @param masterSession whether current control, controls the master session. - */ - public void setMasterSession(boolean masterSession); - - /** - * Starts and enables zrtp in the stream holding this control. - * @param mediaType the media type of the stream this control controls. - */ - public void start(MediaType mediaType); - - /** - * Sets the multistream data, which means that the master stream - * has successfully started and this will start all other streams - * in this session. - * @param master The security control of the master stream. - */ - public void setMultistream(SrtpControl master); - - /** - * Returns the transform engine currently used by this stream. - * - * @return the RTP stream transformation engine - */ - public TransformEngine getTransformEngine(); - - /** - * Sets the RTPConnector which is to use or uses this SRTP engine. - * - * @param connector the RTPConnector which is to use or uses this - * SRTP engine - */ - public void setConnector(AbstractRTPConnector connector); - - /** - * Indicates if the key exchange method is dependent on secure transport of - * the signaling channel. - * - * @return True when secure signaling is required to make the encryption - * secure, false otherwise. - */ - public boolean requiresSecureSignalingTransport(); -} diff --git a/src/net/java/sip/communicator/service/neomedia/SrtpControlType.java b/src/net/java/sip/communicator/service/neomedia/SrtpControlType.java deleted file mode 100644 index d015017ba..000000000 --- a/src/net/java/sip/communicator/service/neomedia/SrtpControlType.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -/** - * The SrtpControlType enumeration contains all currently known - * SrtpControl implementations. - * - * @author Ingo Bauersachs - */ -public enum SrtpControlType -{ - /** - * Session Description Protocol (SDP) Security Descriptions for Media - * Streams (RFC 4568) - */ - SDES, - - /** - * ZRTP: Media Path Key Agreement for Unicast Secure RTP (RFC 6189) - */ - ZRTP, - - /** - * Multimedia Internet KEYing (RFC 3830) - */ - MIKEY -} diff --git a/src/net/java/sip/communicator/service/neomedia/StreamConnector.java b/src/net/java/sip/communicator/service/neomedia/StreamConnector.java deleted file mode 100644 index 027bb2dfd..000000000 --- a/src/net/java/sip/communicator/service/neomedia/StreamConnector.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import java.net.*; - -/** - * The StreamConnector interface represents a pair of datagram sockets - * that a media stream could use for RTP and RTCP traffic. - *

- * The reason why this media service makes sockets visible through this - * StreamConnector is so that they could be shared among media - * and other libraries that may need to use them like an ICE implementation for - * example. - * - * @author Emil Ivov - */ -public interface StreamConnector -{ - /** - * Enumerates the protocols supported by StreamConnector. - */ - public enum Protocol - { - /** - * UDP protocol. - */ - UDP, - - /** - * TCP protocol. - */ - TCP - } - - /** - * Returns a reference to the DatagramSocket that a stream should - * use for data (e.g. RTP) traffic. - * - * @return a reference to the DatagramSocket that a stream should - * use for data (e.g. RTP) traffic or null if this - * StreamConnector does not handle UDP sockets. - */ - public DatagramSocket getDataSocket(); - - /** - * Returns a reference to the DatagramSocket that a stream should - * use for control data (e.g. RTCP). - * - * @return a reference to the DatagramSocket that a stream should - * use for control data (e.g. RTCP) or null if this - * StreamConnector does not handle UDP sockets. - */ - public DatagramSocket getControlSocket(); - - /** - * Returns a reference to the Socket that a stream should - * use for data (e.g. RTP) traffic. - * - * @return a reference to the Socket that a stream should - * use for data (e.g. RTP) traffic or null if this - * StreamConnector does not handle TCP sockets. - */ - public Socket getDataTCPSocket(); - - /** - * Returns a reference to the Socket that a stream should - * use for control data (e.g. RTCP). - * - * @return a reference to the Socket that a stream should - * use for control data (e.g. RTCP) or null if this - * StreamConnector does not handle TCP sockets. - */ - public Socket getControlTCPSocket(); - - /** - * Returns the protocol of this StreamConnector. - * - * @return the protocol of this StreamConnector - */ - public Protocol getProtocol(); - - /** - * Releases the resources allocated by this instance in the course of its - * execution and prepares it to be garbage collected. - */ - public void close(); - - /** - * Notifies this instance that utilization of its DatagramSockets - * for data and/or control traffic has started. - */ - public void started(); - - /** - * Notifies this instance that utilization of its DatagramSockets - * for data and/or control traffic has temporarily stopped. This instance - * should be prepared to be started at a later time again though. - */ - public void stopped(); -} diff --git a/src/net/java/sip/communicator/service/neomedia/StreamConnectorDelegate.java b/src/net/java/sip/communicator/service/neomedia/StreamConnectorDelegate.java deleted file mode 100644 index 111923122..000000000 --- a/src/net/java/sip/communicator/service/neomedia/StreamConnectorDelegate.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import java.net.*; - -/** - * Implements a {@link StreamConnector} which wraps a specific - * StreamConnector instance. - * - * @param the very type of the StreamConnector wrapped by - * StreamConnectorDelegate - * - * @author Lyubomir Marinov - */ -public class StreamConnectorDelegate - implements StreamConnector -{ - /** - * The StreamConnector wrapped by this instance. - */ - protected final T streamConnector; - - /** - * Initializes a new StreamConnectorDelegate which is to wrap a - * specific StreamConnector. - * - * @param streamConnector the StreamConnector to be wrapped by the - * new instance - */ - public StreamConnectorDelegate(T streamConnector) - { - if (streamConnector == null) - throw new NullPointerException("streamConnector"); - - this.streamConnector = streamConnector; - } - - /** - * Releases the resources allocated by this instance in the course of its - * execution and prepares it to be garbage collected. Calls - * {@link StreamConnector#close()} on the StreamConnector wrapped - * by this instance. - */ - public void close() - { - streamConnector.close(); - } - - public DatagramSocket getControlSocket() - { - return streamConnector.getControlSocket(); - } - - public Socket getControlTCPSocket() - { - return streamConnector.getControlTCPSocket(); - } - - public DatagramSocket getDataSocket() - { - return streamConnector.getDataSocket(); - } - - public Socket getDataTCPSocket() - { - return streamConnector.getDataTCPSocket(); - } - - public Protocol getProtocol() - { - return streamConnector.getProtocol(); - } - - public void started() - { - streamConnector.started(); - } - - public void stopped() - { - streamConnector.stopped(); - } -} diff --git a/src/net/java/sip/communicator/service/neomedia/StreamConnectorFactory.java b/src/net/java/sip/communicator/service/neomedia/StreamConnectorFactory.java deleted file mode 100644 index 3a662f9ad..000000000 --- a/src/net/java/sip/communicator/service/neomedia/StreamConnectorFactory.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -/** - * Represents a factory of StreamConnector instances. - * - * @author Lyubomir Marinov - */ -public interface StreamConnectorFactory -{ - /** - * Initializes a StreamConnector instance. - * - * @return a StreamConnector instance - */ - public StreamConnector createStreamConnector(); -} diff --git a/src/net/java/sip/communicator/service/neomedia/VideoMediaStream.java b/src/net/java/sip/communicator/service/neomedia/VideoMediaStream.java deleted file mode 100644 index 851ac9499..000000000 --- a/src/net/java/sip/communicator/service/neomedia/VideoMediaStream.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import java.awt.*; -import java.util.*; -import java.util.List; - -import net.java.sip.communicator.service.neomedia.control.*; -import net.java.sip.communicator.util.event.*; - -/** - * Extends the MediaStream interface and adds methods specific to - * video streaming. - * - * @author Emil Ivov - * @author Lyubomir Marinov - */ -public interface VideoMediaStream - extends MediaStream -{ - /** - * Gets local visual Component of the local peer. - * - * @param flipLocalVideoDisplay Tells to flip the local video display (true, - * in case of diplaying the webcam as a mirror), or not (false, for desktop - * streaming). - * - * @return visual Component - */ - public Component createLocalVisualComponent(boolean flipLocalVideoDisplay); - - /** - * Disposes of a specific local visual Component of the local peer. - * - * @param component the local visual Component of the local peer to - * dispose of - */ - public void disposeLocalVisualComponent(Component component); - - /** - * Gets the visual Component where video from the remote peer is - * being rendered or null if no video is currently being rendered. - * - * @return the visual Component where video from the remote peer is - * being rendered or null if no video is currently being rendered - */ - @Deprecated - public Component getVisualComponent(); - - /** - * Gets a list of the visual Components where video from the remote - * peer is being rendered. - * - * @return a list of the visual Components where video from the - * remote peer is being rendered - */ - public List getVisualComponents(); - - /** - * Gets the visual Components rendering the ReceiveStream - * corresponding to the given ssrc. - * - * @param ssrc the src-id of the receive stream, which visual - * Component we're looking for - * @return the visual Component rendering the - * ReceiveStream corresponding to the given ssrc - */ - public Component getVisualComponent(long ssrc); - - /** - * Adds a specific VideoListener to this VideoMediaStream - * in order to receive notifications when visual/video Components - * are being added and removed. - *

- * Adding a listener which has already been added does nothing i.e. it is - * not added more than once and thus does not receive one and the same - * VideoEvent multiple times - *

- * - * @param listener the VideoListener to be notified when - * visual/video Components are being added or removed in this - * VideoMediaStream - */ - public void addVideoListener(VideoListener listener); - - /** - * Removes a specific VideoListener from this - * VideoMediaStream in order to have to no longer receive - * notifications when visual/video Components are being added and - * removed. - * - * @param listener the VideoListener to no longer be notified when - * visual/video Components are being added or removed in this - * VideoMediaStream - */ - public void removeVideoListener(VideoListener listener); - - /** - * Gets the KeyFrameControl of this VideoMediaStream. - * - * @return the KeyFrameControl of this VideoMediaStream - */ - public KeyFrameControl getKeyFrameControl(); - - /** - * Gets the QualityControl of this VideoMediaStream. - * - * @return the QualityControl of this VideoMediaStream - */ - public QualityControl getQualityControl(); - - /** - * Updates the QualityControl of this VideoMediaStream. - * - * @param advancedParams parameters of advanced attributes that may affect - * quality control - */ - public void updateQualityControl( - Map advancedParams); - - /** - * Move origin of a partial desktop streaming MediaDevice. - * - * @param x new x coordinate origin - * @param y new y coordinate origin - */ - public void movePartialDesktopStreaming( - int x, int y); -} diff --git a/src/net/java/sip/communicator/service/neomedia/VolumeControl.java b/src/net/java/sip/communicator/service/neomedia/VolumeControl.java deleted file mode 100644 index 229456975..000000000 --- a/src/net/java/sip/communicator/service/neomedia/VolumeControl.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -import net.java.sip.communicator.service.neomedia.event.*; - -/** - * Control for volume level in media service. - * - * @author Damian Minkov - */ -public interface VolumeControl -{ - /** - * The name of the configuration property which specifies the volume level - * of audio input. - */ - public final static String CAPTURE_VOLUME_LEVEL_PROPERTY_NAME - = "net.java.sip.communicator.service.media.CAPTURE_VOLUME_LEVEL"; - - /** - * The name of the configuration property which specifies the volume level - * of audio output. - */ - public final static String PLAYBACK_VOLUME_LEVEL_PROPERTY_NAME - = "net.java.sip.communicator.service.media.PLAYBACK_VOLUME_LEVEL"; - - /** - * Current volume value. - * @return the current volume level. - */ - public float getVolume(); - - /** - * Returns the minimum allowed volume value. - * @return the minimum allowed volume value. - */ - public float getMinValue(); - - /** - * Returns the maximum allowed volume value. - * @return the maximum allowed volume value. - */ - public float getMaxValue(); - - /** - * Changes volume level. - * @param value the new level to set. - * @return the actual level which was set. - */ - public float setVolume(float value); - - /** - * Mutes current sound playback. - * @param mute mutes/unmutes playback. - */ - public void setMute(boolean mute); - - /** - * Get mute state of sound playback. - * @return mute state of sound playback. - */ - public boolean getMute(); - - /** - * Adds a VolumeChangeListener to be informed for any change - * in the volume levels. - * - * @param listener volume change listener. - */ - public void addVolumeChangeListener(VolumeChangeListener listener); - - /** - * Removes a VolumeChangeListener. - * @param listener the volume change listener to be removed. - */ - public void removeVolumeChangeListener(VolumeChangeListener listener); -} diff --git a/src/net/java/sip/communicator/service/neomedia/ZrtpControl.java b/src/net/java/sip/communicator/service/neomedia/ZrtpControl.java deleted file mode 100644 index c6b1efdc0..000000000 --- a/src/net/java/sip/communicator/service/neomedia/ZrtpControl.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia; - -/** - * ZRTP based SRTP MediaStream encryption control. - * - * @author Damian Minkov - */ -public interface ZrtpControl - extends SrtpControl -{ - /** - * Return the zrtp hello hash String. - * - * @return String the zrtp hello hash. - */ - public String getHelloHash(); - - /** - * Get the ZRTP Hello Hash data - separate strings. - * - * @return String array containing the version string at offset 0, the Hello - * hash value as hex-digits at offset 1. Hello hash is available - * immediately after class instantiation. Returns null - * if ZRTP is not available. - */ - public String[] getHelloHashSep(); - - /** - * Gets the SAS for the current media stream. - * - * @return the four character ZRTP SAS. - */ - public String getSecurityString(); - - /** - * Gets the cipher information for the current media stream. - * - * @return the cipher information string. - */ - public String getCipherString(); - - /** - * Gets the status of the SAS verification. - * - * @return true when the SAS has been verified. - */ - public boolean isSecurityVerified(); - - /** - * Sets the SAS verification - * - * @param verified the new SAS verification status - */ - public void setSASVerification(boolean verified); - - /** - * Returns the timeout value that will we will wait - * and fire timeout secure event if call is not secured. - * The value is in milliseconds. - * @return the timeout value that will we will wait - * and fire timeout secure event if call is not secured. - */ - public long getTimeoutValue(); - - /** - * Get other party's ZID (ZRTP Identifier) data - * - * This functions returns the other party's ZID that was receivied during - * ZRTP processing. - * - * The ZID data can be retrieved after ZRTP receive the first Hello packet - * from the other party. - * - * @return the ZID data as byte array. - */ - public byte[] getPeerZid(); - - /** - * Get other party's ZID (ZRTP Identifier) data as String - * - * This functions returns the other party's ZID that was receivied during - * ZRTP processing. - * - * The ZID data can be retrieved after ZRTP receive the first Hello packet - * from the other party. - * - * @return the ZID data as String. - */ - public String getPeerZidString(); -} diff --git a/src/net/java/sip/communicator/service/neomedia/control/KeyFrameControl.java b/src/net/java/sip/communicator/service/neomedia/control/KeyFrameControl.java deleted file mode 100644 index c3b4facd5..000000000 --- a/src/net/java/sip/communicator/service/neomedia/control/KeyFrameControl.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.control; - -import java.util.*; - -/** - * Represents a control over the key frame-related logic of a - * VideoMediaStream. - * - * @author Lyubomir Marinov - */ -public interface KeyFrameControl -{ - /** - * Adds a KeyFrameRequestee to be made available through this - * KeyFrameControl. - * - * @param index the zero-based index at which keyFrameRequestee is - * to be added to the list of KeyFrameRequestees made available or - * -1 to have this KeyFrameControl choose at which index - * it is to be added in accord with its internal logic - * through this KeyFrameControl - * @param keyFrameRequestee the KeyFrameRequestee to be added to - * this KeyFrameControl so that it is made available through it - */ - public void addKeyFrameRequestee( - int index, - KeyFrameRequestee keyFrameRequestee); - - /** - * Adds a KeyFrameRequester to be made available through this - * KeyFrameControl. - * - * @param index the zero-based index at which keyFrameRequester is - * to be added to the list of KeyFrameRequesters made available or - * -1 to have this KeyFrameControl choose at which index - * it is to be added in accord with its internal logic - * through this KeyFrameControl - * @param keyFrameRequester the KeyFrameRequester to be added to - * this KeyFrameControl so that it is made available through it - */ - public void addKeyFrameRequester( - int index, - KeyFrameRequester keyFrameRequester); - - /** - * Gets the KeyFrameRequestees made available through this - * KeyFrameControl. - * - * @return an unmodifiable list of KeyFrameRequestees made - * available through this KeyFrameControl - */ - public List getKeyFrameRequestees(); - - /** - * Gets the KeyFrameRequesters made available through this - * KeyFrameControl. - * - * @return an unmodifiable list of KeyFrameRequesters made - * available through this KeyFrameControl - */ - public List getKeyFrameRequesters(); - - /** - * Notifies this KeyFrameControl that the remote peer of the - * associated VideoMediaStream has requested a key frame from the - * local peer. - * - * @return true if the local peer has honored the request from the - * remote peer for a key frame; otherwise, false - */ - public boolean keyFrameRequest(); - - /** - * Removes a KeyFrameRequestee to no longer be made available - * through this KeyFrameControl. - * - * @param keyFrameRequestee the KeyFrameRequestee to be removed - * from this KeyFrameControl so that it is no longer made available - * through it - * @return true if keyFrameRequestee was found in this - * KeyFrameControl; otherwise, false - */ - public boolean removeKeyFrameRequestee(KeyFrameRequestee keyFrameRequestee); - - /** - * Removes a KeyFrameRequester to no longer be made available - * through this KeyFrameControl. - * - * @param keyFrameRequester the KeyFrameRequester to be removed - * from this KeyFrameControl so that it is no longer made available - * through it - * @return true if keyFrameRequester was found in this - * KeyFrameControl; otherwise, false - */ - public boolean removeKeyFrameRequester(KeyFrameRequester keyFrameRequester); - - /** - * Requests a key frame from the remote peer of the associated - * VideoMediaStream. - * - * @param urgent true if the caller has determined that the need - * for a key frame is urgent and should not obey all constraints with - * respect to time between two subsequent requests for key frames - * @return true if a key frame was indeed requested from the remote - * peer of the associated VideoMediaStream in response to the call; - * otherwise, false - */ - public boolean requestKeyFrame(boolean urgent); - - /** - * Represents a way for the remote peer of a VideoMediaStream to - * request a key frame from its local peer. - * - * @author Lyubomir Marinov - */ - public interface KeyFrameRequestee - { - /** - * Notifies this KeyFrameRequestee that the remote peer of the - * associated VideoMediaStream requests a key frame from the - * local peer. - * - * @return true if this KeyFrameRequestee has honored - * the request for a key frame; otherwise, false - */ - public boolean keyFrameRequest(); - } - - /** - * Represents a way for a VideoMediaStream to request a key frame - * from its remote peer. - * - * @author Lyubomir Marinov - */ - public interface KeyFrameRequester - { - /** - * The name of the ConfigurationService property which - * specifies the preferred KeyFrameRequester to be used. - */ - public static final String PREFERRED_PNAME - = "net.java.sip.communicator.impl.neomedia.codec.video.h264." - + "preferredKeyFrameRequester"; - - /** - * The value of the {@link #PREFERRED_PNAME} - * ConfigurationService property which indicates that the - * RTCP KeyFrameRequester is preferred. - */ - public static final String RTCP = "rtcp"; - - /** - * The value of the {@link #PREFERRED_PNAME} - * ConfigurationService property which indicates that the - * signaling/protocol KeyFrameRequester is preferred. - */ - public static final String SIGNALING = "signaling"; - - /** - * The default value of the {@link #PREFERRED_PNAME} - * ConfigurationService property. - */ - public static final String DEFAULT_PREFERRED = RTCP; - - /** - * Requests a key frame from the remote peer of the associated - * VideoMediaStream. - * - * @return true if this KeyFrameRequester has - * indeed requested a key frame from the remote peer of the associated - * VideoMediaStream in response to the call; otherwise, - * false - */ - public boolean requestKeyFrame(); - } -} diff --git a/src/net/java/sip/communicator/service/neomedia/control/KeyFrameControlAdapter.java b/src/net/java/sip/communicator/service/neomedia/control/KeyFrameControlAdapter.java deleted file mode 100644 index b6682d9a3..000000000 --- a/src/net/java/sip/communicator/service/neomedia/control/KeyFrameControlAdapter.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.control; - -import java.util.*; - -/** - * Provides a default implementation of {@link KeyFrameControl}. - * - * @author Lyubomir Marinov - */ -public class KeyFrameControlAdapter - implements KeyFrameControl -{ - /** - * The KeyFrameRequestees made available by this - * KeyFrameControl. - */ - private List keyFrameRequestees - = new ArrayList(0); - - /** - * The KeyFrameRequesters made available by this - * KeyFrameControl. - */ - private List keyFrameRequesters - = new ArrayList(0); - - /** - * An unmodifiable view of {@link #keyFrameRequestees} appropriate to be - * returned by {@link #getKeyFrameRequestees()}. - */ - private List unmodifiableKeyFrameRequestees; - - /** - * An unmodifiable view of {@link #keyFrameRequesters} appropriate to be - * returned by {@link #getKeyFrameRequesters()}. - */ - private List unmodifiableKeyFrameRequesters; - - /** - * Implements - * {@link KeyFrameControl#addKeyFrameRequestee(int, KeyFrameRequestee)}. - * - * {@inheritDoc} - */ - public void addKeyFrameRequestee( - int index, - KeyFrameRequestee keyFrameRequestee) - { - if (keyFrameRequestee == null) - throw new NullPointerException("keyFrameRequestee"); - synchronized (this) - { - if (!keyFrameRequestees.contains(keyFrameRequestee)) - { - List newKeyFrameRequestees - = new ArrayList( - keyFrameRequestees.size() + 1); - - newKeyFrameRequestees.addAll(keyFrameRequestees); - /* - * If this KeyFrameControl is to determine the index at which - * keyFrameRequestee is to be added according to its own - * internal logic, then it will prefer KeyFrameRequestee - * implementations from outside of neomedia rather than from its - * inside. - */ - if (-1 == index) - { - if (keyFrameRequestee.getClass().getName().contains( - ".neomedia.")) - index = newKeyFrameRequestees.size(); - else - index = 0; - } - newKeyFrameRequestees.add(index, keyFrameRequestee); - - keyFrameRequestees = newKeyFrameRequestees; - unmodifiableKeyFrameRequestees = null; - } - } - } - - /** - * Implements - * {@link KeyFrameControl#addKeyFrameRequester(int, KeyFrameRequester)}. - * - * {@inheritDoc} - */ - public void addKeyFrameRequester( - int index, - KeyFrameRequester keyFrameRequester) - { - if (keyFrameRequester == null) - throw new NullPointerException("keyFrameRequester"); - synchronized (this) - { - if (!keyFrameRequesters.contains(keyFrameRequester)) - { - List newKeyFrameRequesters - = new ArrayList( - keyFrameRequesters.size() + 1); - - newKeyFrameRequesters.addAll(keyFrameRequesters); - /* - * If this KeyFrameControl is to determine the index at which - * keyFrameRequester is to be added according to its own - * internal logic, then it will prefer KeyFrameRequester - * implementations from outside of neomedia rather than from its - * inside. - */ - if (-1 == index) - { - if (keyFrameRequester.getClass().getName().contains( - ".neomedia.")) - index = newKeyFrameRequesters.size(); - else - index = 0; - } - newKeyFrameRequesters.add(index, keyFrameRequester); - - keyFrameRequesters = newKeyFrameRequesters; - unmodifiableKeyFrameRequesters = null; - } - } - } - - /** - * Implements {@link KeyFrameControl#getKeyFrameRequestees()}. - * - * {@inheritDoc} - */ - public List getKeyFrameRequestees() - { - synchronized (this) - { - if (unmodifiableKeyFrameRequestees == null) - { - unmodifiableKeyFrameRequestees - = Collections.unmodifiableList(keyFrameRequestees); - } - return unmodifiableKeyFrameRequestees; - } - } - - /** - * Implements {@link KeyFrameControl#getKeyFrameRequesters()}. - * - * {@inheritDoc} - */ - public List getKeyFrameRequesters() - { - synchronized (this) - { - if (unmodifiableKeyFrameRequesters == null) - { - unmodifiableKeyFrameRequesters - = Collections.unmodifiableList(keyFrameRequesters); - } - return unmodifiableKeyFrameRequesters; - } - } - - /** - * Implements {@link KeyFrameControl#keyFrameRequest()}. - * - * {@inheritDoc} - */ - public boolean keyFrameRequest() - { - for (KeyFrameRequestee keyFrameRequestee : getKeyFrameRequestees()) - { - try - { - if (keyFrameRequestee.keyFrameRequest()) - return true; - } - catch (Exception e) - { - /* - * A KeyFrameRequestee has malfunctioned, do not let it - * interfere with the others. - */ - } - } - return false; - } - - /** - * Implements - * {@link KeyFrameControl#removeKeyFrameRequestee(KeyFrameRequestee)}. - * - * {@inheritDoc} - */ - public boolean removeKeyFrameRequestee(KeyFrameRequestee keyFrameRequestee) - { - synchronized (this) - { - int index = keyFrameRequestees.indexOf(keyFrameRequestee); - - if (-1 != index) - { - List newKeyFrameRequestees - = new ArrayList(keyFrameRequestees); - - newKeyFrameRequestees.remove(index); - - keyFrameRequestees = newKeyFrameRequestees; - unmodifiableKeyFrameRequestees = null; - - return true; - } - else - return false; - } - } - - /** - * Implements - * {@link KeyFrameControl#removeKeyFrameRequester(KeyFrameRequester)}. - * - * {@inheritDoc} - */ - public boolean removeKeyFrameRequester(KeyFrameRequester keyFrameRequester) - { - synchronized (this) - { - int index = keyFrameRequesters.indexOf(keyFrameRequester); - - if (-1 != index) - { - List newKeyFrameRequesters - = new ArrayList(keyFrameRequesters); - - newKeyFrameRequesters.remove(index); - - keyFrameRequesters = newKeyFrameRequesters; - unmodifiableKeyFrameRequesters = null; - - return true; - } - else - return false; - } - } - - /** - * Implements {@link KeyFrameControl#requestKeyFrame(boolean)}. - * - * {@inheritDoc} - */ - public boolean requestKeyFrame(boolean urgent) - { - for (KeyFrameRequester keyFrameRequester : getKeyFrameRequesters()) - { - try - { - if (keyFrameRequester.requestKeyFrame()) - return true; - } - catch (Exception e) - { - /* - * A KeyFrameRequestee has malfunctioned, do not let it - * interfere with the others. - */ - } - } - return false; - } -} diff --git a/src/net/java/sip/communicator/service/neomedia/device/MediaDevice.java b/src/net/java/sip/communicator/service/neomedia/device/MediaDevice.java deleted file mode 100644 index 96cb75447..000000000 --- a/src/net/java/sip/communicator/service/neomedia/device/MediaDevice.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.device; - -import java.util.*; - -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.format.*; - -/** - * The MediaDevice class represents capture and playback devices that - * can be used to grab or render media. Sound cards, USB phones and webcams are - * examples of such media devices. - * - * @author Emil Ivov - */ -public interface MediaDevice -{ - - /** - * Returns the MediaDirection supported by this device. - * - * @return MediaDirection.SENDONLY if this is a read-only device, - * MediaDirection.RECVONLY if this is a write-only device and - * MediaDirection.SENDRECV if this MediaDevice can both - * capture and render media. - */ - public MediaDirection getDirection(); - - /** - * Returns the MediaFormat that this device is currently set to use - * when capturing data. - * - * @return the MediaFormat that this device is currently set to - * provide media in. - */ - public MediaFormat getFormat(); - - /** - * Returns the MediaType that this device supports. - * - * @return MediaType.AUDIO if this is an audio device or - * MediaType.VIDEO in case of a video device. - */ - public MediaType getMediaType(); - - /** - * Returns the List of RTPExtensions that this device - * know how to handle. - * - * @return the List of RTPExtensions that this device - * know how to handle or null if the device does not support any - * RTP extensions. - */ - public List getSupportedExtensions(); - - /** - * Returns a list of MediaFormat instances representing the media - * formats supported by this MediaDevice. - * - * @return the list of MediaFormats supported by this device. - */ - public List getSupportedFormats(); - - /** - * Returns a list of MediaFormat instances representing the media - * formats supported by this MediaDevice. - * - * @param localPreset the preset used to set the send format parameters, - * used for video and settings. - * @param remotePreset the preset used to set the receive format parameters, - * used for video and settings. - * - * @return the list of MediaFormats supported by this device. - */ - public List getSupportedFormats( - QualityPreset localPreset, - QualityPreset remotePreset); -} diff --git a/src/net/java/sip/communicator/service/neomedia/device/MediaDeviceWrapper.java b/src/net/java/sip/communicator/service/neomedia/device/MediaDeviceWrapper.java deleted file mode 100644 index 2dee70ea6..000000000 --- a/src/net/java/sip/communicator/service/neomedia/device/MediaDeviceWrapper.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.device; - -/** - * Represents a special-purpose MediaDevice which is effectively built - * on top of and forwarding to another MediaDevice. - * - * @author Lyubomir Marinov - */ -public interface MediaDeviceWrapper - extends MediaDevice -{ - /** - * Gets the actual MediaDevice which this MediaDevice is - * effectively built on top of and forwarding to. - * - * @return the actual MediaDevice which this MediaDevice - * is effectively built on top of and forwarding to - */ - public MediaDevice getWrappedDevice(); -} diff --git a/src/net/java/sip/communicator/service/neomedia/device/ScreenDevice.java b/src/net/java/sip/communicator/service/neomedia/device/ScreenDevice.java deleted file mode 100644 index e481d345b..000000000 --- a/src/net/java/sip/communicator/service/neomedia/device/ScreenDevice.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.device; - -import java.awt.*; - -/** - * Represents a physical screen display. - * - * @author Sebastien Vincent - */ -public interface ScreenDevice -{ - - /** - * Determines whether this screen contains a specified point. - * - * @param p point coordinate - * @return true if point belongs to this screen; - * false, otherwise - */ - public boolean containsPoint(Point p); - - /** - * Gets this screen's index. - * - * @return this screen's index - */ - public int getIndex(); - - /** - * Gets the current resolution of this screen. - * - * @return the current resolution of this screen - */ - public Dimension getSize(); -} diff --git a/src/net/java/sip/communicator/service/neomedia/event/CsrcAudioLevelListener.java b/src/net/java/sip/communicator/service/neomedia/event/CsrcAudioLevelListener.java deleted file mode 100644 index 1644f5641..000000000 --- a/src/net/java/sip/communicator/service/neomedia/event/CsrcAudioLevelListener.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.event; - -/** - * The CsrcAudioLevelListener delivers audio level events reported by - * the remote party in cases where it (the remote party) is acting as a mixer, - * mixing flows from numerous contributors. It is up to upper layers such as - * SIP to define means of determining the exact members that the CSRC IDs and - * hence audio levels participants belong to. - * - * @author Emil Ivov - */ -public interface CsrcAudioLevelListener -{ - /** - * Called by the media service implementation after it has received audio - * levels for the various participants (Contributing SouRCes) that are - * taking part in a conference call. - * - * @param audioLevels a long array in which the elements at the - * even indices specify the CSRC IDs and the elements at the odd indices - * specify the respective audio levels - */ - public void audioLevelsReceived(long[] audioLevels); -} diff --git a/src/net/java/sip/communicator/service/neomedia/event/DTMFListener.java b/src/net/java/sip/communicator/service/neomedia/event/DTMFListener.java deleted file mode 100644 index 4a6156958..000000000 --- a/src/net/java/sip/communicator/service/neomedia/event/DTMFListener.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.event; - -/** - * The purpose of a DTMFListener is to notify implementors when new - * DMTF tones are received by this MediaService implementation. - * - * @author Emil Ivov - */ -public interface DTMFListener -{ - - /** - * Indicates that we have started receiving a DTMFTone. - * - * @param event the DTMFToneEvent instance containing the - * DTMFTone - */ - public void dtmfToneReceptionStarted(DTMFToneEvent event); - - /** - * Indicates that reception of a DTMF tone has stopped. - * - * @param event the DTMFToneEvent instance containing the - * DTMFTone - */ - public void dtmfToneReceptionEnded(DTMFToneEvent event); -} diff --git a/src/net/java/sip/communicator/service/neomedia/event/DTMFToneEvent.java b/src/net/java/sip/communicator/service/neomedia/event/DTMFToneEvent.java deleted file mode 100644 index 48b11b85a..000000000 --- a/src/net/java/sip/communicator/service/neomedia/event/DTMFToneEvent.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.event; - -import java.util.*; - -import net.java.sip.communicator.service.neomedia.*; - -/** - * This event represents starting or ending reception of a specific - * DTMFRtpTone. - * - * @author Emil Ivov - */ -public class DTMFToneEvent - extends EventObject -{ - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * The tone that this event is pertaining to. - */ - private final DTMFRtpTone dtmfTone; - - /** - * Creates an instance of this DTMFToneEvent with the specified - * source stream and DTMF tone. - * - * @param source the AudioMediaSteam instance that received the - * tone. - * @param dtmfTone the tone that we (started/stopped) receiving. - */ - public DTMFToneEvent(AudioMediaStream source, DTMFRtpTone dtmfTone) - { - super(source); - - this.dtmfTone = dtmfTone; - } - - /** - * Returns the DTMFTone instance that this event pertains to. - * - * @return the DTMFTone instance that this event pertains to. - */ - public DTMFRtpTone getDtmfTone() - { - return dtmfTone; - } -} diff --git a/src/net/java/sip/communicator/service/neomedia/event/RTCPFeedbackEvent.java b/src/net/java/sip/communicator/service/neomedia/event/RTCPFeedbackEvent.java deleted file mode 100644 index 6db18ea8f..000000000 --- a/src/net/java/sip/communicator/service/neomedia/event/RTCPFeedbackEvent.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.event; - -import java.util.*; - -/** - * Represents an event coming from RTCP that meant to tell codec - * to do something (i.e send a keyframe, ...). - * - * @author Sebastien Vincent - */ -public class RTCPFeedbackEvent - extends EventObject -{ - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * Transport layer type (payload type). - */ - public static final int PT_TL = 205; - - /** - * Payload-specific type (payload type). - */ - public static final int PT_PS = 206; - - /** - * Picture Loss Indication message type. - */ - public static final int FMT_PLI = 1; - - /** - * Full Intra-frame Request message type. - */ - public static final int FMT_FIR = 4; - - /** - * Feedback message type. - */ - private int feedbackMessageType = 0; - - /** - * Payload type. - */ - private int payloadType = 0; - - /** - * Constructor. - * - * @param src source - * @param feedbackMessageType FMT - * @param payloadType PT - */ - public RTCPFeedbackEvent(Object src, int feedbackMessageType, - int payloadType) - { - super(src); - - this.feedbackMessageType = feedbackMessageType; - this.payloadType = payloadType; - } - - /** - * Get feedback message type. - * - * @return message type - */ - public int getFeedbackMessageType() - { - return feedbackMessageType; - } - - /** - * Get payload type of RTCP packet. - * - * @return payload type - */ - public int getPayloadType() - { - return payloadType; - } -} - diff --git a/src/net/java/sip/communicator/service/neomedia/event/RTCPFeedbackListener.java b/src/net/java/sip/communicator/service/neomedia/event/RTCPFeedbackListener.java deleted file mode 100644 index c94e14744..000000000 --- a/src/net/java/sip/communicator/service/neomedia/event/RTCPFeedbackListener.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.event; - -/** - * RTCPFeedbackListener is used by codec to be notified - * by RTCP feedback event such as PLI (Picture Loss Indication) or - * FIR (Full Intra-frame Request). - * - * @author Sebastien Vincent - */ -public interface RTCPFeedbackListener -{ - /** - * Event fired when RTCP feedback message is received. - * - * @param event RTCPFeedbackEvent - */ - public void feedbackReceived(RTCPFeedbackEvent event); -} - diff --git a/src/net/java/sip/communicator/service/neomedia/event/SimpleAudioLevelListener.java b/src/net/java/sip/communicator/service/neomedia/event/SimpleAudioLevelListener.java deleted file mode 100644 index 0f33048b2..000000000 --- a/src/net/java/sip/communicator/service/neomedia/event/SimpleAudioLevelListener.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.event; - -/** - * A very simple listener that delivers int values every time the audio - * level of an audio source changes. - * - * @author Emil Ivov - */ -public interface SimpleAudioLevelListener -{ - /** - * The maximum level that can be reported for a participant in a conference. - * Level values should be distributed between MAX_LEVEL and - * {@link #MIN_LEVEL} in a way that would appear uniform to users. - *
- */ - public static final int MAX_LEVEL = 127; - - /** - * The maximum (zero) level that can be reported for a participant in a - * conference. Level values should be distributed among {@link #MAX_LEVEL} - * and MIN_LEVEL in a way that would appear uniform to users. - *

- * Note: The value of 127 is specifically chosen as the - * value of MAX_LEVEL because (1) we transport the levels within - * RTP and it gives us a signed byte for it, and (2) the range of - * [0, 127] is pretty good to directly express the sound pressure - * level decibels as heard by humans in Earth's atmosphere. - *

- * Note: The value of 0 is specifically chosen as the value - * of MIN_LEVEL because (1) we transport the levels within RTP and - * it gives us a signed byte for it, and (2) the range of - * [0, 127] is pretty good to directly express the sound pressure - * level decibels as heard by humans in Earth's atmosphere. - *

- */ - public static final int MIN_LEVEL = 0; - - /** - * Indicates a new audio level for the source that this listener was - * registered with. - * @param level the new/current level of the audio source that this - * listener is registered with. - */ - public void audioLevelChanged(int level); -} diff --git a/src/net/java/sip/communicator/service/neomedia/event/SrtpListener.java b/src/net/java/sip/communicator/service/neomedia/event/SrtpListener.java deleted file mode 100644 index 0e291123d..000000000 --- a/src/net/java/sip/communicator/service/neomedia/event/SrtpListener.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.event; - -import net.java.sip.communicator.service.neomedia.*; - -/** - * The ZrtpListener is meant to be used by the media stream creator, as - * the name indicates in order to be notified when a security event has occurred - * that concerns ZRTP. - * - * @author Yana Stamcheva - */ -public interface SrtpListener -{ - /** - * Indicates that the security has been turned on. When we are in the case - * of using multistreams when the master stream ZRTP is initialized and - * established the param multiStreamData holds the data needed for the - * slave streams to establish their sessions. If this is a securityTurnedOn - * event on non master stream the multiStreamData is null. - * - * @param sessionType the type of the call session - audio or video. - * @param cipher the security cipher that encrypts the call - * @param sender the control that initiated the event. - */ - public void securityTurnedOn( int sessionType, - String cipher, - SrtpControl sender); - - /** - * Indicates that the security has been turned off. - * - * @param sessionType the type of the call session - audio or video. - */ - public void securityTurnedOff(int sessionType); - - /** - * Indicates that a security message has occurred associated with a - * failure/warning or information coming from the encryption protocol. - * - * @param message the message. - * @param i18nMessage the internationalized message - * @param severity severity level - */ - public void securityMessageReceived(String message, - String i18nMessage, - int severity); - - /** - * Indicates that the other party has timed out replying to our - * offer to secure the connection. - * - * @param sessionType the type of the call session - audio or video. - */ - public void securityTimeout(int sessionType); - - /** - * Indicates that we started the process of securing the the connection. - * - * @param sessionType the type of the call session - audio or video. - * @param sender the control that initiated the event. - */ - public void securityNegotiationStarted(int sessionType, SrtpControl sender); -} diff --git a/src/net/java/sip/communicator/service/neomedia/event/VolumeChangeEvent.java b/src/net/java/sip/communicator/service/neomedia/event/VolumeChangeEvent.java deleted file mode 100644 index 9347d3dbb..000000000 --- a/src/net/java/sip/communicator/service/neomedia/event/VolumeChangeEvent.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.event; - -import java.util.*; - -import net.java.sip.communicator.service.neomedia.*; - -/** - * Represents the event fired when playback volume value has changed. - * - * @author Damian Minkov - */ -public class VolumeChangeEvent - extends EventObject -{ - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * The volume level. - */ - private final float level; - - /** - * The indicator which determines whether the volume is muted. - */ - private final boolean mute; - - /** - * Initializes a new VolumeChangeEvent which is to notify about a - * specific volume level and its mute state. - * - * @param source the VolumeControl which is the source of the - * change - * @param level the volume level - * @param mute true if the volume is muted; otherwise, - * false - * @throws IllegalArgumentException if source is null - */ - public VolumeChangeEvent(VolumeControl source, float level, boolean mute) - { - super(source); - - this.level = level; - this.mute = mute; - } - - /** - * Gets the VolumeControl which is the source of the change - * notified about by this VolumeChangeEvent. - * - * @return the VolumeControl which is the source of the change - * notified about by this VolumeChangeEvent - */ - public VolumeControl getSourceVolumeControl() - { - return (VolumeControl) getSource(); - } - - /** - * Gets the volume level notified about by this VolumeChangeEvent. - * - * @return the volume level notified about by this - * VolumeChangeEvent - */ - public float getLevel() - { - return level; - } - - /** - * Gets the indicator which determines whether the volume is muted. - * - * @return true if the volume is muted; otherwise, false - */ - public boolean getMute() - { - return mute; - } -} diff --git a/src/net/java/sip/communicator/service/neomedia/event/VolumeChangeListener.java b/src/net/java/sip/communicator/service/neomedia/event/VolumeChangeListener.java deleted file mode 100644 index 7db9568dd..000000000 --- a/src/net/java/sip/communicator/service/neomedia/event/VolumeChangeListener.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.event; - -/** - * VolumeChangeListener used to notify for changes in the - * playback volume. - * - * @author Damian Minkov - */ -public interface VolumeChangeListener -{ - /** - * Event fired when volume has changed. - * @param volumeChangeEvent the volume change event. - */ - public void volumeChange(VolumeChangeEvent volumeChangeEvent); -} diff --git a/src/net/java/sip/communicator/service/neomedia/format/AudioMediaFormat.java b/src/net/java/sip/communicator/service/neomedia/format/AudioMediaFormat.java deleted file mode 100644 index 46a64c75c..000000000 --- a/src/net/java/sip/communicator/service/neomedia/format/AudioMediaFormat.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.format; - -/** - * The interface represents an audio format. Audio formats characterize audio - * streams and the AudioMediaFormat interface gives access to some of its - * properties such as encoding, clock rate, and number of channels. - * - * @author Emil Ivov - */ -public interface AudioMediaFormat - extends MediaFormat -{ - /** - * Returns the number of audio channels associated with this - * AudioMediaFormat. - * - * @return the number of audio channels associated with this - * AudioMediaFormat. - */ - public int getChannels(); -} diff --git a/src/net/java/sip/communicator/service/neomedia/format/MediaFormat.java b/src/net/java/sip/communicator/service/neomedia/format/MediaFormat.java deleted file mode 100644 index 1ffab4868..000000000 --- a/src/net/java/sip/communicator/service/neomedia/format/MediaFormat.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.format; - -import java.util.*; - -import net.java.sip.communicator.service.neomedia.*; - -/** - * The MediaFormat interface represents a generic (i.e. audio/video or - * other) format used to represent media represent a media stream. - *

- * The interface contains utility methods for extracting common media format - * properties such as the name of the underlying encoding, or clock rate or in - * order comparing to compare formats. Extending interfaces representing audio - * or video formats are likely to add other methods. - * - * @author Emil Ivov - * @author Lyubomir Marinov - */ -public interface MediaFormat -{ - - /** - * The constant returned by {@link #getRTPPayloadType()} when the - * MediaFormat instance describes a format without an RTP payload - * type (number) known in RFC 3551 "RTP Profile for Audio and Video - * Conferences with Minimal Control". - */ - public static final byte RTP_PAYLOAD_TYPE_UNKNOWN = -1; - - /** - * The minimum integer that is allowed for use in dynamic payload type - * assignment. - */ - public static final int MIN_DYNAMIC_PAYLOAD_TYPE = 96; - - /** - * The maximum integer that is allowed for use in dynamic payload type - * assignment. - */ - public static final int MAX_DYNAMIC_PAYLOAD_TYPE = 127; - - /** - * Returns the type of this MediaFormat (e.g. audio or video). - * - * @return the MediaType that this format represents (e.g. audio - * or video). - */ - public MediaType getMediaType(); - - /** - * Returns the name of the encoding (i.e. codec) used by this - * MediaFormat. - * - * @return The name of the encoding that this MediaFormat is using. - */ - public String getEncoding(); - - /** - * Returns the clock rate associated with this MediaFormat. - * - * @return The clock rate associated with this format. - */ - public double getClockRate(); - - /** - * Returns a String representation of the clock rate associated - * with this MediaFormat making sure that the value appears as - * an integer (i.e. contains no decimal point) unless it is actually a non - * integer. - * - * @return a String representation of the clock rate associated - * with this MediaFormat. - */ - public String getClockRateString(); - - /** - * Returns a String representation of the real used clock rate - * associated with this MediaFormat making sure that the value - * appears as an integer (i.e. contains no decimal point) unless it is - * actually a non integer. - * This function corrects the problem of the G.722 codec which advertises - * its clock rate to be 8 kHz while 16 kHz is really used to encode the - * stream (that's an error noted in the respective RFC and kept for the sake - * of compatibility.). - * - * @return a String representation of the real used clock rate - * associated with this MediaFormat. - */ - public String getRealUsedClockRateString(); - - /** - * Determines whether this MediaFormat is equal to - * mediaFormat i.e. they have the same encoding, clock rate, format - * parameters, advanced attributes, etc. - * - * @param mediaFormat the MediaFormat to compare to this instance - * @return true if mediaFormat is equal to this format and - * false otherwise. - */ - @Override - public boolean equals(Object mediaFormat); - - /** - * Determines whether the format parameters of this MediaFormat - * match a specific set of format parameters. - * - * @param fmtps the set of format parameters to match to the format - * parameters of this MediaFormat - * @return true if this MediaFormat considers - * fmtps matching its format parameters; otherwise, false - */ - public boolean formatParametersMatch(Map fmtps); - - /** - * Returns a Map containing advanced parameters specific to this - * particular MediaFormat. The parameters returned here are meant - * for use in SIP/SDP or XMPP session descriptions. - * - * @return a Map containing advanced parameters specific to this - * particular MediaFormat - */ - public Map getAdvancedAttributes(); - - /** - * Returns a Map containing parameters specific to this particular - * MediaFormat. The parameters returned here are meant for use in - * SIP/SDP or XMPP session descriptions where they get transported through - * the "fmtp:" attribute or tag respectively. - * - * @return a Map containing parameters specific to this particular - * MediaFormat. - */ - public Map getFormatParameters(); - - /** - * Gets the RTP payload type (number) of this MediaFormat as it is - * known in RFC 3551 "RTP Profile for Audio and Video Conferences with - * Minimal Control". - * - * @return the RTP payload type of this MediaFormat if it is known - * in RFC 3551 "RTP Profile for Audio and Video Conferences with Minimal - * Control"; otherwise, {@link #RTP_PAYLOAD_TYPE_UNKNOWN} - */ - public byte getRTPPayloadType(); - - /** - * Sets additional codec settings. - * - * @param settings additional settings represented by a map. - */ - public void setAdditionalCodecSettings(Map settings); - - /** - * Returns additional codec settings. - * - * @return additional settings represented by a map. - */ - public Map getAdditionalCodecSettings(); - - /** - * Returns a String representation of this MediaFormat - * containing important format attributes such as the encoding for example. - * - * @return a String representation of this MediaFormat. - */ - @Override - public String toString(); -} diff --git a/src/net/java/sip/communicator/service/neomedia/format/MediaFormatFactory.java b/src/net/java/sip/communicator/service/neomedia/format/MediaFormatFactory.java deleted file mode 100644 index 068e69292..000000000 --- a/src/net/java/sip/communicator/service/neomedia/format/MediaFormatFactory.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.format; - -import java.util.*; - -import net.java.sip.communicator.service.neomedia.*; - -/** - * Allows the creation of audio and video MediaFormat instances. - * - * @author Emil Ivov - * @author Lubomir Marinov - */ -public interface MediaFormatFactory -{ - - /** - * The constant to be used as an argument representing number of channels to - * denote that a specific number of channels is not specified. - */ - public static final int CHANNELS_NOT_SPECIFIED = -1; - - /** - * The constant to be used as an argument representing a clock rate to - * denote that a specific clock rate is not specified. - */ - public static final double CLOCK_RATE_NOT_SPECIFIED = -1; - - /** - * Creates an unknown MediaFormat. - * - * @param type MediaType - * @return unknown MediaFormat - */ - public MediaFormat createUnknownMediaFormat(MediaType type); - - /** - * Creates a MediaFormat for the specified encoding with - * default clock rate and set of format parameters. If encoding is - * known to this MediaFormatFactory, returns a - * MediaFormat which is either an AudioMediaFormat or a - * VideoMediaFormat instance. Otherwise, returns null. - * - * @param encoding the well-known encoding (name) to create a - * MediaFormat for - * @return a MediaFormat with the specified encoding which - * is either an AudioMediaFormat or a VideoMediaFormat - * instance if encoding is known to this - * MediaFormatFactory; otherwise, null - */ - public MediaFormat createMediaFormat(String encoding); - - /** - * Creates a MediaFormat for the specified RTP payload type with - * default clock rate and set of format parameters. If - * rtpPayloadType is known to this MediaFormatFactory, - * returns a MediaFormat which is either an - * AudioMediaFormat or a VideoMediaFormat instance. - * Otherwise, returns null. - * - * @param rtpPayloadType the RTP payload type of the MediaFormat to - * create - * @return a MediaFormat with the specified rtpPayloadType - * which is either an AudioMediaFormat or a - * VideoMediaFormat instance if rtpPayloadType is known to - * this MediaFormatFactory; otherwise, null - */ - public MediaFormat createMediaFormat(byte rtpPayloadType); - - /** - * Creates a MediaFormat for the specified encoding with - * the specified clockRate and a default set of format parameters. - * If encoding is known to this MediaFormatFactory, - * returns a MediaFormat which is either an - * AudioMediaFormat or a VideoMediaFormat instance. - * Otherwise, returns null. - * - * @param encoding the well-known encoding (name) to create a - * MediaFormat for - * @param clockRate the clock rate in Hz to create a MediaFormat - * for - * @return a MediaFormat with the specified encoding and - * clockRate which is either an AudioMediaFormat or a - * VideoMediaFormat instance if encoding is known to this - * MediaFormatFactory; otherwise, null - */ - public MediaFormat createMediaFormat( - String encoding, - double clockRate); - - /** - * Creates a MediaFormat for the specified encoding, - * clockRate and channels and a default set of format - * parameters. If encoding is known to this - * MediaFormatFactory, returns a MediaFormat which is - * either an AudioMediaFormat or a VideoMediaFormat - * instance. Otherwise, returns null. - * - * @param encoding the well-known encoding (name) to create a - * MediaFormat for - * @param clockRate the clock rate in Hz to create a MediaFormat - * for - * @param channels the number of available channels (1 for mono, 2 for - * stereo) if it makes sense for the MediaFormat with the specified - * encoding; otherwise, ignored - * @return a MediaFormat with the specified encoding, - * clockRate and channels and a default set of format - * parameters which is either an AudioMediaFormat or a - * VideoMediaFormat instance if encoding is known to this - * MediaFormatFactory; otherwise, null - */ - public MediaFormat createMediaFormat( - String encoding, - double clockRate, - int channels); - - /** - * Creates a MediaFormat for the specified encoding, - * clockRate and set of format parameters. If encoding is - * known to this MediaFormatFactory, returns a MediaFormat - * which is either an AudioMediaFormat or a - * VideoMediaFormat instance. Otherwise, returns null. - * - * @param encoding the well-known encoding (name) to create a - * MediaFormat for - * @param clockRate the clock rate in Hz to create a MediaFormat - * for - * @param formatParams any codec specific parameters which have been - * received via SIP/SDP or XMPP/Jingle - * @param advancedAttrs advanced attributes received via SIP/SDP or - * XMPP/Jingle - * @return a MediaFormat with the specified encoding, - * clockRate and set of format parameters which is either an - * AudioMediaFormat or a VideoMediaFormat instance if - * encoding is known to this MediaFormatFactory; - * otherwise, null - */ - public MediaFormat createMediaFormat( - String encoding, - double clockRate, - Map formatParams, - Map advancedAttrs); - - /** - * Creates a MediaFormat for the specified encoding, - * clockRate, channels and set of format parameters. If - * encoding is known to this MediaFormatFactory, returns a - * MediaFormat which is either an AudioMediaFormat or a - * VideoMediaFormat instance. Otherwise, returns null. - * - * @param encoding the well-known encoding (name) to create a - * MediaFormat for - * @param clockRate the clock rate in Hz to create a MediaFormat - * for - * @param frameRate the frame rate in number of frames per second to - * create a MediaFormat for - * @param channels the number of available channels (1 for mono, 2 for - * stereo) if it makes sense for the MediaFormat with the specified - * encoding; otherwise, ignored - * @param formatParams any codec specific parameters which have been - * received via SIP/SDP or XMPP/Jingle - * @param advancedAttrs advanced attributes received via SIP/SDP or - * XMPP/Jingle - * @return a MediaFormat with the specified encoding, - * clockRate, channels and set of format parameters which - * is either an AudioMediaFormat or a VideoMediaFormat - * instance if encoding is known to this - * MediaFormatFactory; otherwise, null - */ - public MediaFormat createMediaFormat( - String encoding, - double clockRate, - int channels, - float frameRate, - Map formatParams, - Map advancedAttrs); - - /** - * Creates a MediaFormat either for the specified - * rtpPayloadType or for the specified encoding, - * clockRate, channels and set of format parameters. If - * encoding is known to this MediaFormatFactory, ignores - * rtpPayloadType and returns a MediaFormat which is - * either an AudioMediaFormat or a VideoMediaFormat - * instance. If rtpPayloadType is not - * {@link MediaFormat#RTP_PAYLOAD_TYPE_UNKNOWN} and encoding is - * null, uses the encoding associated with rtpPayloadType. - * - * @param rtpPayloadType the RTP payload type to create a - * MediaFormat for; {@link MediaFormat#RTP_PAYLOAD_TYPE_UNKNOWN} if - * encoding is not null. If rtpPayloadType is not - * MediaFormat#RTP_PAYLOAD_TYPE_UNKNOWN and encoding is - * not null, rtpPayloadType is ignored - * @param encoding the well-known encoding (name) to create a - * MediaFormat for; null - * @param clockRate the clock rate in Hz to create a MediaFormat - * for - * @param frameRate the frame rate in number of frames per second to - * create a MediaFormat for - * @param channels the number of available channels (1 for mono, 2 for - * stereo) if it makes sense for the MediaFormat with the specified - * encoding; otherwise, ignored - * @param formatParams any codec specific parameters which have been - * received via SIP/SDP or XMPP/Jingle - * @param advancedAttrs advanced attributes received via SIP/SDP or - * XMPP/Jingle - * @return a MediaFormat with the specified encoding, - * clockRate, channels and set of format parameters which - * is either an AudioMediaFormat or a VideoMediaFormat - * instance if encoding is known to this - * MediaFormatFactory; otherwise, null - */ - public MediaFormat createMediaFormat( - byte rtpPayloadType, - String encoding, - double clockRate, - int channels, - float frameRate, - Map formatParams, - Map advancedAttrs); -} diff --git a/src/net/java/sip/communicator/service/neomedia/format/VideoMediaFormat.java b/src/net/java/sip/communicator/service/neomedia/format/VideoMediaFormat.java deleted file mode 100644 index af32e6fef..000000000 --- a/src/net/java/sip/communicator/service/neomedia/format/VideoMediaFormat.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.neomedia.format; - -import java.awt.*; - -/** - * The interface represents a video format. Video formats characterize video - * streams and the VideoMediaFormat interface gives access to some of - * their properties such as encoding and clock rate. - * - * @author Emil Ivov - */ -public interface VideoMediaFormat - extends MediaFormat -{ - /** - * Returns the size of the image that this VideoMediaFormat - * describes. - * - * @return a java.awt.Dimension instance indicating the image size - * (in pixels) of this VideoMediaFormat. - */ - public Dimension getSize(); - - /** - * Returns the frame rate associated with this MediaFormat. - * - * @return The frame rate associated with this format. - */ - public float getFrameRate(); -} diff --git a/src/net/java/sip/communicator/service/notification/NotificationAction.java b/src/net/java/sip/communicator/service/notification/NotificationAction.java index ae67047dd..c97c740b6 100644 --- a/src/net/java/sip/communicator/service/notification/NotificationAction.java +++ b/src/net/java/sip/communicator/service/notification/NotificationAction.java @@ -97,4 +97,4 @@ public void setEnabled(boolean isEnabled) { this.isEnabled = isEnabled; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/notification/NotificationServiceActivator.java b/src/net/java/sip/communicator/service/notification/NotificationServiceActivator.java index 6599a168a..a2f6932c1 100644 --- a/src/net/java/sip/communicator/service/notification/NotificationServiceActivator.java +++ b/src/net/java/sip/communicator/service/notification/NotificationServiceActivator.java @@ -6,7 +6,7 @@ */ package net.java.sip.communicator.service.notification; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.util.*; import org.osgi.framework.*; diff --git a/src/net/java/sip/communicator/service/notification/NotificationServiceImpl.java b/src/net/java/sip/communicator/service/notification/NotificationServiceImpl.java index e9fb33200..b16e8e563 100644 --- a/src/net/java/sip/communicator/service/notification/NotificationServiceImpl.java +++ b/src/net/java/sip/communicator/service/notification/NotificationServiceImpl.java @@ -8,7 +8,7 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.notification.event.*; import net.java.sip.communicator.util.*; import static net.java.sip.communicator.service.notification.NotificationAction.*; diff --git a/src/net/java/sip/communicator/service/notification/SoundNotificationHandler.java b/src/net/java/sip/communicator/service/notification/SoundNotificationHandler.java index affc26864..46cab32d8 100644 --- a/src/net/java/sip/communicator/service/notification/SoundNotificationHandler.java +++ b/src/net/java/sip/communicator/service/notification/SoundNotificationHandler.java @@ -31,4 +31,4 @@ public interface SoundNotificationHandler * @param data Additional data for the event. */ public void stop(NotificationData data); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/notification/notification.manifest.mf b/src/net/java/sip/communicator/service/notification/notification.manifest.mf index 8a0240d20..6c52f21b5 100644 --- a/src/net/java/sip/communicator/service/notification/notification.manifest.mf +++ b/src/net/java/sip/communicator/service/notification/notification.manifest.mf @@ -8,4 +8,4 @@ Export-Package: net.java.sip.communicator.service.notification, net.java.sip.communicator.service.notification.event Import-Package: org.osgi.framework, net.java.sip.communicator.util, - net.java.sip.communicator.service.configuration + org.jitsi.service.configuration diff --git a/src/net/java/sip/communicator/service/packetlogging/PacketLoggingConfiguration.java b/src/net/java/sip/communicator/service/packetlogging/PacketLoggingConfiguration.java deleted file mode 100644 index 45a4e7168..000000000 --- a/src/net/java/sip/communicator/service/packetlogging/PacketLoggingConfiguration.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.packetlogging; - -/** - * Stores the configuration used by Packet Logging Service. - * - * @author Damian Minkov - */ -public class PacketLoggingConfiguration -{ - /** - * Configuration property for packet logging enabled/disabled. - */ - public final static String PACKET_LOGGING_ENABLED_PROPERTY_NAME - = "net.java.sip.communicator.packetlogging.PACKET_LOGGING_ENABLED"; - - /** - * Configuration property for packet logging for - * sip protocol enabled/disabled. - */ - public final static String PACKET_LOGGING_SIP_ENABLED_PROPERTY_NAME - = "net.java.sip.communicator.packetlogging.PACKET_LOGGING_SIP_ENABLED"; - - /** - * Configuration property for packet logging for - * jabber protocol enabled/disabled. - */ - public final static String PACKET_LOGGING_JABBER_ENABLED_PROPERTY_NAME - = "net.java.sip.communicator.packetlogging.PACKET_LOGGING_JABBER_ENABLED"; - - /** - * Configuration property for packet logging for - * RTP enabled/disabled. - */ - public final static String PACKET_LOGGING_RTP_ENABLED_PROPERTY_NAME - = "net.java.sip.communicator.packetlogging.PACKET_LOGGING_RTP_ENABLED"; - - /** - * Configuration property for packet logging for - * ICE4J enabled/disabled. - */ - public final static String PACKET_LOGGING_ICE4J_ENABLED_PROPERTY_NAME - = "net.java.sip.communicator.packetlogging.PACKET_LOGGING_ICE4J_ENABLED"; - - /** - * Configuration property for packet logging file count. - */ - public final static String PACKET_LOGGING_FILE_COUNT_PROPERTY_NAME - = "net.java.sip.communicator.packetlogging.PACKET_LOGGING_FILE_COUNT"; - - /** - * Configuration property for packet logging file size. - */ - public final static String PACKET_LOGGING_FILE_SIZE_PROPERTY_NAME - = "net.java.sip.communicator.packetlogging.PACKET_LOGGING_FILE_SIZE"; - - /** - * Is Packet Logging Service enabled. - */ - private boolean globalLoggingEnabled = true; - - /** - * Is Packet Logging Service enabled for sip protocol. - */ - private boolean sipLoggingEnabled = true; - - /** - * Is Packet Logging Service enabled for jabber protocol. - */ - private boolean jabberLoggingEnabled = true; - - /** - * Is Packet Logging Service enabled for rtp. - */ - private boolean rtpLoggingEnabled = true; - - /** - * Is Packet Logging Service enabled for ice4j. - */ - private boolean ice4jLoggingEnabled = true; - - /** - * The limit for the file size. - * 0 means no limit. - */ - private long limit = 5000000; - - /** - * The counter for number of files. - */ - private int logfileCount = 3; - - /** - * Checks whether packet logging is enabled in the configuration. - * @return true if packet logging is enabled. - */ - public boolean isGlobalLoggingEnabled() - { - return this.globalLoggingEnabled; - } - - /** - * Checks whether packet logging is enabled in the configuration - * for sip protocol. - * @return true if packet logging is enabled for sip protocol. - */ - public boolean isSipLoggingEnabled() - { - return this.sipLoggingEnabled; - } - - /** - * Checks whether packet logging is enabled in the configuration - * for jabber protocol. - * @return true if packet logging is enabled for jabber protocol. - */ - public boolean isJabberLoggingEnabled() - { - return this.jabberLoggingEnabled; - } - - /** - * Checks whether packet logging is enabled in the configuration - * for RTP. - * @return true if packet logging is enabled for RTP. - */ - public boolean isRTPLoggingEnabled() - { - return this.rtpLoggingEnabled; - } - - /** - * Checks whether packet logging is enabled in the configuration - * for Ice4J. - * @return true if packet logging is enabled for RTP. - */ - public boolean isIce4JLoggingEnabled() - { - return this.ice4jLoggingEnabled; - } - - /** - * The limit for the file size. 0 means no limit. - * @return the file size limit. - */ - public long getLimit() - { - return this.limit; - } - - /** - * The counter for number of files. - * @return the number of file counts. - */ - public int getLogfileCount() - { - return this.logfileCount; - } - - /** - * Change whether packet logging is enabled. - * @param enabled true if we enable it. - */ - public void setGlobalLoggingEnabled(boolean enabled) - { - if(!enabled) - { - // as we are globally off, set it and to services - this.sipLoggingEnabled = false; - this.jabberLoggingEnabled = false; - this.rtpLoggingEnabled = false; - this.ice4jLoggingEnabled = false; - } - - this.globalLoggingEnabled = enabled; - } - - /** - * Change whether packet logging for sip protocol is enabled. - * @param enabled true if we enable it. - */ - public void setSipLoggingEnabled(boolean enabled) - { - this.sipLoggingEnabled = enabled; - } - - /** - * Change whether packet logging for jabber protocol is enabled. - * @param enabled true if we enable it. - */ - public void setJabberLoggingEnabled(boolean enabled) - { - this.jabberLoggingEnabled = enabled; - } - - /** - * Change whether packet logging for RTP is enabled. - * @param enabled true if we enable it. - */ - public void setRTPLoggingEnabled(boolean enabled) - { - this.rtpLoggingEnabled = true; - } - - /** - * Change whether packet logging for Ice4J is enabled. - * @param enabled true if we enable it. - */ - public void setIce4JLoggingEnabled(boolean enabled) - { - this.ice4jLoggingEnabled = true; - } - - /** - * Changes the file size limit. - * @param limit the new limit size. - */ - public void setLimit(long limit) - { - this.limit = limit; - } - - /** - * Changes file count. - * @param logfileCount the new file count. - */ - public void setLogfileCount(int logfileCount) - { - this.logfileCount = logfileCount; - } - -} diff --git a/src/net/java/sip/communicator/service/packetlogging/PacketLoggingService.java b/src/net/java/sip/communicator/service/packetlogging/PacketLoggingService.java deleted file mode 100644 index 537e6448f..000000000 --- a/src/net/java/sip/communicator/service/packetlogging/PacketLoggingService.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.packetlogging; - -/** - * A Packet Logging Service to log packets that were send/received - * by protocols or any other network related services in various formats. - * Its for debugging purposes. - * - * @author Damian Minkov - */ -public interface PacketLoggingService -{ - /** - * These are the services that this packet logging service - * cab handle. - */ - public enum ProtocolName - { - /** - * SIP protocol name. - */ - SIP, - - /** - * Jabber protocol name. - */ - JABBER, - - /** - * RTP protocol name. - */ - RTP, - - /** - * ICE protocol name. - */ - ICE4J - } - - /** - * The transport names. - */ - public enum TransportName - { - /** - * UDP transport name. - */ - UDP, - - /** - * TCP transport name. - */ - TCP - } - - /** - * Checks is logging globally enabled for the service. - * @return is logging enabled. - */ - public boolean isLoggingEnabled(); - - /** - * Checks is logging globally enabled for and is it currently - * available fo the given protocol. - *. - * @param protocol that is checked. - * @return is logging enabled. - */ - public boolean isLoggingEnabled(ProtocolName protocol); - - /** - * Log a packet with all the required information. - * - * @param protocol the source protocol that logs this packet. - * @param sourceAddress the source address of the packet. - * @param sourcePort the source port of the packet. - * @param destinationAddress the destination address. - * @param destinationPort the destination port. - * @param transport the transport this packet uses. - * @param sender are we the sender of the packet or not. - * @param packetContent the packet content. - */ - public void logPacket( - ProtocolName protocol, - byte[] sourceAddress, - int sourcePort, - byte[] destinationAddress, - int destinationPort, - TransportName transport, - boolean sender, - byte[] packetContent); - - /** - * Log a packet with all the required information. - * - * @param protocol the source protocol that logs this packet. - * @param sourceAddress the source address of the packet. - * @param sourcePort the source port of the packet. - * @param destinationAddress the destination address. - * @param destinationPort the destination port. - * @param transport the transport this packet uses. - * @param sender are we the sender of the packet or not. - * @param packetContent the packet content. - * @param packetOffset the packet content offset. - * @param packetLength the packet content length. - */ - public void logPacket( - ProtocolName protocol, - byte[] sourceAddress, - int sourcePort, - byte[] destinationAddress, - int destinationPort, - TransportName transport, - boolean sender, - byte[] packetContent, - int packetOffset, - int packetLength); - - /** - * Returns the current Packet Logging Configuration. - * - * @return the Packet Logging Configuration. - */ - public PacketLoggingConfiguration getConfiguration(); -} diff --git a/src/net/java/sip/communicator/service/protocol/AbstractCallPeer.java b/src/net/java/sip/communicator/service/protocol/AbstractCallPeer.java index 7eb43a882..74538938c 100644 --- a/src/net/java/sip/communicator/service/protocol/AbstractCallPeer.java +++ b/src/net/java/sip/communicator/service/protocol/AbstractCallPeer.java @@ -11,7 +11,9 @@ import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; -import net.java.sip.communicator.util.event.*; + +import org.jitsi.service.protocol.event.*; +import org.jitsi.util.event.*; /** * Provides a default implementation for most of the CallPeer methods diff --git a/src/net/java/sip/communicator/service/protocol/AbstractConferenceMember.java b/src/net/java/sip/communicator/service/protocol/AbstractConferenceMember.java index 739a03a56..eafc2b0d0 100644 --- a/src/net/java/sip/communicator/service/protocol/AbstractConferenceMember.java +++ b/src/net/java/sip/communicator/service/protocol/AbstractConferenceMember.java @@ -6,7 +6,7 @@ */ package net.java.sip.communicator.service.protocol; -import net.java.sip.communicator.util.event.*; +import org.jitsi.util.event.*; /** * Provides the default implementation of the ConferenceMember diff --git a/src/net/java/sip/communicator/service/protocol/AccountManager.java b/src/net/java/sip/communicator/service/protocol/AccountManager.java index 4aa3a426a..14b9aa653 100644 --- a/src/net/java/sip/communicator/service/protocol/AccountManager.java +++ b/src/net/java/sip/communicator/service/protocol/AccountManager.java @@ -8,11 +8,11 @@ import java.util.*; -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.service.credentialsstorage.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.configuration.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/service/protocol/CallPeer.java b/src/net/java/sip/communicator/service/protocol/CallPeer.java index 855dd68ea..8ecec6e7c 100644 --- a/src/net/java/sip/communicator/service/protocol/CallPeer.java +++ b/src/net/java/sip/communicator/service/protocol/CallPeer.java @@ -6,11 +6,13 @@ */ package net.java.sip.communicator.service.protocol; -import java.net.*; import java.beans.*; +import java.net.*; import net.java.sip.communicator.service.protocol.event.*; +import org.jitsi.service.protocol.event.*; + /** * The CallPeer is an interface that represents peers in a call. * Users of the UIService need to implement this interface (or one of its diff --git a/src/net/java/sip/communicator/service/protocol/DTMFTone.java b/src/net/java/sip/communicator/service/protocol/DTMFTone.java deleted file mode 100644 index 9a1a69c16..000000000 --- a/src/net/java/sip/communicator/service/protocol/DTMFTone.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.protocol; - -/** - * Class for representing all the different DTMF tones. - * - * @author JM HEITZ - */ -public final class DTMFTone -{ - /** - * The "A" DTMF Tone - */ - public static final DTMFTone DTMF_A=new DTMFTone("A"); - - /** - * The "B" DTMF Tone - */ - public static final DTMFTone DTMF_B=new DTMFTone("B"); - - /** - * The "C" DTMF Tone - */ - public static final DTMFTone DTMF_C=new DTMFTone("C"); - - /** - * The "D" DTMF Tone - */ - public static final DTMFTone DTMF_D=new DTMFTone("D"); - - /** - * The "0" DTMF Tone - */ - public static final DTMFTone DTMF_0=new DTMFTone("0"); - - /** - * The "1" DTMF Tone - */ - public static final DTMFTone DTMF_1=new DTMFTone("1"); - - /** - * The "2" DTMF Tone - */ - public static final DTMFTone DTMF_2=new DTMFTone("2"); - - /** - * The "3" DTMF Tone - */ - public static final DTMFTone DTMF_3=new DTMFTone("3"); - - /** - * The "4" DTMF Tone - */ - public static final DTMFTone DTMF_4=new DTMFTone("4"); - - /** - * The "5" DTMF Tone - */ - public static final DTMFTone DTMF_5=new DTMFTone("5"); - - /** - * The "6" DTMF Tone - */ - public static final DTMFTone DTMF_6=new DTMFTone("6"); - - /** - * The "7" DTMF Tone - */ - public static final DTMFTone DTMF_7=new DTMFTone("7"); - - /** - * The "8" DTMF Tone - */ - public static final DTMFTone DTMF_8=new DTMFTone("8"); - - /** - * The "9" DTMF Tone - */ - public static final DTMFTone DTMF_9=new DTMFTone("9"); - - /** - * The "*" DTMF Tone - */ - public static final DTMFTone DTMF_STAR=new DTMFTone("*"); - - /** - * The "#" DTMF Tone - */ - public static final DTMFTone DTMF_SHARP=new DTMFTone("#"); - - /** - * The value of the DTMF tone - */ - private final String value; - - /** - * Creates a DTMF instance with the specified tone value. The method is - * private since one would only have to use predefined static instances. - * - * @param value one of te DTMF_XXX fields, indicating the value of the tone. - */ - private DTMFTone(String value) - { - this.value = value; - } - - /** - * Returns the string representation of this DTMF tone. - * - * @return the String representation of this DTMF tone. - */ - public String getValue() - { - return this.value; - } - - /** - * Indicates whether some other object is "equal to" this tone. - *

- * @param target the reference object with which to compare. - * - * @return true if target represents the same tone as this - * object. - */ - public boolean equals(Object target) - { - if(!(target instanceof DTMFTone)) - { - return false; - } - DTMFTone targetDTMFTone = (DTMFTone)(target); - - return targetDTMFTone.value.equals(this.value); - } - - /** - * Returns a hash code value for the object. This method is - * supported for the benefit of hashtables such as those provided by - * java.util.Hashtable. The method would actually return the - * hashcode of the string representation of this DTMF tone. - *

- * - * @return a hash code value for this object (same as calling - * getValue().hashCode()). - */ - public int hashCode() - { - return getValue().hashCode(); - } - - /** - * Parses input value and return the corresponding tone. - * If unknown will return null; - * @param value the input value. - * @return the corresponding tone, null for unknown. - */ - public static DTMFTone getDTMFTone(String value) - { - if(value == null) - return null; - else if(value.equals(DTMF_0.getValue())) - return DTMF_0; - else if(value.equals(DTMF_1.getValue())) - return DTMF_1; - else if(value.equals(DTMF_2.getValue())) - return DTMF_2; - else if(value.equals(DTMF_3.getValue())) - return DTMF_3; - else if(value.equals(DTMF_4.getValue())) - return DTMF_4; - else if(value.equals(DTMF_5.getValue())) - return DTMF_5; - else if(value.equals(DTMF_6.getValue())) - return DTMF_6; - else if(value.equals(DTMF_7.getValue())) - return DTMF_7; - else if(value.equals(DTMF_8.getValue())) - return DTMF_8; - else if(value.equals(DTMF_9.getValue())) - return DTMF_9; - else if(value.equals(DTMF_A.getValue())) - return DTMF_A; - else if(value.equals(DTMF_B.getValue())) - return DTMF_B; - else if(value.equals(DTMF_C.getValue())) - return DTMF_C; - else if(value.equals(DTMF_D.getValue())) - return DTMF_D; - else if(value.equals(DTMF_SHARP.getValue())) - return DTMF_SHARP; - else if(value.equals(DTMF_STAR.getValue())) - return DTMF_STAR; - else - return null; - } -} diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetBasicTelephony.java b/src/net/java/sip/communicator/service/protocol/OperationSetBasicTelephony.java index 12b7c7be1..e73229d3f 100644 --- a/src/net/java/sip/communicator/service/protocol/OperationSetBasicTelephony.java +++ b/src/net/java/sip/communicator/service/protocol/OperationSetBasicTelephony.java @@ -9,9 +9,10 @@ import java.text.*; import java.util.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.event.*; +import org.jitsi.service.neomedia.*; + /** * An Operation Set defining all basic telephony operations such as conducting * simple calls and etc. Note that video is not considered as a part of a diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetDTMF.java b/src/net/java/sip/communicator/service/protocol/OperationSetDTMF.java index cd1ab2bf1..d39449b72 100644 --- a/src/net/java/sip/communicator/service/protocol/OperationSetDTMF.java +++ b/src/net/java/sip/communicator/service/protocol/OperationSetDTMF.java @@ -6,6 +6,8 @@ */ package net.java.sip.communicator.service.protocol; +import org.jitsi.service.protocol.*; + /** * An OperationSet that allows other modules to send DMF tones through * this protocol provider. diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetDesktopStreaming.java b/src/net/java/sip/communicator/service/protocol/OperationSetDesktopStreaming.java index 6377622f3..11b8e6f6b 100644 --- a/src/net/java/sip/communicator/service/protocol/OperationSetDesktopStreaming.java +++ b/src/net/java/sip/communicator/service/protocol/OperationSetDesktopStreaming.java @@ -8,7 +8,7 @@ import java.text.*; -import net.java.sip.communicator.service.neomedia.device.*; +import org.jitsi.service.neomedia.device.*; /** * Represents an OperationSet giving access to desktop streaming @@ -95,4 +95,4 @@ public void setLocalVideoAllowed( Call call, */ public void movePartialDesktopStreaming(Call call, int x, int y); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetVideoTelephony.java b/src/net/java/sip/communicator/service/protocol/OperationSetVideoTelephony.java index a6119bd1b..c9f56d33c 100644 --- a/src/net/java/sip/communicator/service/protocol/OperationSetVideoTelephony.java +++ b/src/net/java/sip/communicator/service/protocol/OperationSetVideoTelephony.java @@ -11,9 +11,10 @@ import java.text.*; import java.util.List; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.util.event.*; + +import org.jitsi.service.neomedia.*; +import org.jitsi.util.event.*; /** * Represents an OperationSet giving access to video-specific diff --git a/src/net/java/sip/communicator/service/protocol/ProtocolProviderActivator.java b/src/net/java/sip/communicator/service/protocol/ProtocolProviderActivator.java index eec179916..39186773f 100644 --- a/src/net/java/sip/communicator/service/protocol/ProtocolProviderActivator.java +++ b/src/net/java/sip/communicator/service/protocol/ProtocolProviderActivator.java @@ -6,12 +6,12 @@ */ package net.java.sip.communicator.service.protocol; -import org.osgi.framework.*; - -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; +import org.osgi.framework.*; + /** * Implements BundleActivator for the purposes of * protocol.jar/protocol.provider.manifest.mf and in order to register and start diff --git a/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java b/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java index 8e8560a4a..e3a1a45f9 100644 --- a/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java +++ b/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java @@ -9,7 +9,7 @@ import java.lang.reflect.*; import java.util.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.credentialsstorage.*; import net.java.sip.communicator.util.*; diff --git a/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceListener.java b/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceListener.java index 560398174..32ae1190c 100644 --- a/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceListener.java +++ b/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceListener.java @@ -29,4 +29,4 @@ public interface AdHocChatRoomParticipantPresenceListener */ public void participantPresenceChanged( AdHocChatRoomParticipantPresenceChangeEvent evt); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/protocol/event/CallEvent.java b/src/net/java/sip/communicator/service/protocol/event/CallEvent.java index f5639617b..c059349ed 100644 --- a/src/net/java/sip/communicator/service/protocol/event/CallEvent.java +++ b/src/net/java/sip/communicator/service/protocol/event/CallEvent.java @@ -8,9 +8,10 @@ import java.util.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; +import org.jitsi.service.neomedia.*; + /** * An event class representing that an incoming or an outgoing call has been * created. The event id indicates the exact reason for this event. diff --git a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityListener.java b/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityListener.java index db07b48f1..a7c2d7c54 100755 --- a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityListener.java +++ b/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityListener.java @@ -8,6 +8,8 @@ import java.util.*; +import org.jitsi.service.protocol.event.*; + /** * CallPeerSecurityListener interface extends EventListener. This is the * listener interface used to handle an event related with a change in security diff --git a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityMessageEvent.java b/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityMessageEvent.java deleted file mode 100644 index 8543dc880..000000000 --- a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityMessageEvent.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.protocol.event; - -import java.util.*; - -/** - * The CallPeerSecurityFailedEvent is triggered whenever - * a problem has occurred during call security process. - * - * @author Yana Stamcheva - * @author Werner Dittmann - */ -public class CallPeerSecurityMessageEvent - extends EventObject -{ - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * This is a information message. Security will be established. - */ - public static final int INFORMATION = 0; - - /** - * This is a warning message. Security will not be established. - */ - public static final int WARNING = 1; - - /** - * This is a severe error. Security will not be established. - */ - public static final int SEVERE = 2; - - /** - * This is a ZRTP error message. Security will not be established. - */ - public static final int ERROR = 3; - - /** - * The internationalized message associated with this event. - */ - private final String eventI18nMessage; - - /** - * The message associated with this event. - */ - private final String eventMessage; - - /** - * The severity of the security message event. - */ - private final int eventSeverity; - - /** - * Creates a CallPeerSecurityFailedEvent by specifying the - * call peer, event type and message associated with this event. - * - * @param source the object on which the event initially occurred - * @param eventMessage the message associated with this event. - * @param i18nMessage the internationalized message associated with this - * event that could be shown to the user. - * @param eventSeverity severity level. - */ - public CallPeerSecurityMessageEvent( - Object source, - String eventMessage, - String i18nMessage, - int eventSeverity) - { - super(source); - - this.eventMessage = eventMessage; - this.eventI18nMessage = i18nMessage; - this.eventSeverity = eventSeverity; - } - - /** - * Returns the message associated with this event. - * - * @return the message associated with this event. - */ - public String getMessage() - { - return eventMessage; - } - - /** - * Returns the internationalized message associated with this event. - * - * @return the internationalized message associated with this event. - */ - public String getI18nMessage() - { - return eventI18nMessage; - } - - /** - * Returns the event severity. - * - * @return the eventSeverity - */ - public int getEventSeverity() { - return eventSeverity; - } -} diff --git a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityNegotiationStartedEvent.java b/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityNegotiationStartedEvent.java index 61009b39b..9a86e8759 100644 --- a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityNegotiationStartedEvent.java +++ b/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityNegotiationStartedEvent.java @@ -6,9 +6,11 @@ */ package net.java.sip.communicator.service.protocol.event; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.protocol.event.*; + /** * The CallPeerSecurityNegotiationStartedEvent is triggered whenever a * communication with a given peer is established, diff --git a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityOffEvent.java b/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityOffEvent.java index 1e247aa34..73c713e94 100644 --- a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityOffEvent.java +++ b/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityOffEvent.java @@ -8,6 +8,8 @@ import net.java.sip.communicator.service.protocol.*; +import org.jitsi.service.protocol.event.*; + /** * The CallPeerSecurityAuthenticationEvent is triggered whenever * a the security strings are received in a secure call. diff --git a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityOnEvent.java b/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityOnEvent.java index 976952f8d..210a53629 100644 --- a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityOnEvent.java +++ b/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityOnEvent.java @@ -6,9 +6,11 @@ */ package net.java.sip.communicator.service.protocol.event; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.protocol.event.*; + /** * The CallPeerSecurityOnEvent is triggered whenever a * communication with a given peer is going secure. diff --git a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityStatusEvent.java b/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityStatusEvent.java deleted file mode 100644 index 6720f4bd4..000000000 --- a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityStatusEvent.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.protocol.event; - -import java.util.*; - -/** - * Parent class for SecurityOn and SecurityOff events. - * - * @author Yana Stamcheva - */ -public abstract class CallPeerSecurityStatusEvent - extends EventObject -{ - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * Constant value defining that security is enabled. - */ - public static final int AUDIO_SESSION = 1; - - /** - * Constant value defining that security is disabled. - */ - public static final int VIDEO_SESSION = 2; - - /** - * Session type of the event {@link #AUDIO_SESSION} or - * {@link #VIDEO_SESSION}. - */ - private final int sessionType; - - /** - * Constructor required by the EventObject. - * - * @param source the source object for this event. - * @param sessionType either AUDIO_SESSION or - * VIDEO_SESSION to indicate the type of the - * session - */ - public CallPeerSecurityStatusEvent(Object source, int sessionType) - { - super(source); - - this.sessionType = sessionType; - } - - /** - * Returns the type of the session, either AUDIO_SESSION or VIDEO_SESSION. - * - * @return the type of the session, either AUDIO_SESSION or VIDEO_SESSION. - */ - public int getSessionType() - { - return sessionType; - } -} diff --git a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityTimeoutEvent.java b/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityTimeoutEvent.java index 63f546e05..5014a8966 100644 --- a/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityTimeoutEvent.java +++ b/src/net/java/sip/communicator/service/protocol/event/CallPeerSecurityTimeoutEvent.java @@ -8,6 +8,8 @@ import net.java.sip.communicator.service.protocol.*; +import org.jitsi.service.protocol.event.*; + /** * The CallPeerSecurityTimeoutEvent is triggered whenever a * communication with a given peer cannot be established, the peer diff --git a/src/net/java/sip/communicator/service/protocol/event/DTMFReceivedEvent.java b/src/net/java/sip/communicator/service/protocol/event/DTMFReceivedEvent.java index 319eac660..84cac5eaa 100644 --- a/src/net/java/sip/communicator/service/protocol/event/DTMFReceivedEvent.java +++ b/src/net/java/sip/communicator/service/protocol/event/DTMFReceivedEvent.java @@ -6,9 +6,11 @@ */ package net.java.sip.communicator.service.protocol.event; +import java.util.*; + import net.java.sip.communicator.service.protocol.*; -import java.util.*; +import org.jitsi.service.protocol.*; /** * DTMFReceivedEvents indicate reception of a DTMF tone. diff --git a/src/net/java/sip/communicator/service/protocol/event/WhiteboardInvitationReceivedEvent.java b/src/net/java/sip/communicator/service/protocol/event/WhiteboardInvitationReceivedEvent.java index 724d479d8..d92c7d360 100644 --- a/src/net/java/sip/communicator/service/protocol/event/WhiteboardInvitationReceivedEvent.java +++ b/src/net/java/sip/communicator/service/protocol/event/WhiteboardInvitationReceivedEvent.java @@ -84,4 +84,4 @@ public Date getTimestamp() { return timestamp; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/protocol/event/WhiteboardInvitationRejectedEvent.java b/src/net/java/sip/communicator/service/protocol/event/WhiteboardInvitationRejectedEvent.java index afed27a3b..b7d096157 100644 --- a/src/net/java/sip/communicator/service/protocol/event/WhiteboardInvitationRejectedEvent.java +++ b/src/net/java/sip/communicator/service/protocol/event/WhiteboardInvitationRejectedEvent.java @@ -122,4 +122,4 @@ public Date getTimestamp() return timestamp; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/protocol/event/WhiteboardObjectDeletedEvent.java b/src/net/java/sip/communicator/service/protocol/event/WhiteboardObjectDeletedEvent.java index ac9457fd4..8daeb8586 100644 --- a/src/net/java/sip/communicator/service/protocol/event/WhiteboardObjectDeletedEvent.java +++ b/src/net/java/sip/communicator/service/protocol/event/WhiteboardObjectDeletedEvent.java @@ -105,4 +105,4 @@ public Date getTimestamp () { return timestamp; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/protocol/event/WhiteboardSessionPresenceChangeEvent.java b/src/net/java/sip/communicator/service/protocol/event/WhiteboardSessionPresenceChangeEvent.java index 6234dc14b..960ce72f5 100644 --- a/src/net/java/sip/communicator/service/protocol/event/WhiteboardSessionPresenceChangeEvent.java +++ b/src/net/java/sip/communicator/service/protocol/event/WhiteboardSessionPresenceChangeEvent.java @@ -150,4 +150,4 @@ public String toString() + getWhiteboardSession() + "]"; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetBasicTelephony.java b/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetBasicTelephony.java index c1a7ca850..96e41b44d 100644 --- a/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetBasicTelephony.java +++ b/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetBasicTelephony.java @@ -8,11 +8,12 @@ import java.util.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.neomedia.*; + /** * Represents a default implementation of OperationSetBasicTelephony in * order to make it easier for implementers to provide complete solutions while diff --git a/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetVideoTelephony.java b/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetVideoTelephony.java index 9e9074ee4..f2f033bdf 100644 --- a/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetVideoTelephony.java +++ b/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetVideoTelephony.java @@ -11,10 +11,11 @@ import java.text.*; import java.util.List; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.util.event.*; + +import org.jitsi.service.neomedia.*; +import org.jitsi.util.event.*; /** * Represents a default implementation of OperationSetVideoTelephony in diff --git a/src/net/java/sip/communicator/service/protocol/media/AbstractQualityControlWrapper.java b/src/net/java/sip/communicator/service/protocol/media/AbstractQualityControlWrapper.java index c8114e9de..60d1b4497 100644 --- a/src/net/java/sip/communicator/service/protocol/media/AbstractQualityControlWrapper.java +++ b/src/net/java/sip/communicator/service/protocol/media/AbstractQualityControlWrapper.java @@ -6,8 +6,8 @@ */ package net.java.sip.communicator.service.protocol.media; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.protocol.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.protocol.*; /** * A wrapper of media quality control. @@ -146,4 +146,4 @@ public void setRemoteSendMaxPreset(QualityPreset preset) */ public abstract void setPreferredRemoteSendMaxPreset(QualityPreset preset) throws OperationFailedException; -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java b/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java index 3affd164f..314a4d262 100644 --- a/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java +++ b/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java @@ -11,14 +11,15 @@ import java.util.*; import java.util.List; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.control.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.event.*; -import net.java.sip.communicator.service.neomedia.format.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.util.event.*; + +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.control.*; +import org.jitsi.service.neomedia.device.*; +import org.jitsi.service.neomedia.event.*; +import org.jitsi.service.neomedia.format.*; +import org.jitsi.util.event.*; /** * A utility class implementing media control code shared between current diff --git a/src/net/java/sip/communicator/service/protocol/media/DynamicPayloadTypeRegistry.java b/src/net/java/sip/communicator/service/protocol/media/DynamicPayloadTypeRegistry.java index 57ab34408..794ff412b 100644 --- a/src/net/java/sip/communicator/service/protocol/media/DynamicPayloadTypeRegistry.java +++ b/src/net/java/sip/communicator/service/protocol/media/DynamicPayloadTypeRegistry.java @@ -8,8 +8,8 @@ import java.util.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.format.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.format.*; /** * The RTP Audio/Video Profile [RFC 3551] specifies a number of static payload diff --git a/src/net/java/sip/communicator/service/protocol/media/DynamicRTPExtensionsRegistry.java b/src/net/java/sip/communicator/service/protocol/media/DynamicRTPExtensionsRegistry.java index 18c817533..9a9e6541d 100644 --- a/src/net/java/sip/communicator/service/protocol/media/DynamicRTPExtensionsRegistry.java +++ b/src/net/java/sip/communicator/service/protocol/media/DynamicRTPExtensionsRegistry.java @@ -8,7 +8,7 @@ import java.util.*; -import net.java.sip.communicator.service.neomedia.*; +import org.jitsi.service.neomedia.*; /** * RFC [RFC 5285] defines a mechanism for attaching multiple extensions to diff --git a/src/net/java/sip/communicator/service/protocol/media/MediaAwareCall.java b/src/net/java/sip/communicator/service/protocol/media/MediaAwareCall.java index 2a05646a6..81b661998 100644 --- a/src/net/java/sip/communicator/service/protocol/media/MediaAwareCall.java +++ b/src/net/java/sip/communicator/service/protocol/media/MediaAwareCall.java @@ -9,12 +9,13 @@ import java.beans.*; import java.util.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.event.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.util.*; + +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.device.*; +import org.jitsi.service.neomedia.event.*; +import org.jitsi.util.*; /** * A utility class implementing media control code shared between current diff --git a/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallPeer.java b/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallPeer.java index 545cf2013..95a7afae6 100644 --- a/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallPeer.java +++ b/src/net/java/sip/communicator/service/protocol/media/MediaAwareCallPeer.java @@ -9,12 +9,13 @@ import java.beans.*; import java.util.*; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.event.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.event.*; + /** * A utility class implementing media control code shared between current * telephony implementations. This class is only meant for use by protocol diff --git a/src/net/java/sip/communicator/service/protocol/media/MediaHandler.java b/src/net/java/sip/communicator/service/protocol/media/MediaHandler.java index f1df1265f..d51cee4b0 100644 --- a/src/net/java/sip/communicator/service/protocol/media/MediaHandler.java +++ b/src/net/java/sip/communicator/service/protocol/media/MediaHandler.java @@ -11,14 +11,15 @@ import java.util.*; import java.util.List; -import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.service.neomedia.control.*; -import net.java.sip.communicator.service.neomedia.device.*; -import net.java.sip.communicator.service.neomedia.event.*; -import net.java.sip.communicator.service.neomedia.format.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; -import net.java.sip.communicator.util.event.*; + +import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.control.*; +import org.jitsi.service.neomedia.device.*; +import org.jitsi.service.neomedia.event.*; +import org.jitsi.service.neomedia.format.*; +import org.jitsi.util.event.*; /** * Implements media control code which allows state sharing among multiple diff --git a/src/net/java/sip/communicator/service/protocol/media/ProtocolMediaActivator.java b/src/net/java/sip/communicator/service/protocol/media/ProtocolMediaActivator.java index 3f7f406cd..a6f95f945 100644 --- a/src/net/java/sip/communicator/service/protocol/media/ProtocolMediaActivator.java +++ b/src/net/java/sip/communicator/service/protocol/media/ProtocolMediaActivator.java @@ -6,11 +6,11 @@ */ package net.java.sip.communicator.service.protocol.media; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.netaddr.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.neomedia.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/service/protocol/media/TransportManager.java b/src/net/java/sip/communicator/service/protocol/media/TransportManager.java index 40eac4868..6a3cd6a22 100644 --- a/src/net/java/sip/communicator/service/protocol/media/TransportManager.java +++ b/src/net/java/sip/communicator/service/protocol/media/TransportManager.java @@ -9,13 +9,13 @@ import java.net.*; import java.util.*; -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.netaddr.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; import org.ice4j.ice.*; +import org.jitsi.service.configuration.*; +import org.jitsi.service.neomedia.*; /** * TransportManagers are responsible for allocating ports, gathering diff --git a/src/net/java/sip/communicator/service/protocol/media/protocol.media.manifest.mf b/src/net/java/sip/communicator/service/protocol/media/protocol.media.manifest.mf index 8f640cb77..7955aad67 100644 --- a/src/net/java/sip/communicator/service/protocol/media/protocol.media.manifest.mf +++ b/src/net/java/sip/communicator/service/protocol/media/protocol.media.manifest.mf @@ -5,15 +5,16 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, - net.java.sip.communicator.service.neomedia, - net.java.sip.communicator.service.neomedia.control, - net.java.sip.communicator.service.neomedia.device, - net.java.sip.communicator.service.neomedia.event, - net.java.sip.communicator.service.neomedia.format, + org.jitsi.service.configuration, + org.jitsi.service.neomedia, + org.jitsi.service.neomedia.control, + org.jitsi.service.neomedia.device, + org.jitsi.service.neomedia.event, + org.jitsi.service.neomedia.format, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.netaddr, + org.jitsi.util, net.java.sip.communicator.util, net.java.sip.communicator.util.event, org.ice4j.ice diff --git a/src/net/java/sip/communicator/service/protocol/protocol.provider.manifest.mf b/src/net/java/sip/communicator/service/protocol/protocol.provider.manifest.mf index 00a5c7409..7da2c040b 100644 --- a/src/net/java/sip/communicator/service/protocol/protocol.provider.manifest.mf +++ b/src/net/java/sip/communicator/service/protocol/protocol.provider.manifest.mf @@ -5,10 +5,10 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.credentialsstorage, - net.java.sip.communicator.service.neomedia, - net.java.sip.communicator.service.resources, + org.jitsi.service.neomedia, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, net.java.sip.communicator.util.event Export-Package: net.java.sip.communicator.service.protocol, diff --git a/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObject.java b/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObject.java index 73e44910e..9f291e4b8 100644 --- a/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObject.java +++ b/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObject.java @@ -69,4 +69,4 @@ public interface WhiteboardObject public void setColor(int color); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectCircle.java b/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectCircle.java index 080897593..8f3c7d697 100644 --- a/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectCircle.java +++ b/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectCircle.java @@ -83,4 +83,4 @@ public interface WhiteboardObjectCircle extends WhiteboardObject * @return the RGB value of the background color of this object. */ public int getBackgroundColor (); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectEllipse.java b/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectEllipse.java index f612e595e..2aae1ef35 100644 --- a/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectEllipse.java +++ b/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectEllipse.java @@ -97,4 +97,4 @@ public interface WhiteboardObjectEllipse extends WhiteboardObject * @return the RGB value of the background color of this object. */ public int getBackgroundColor (); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectImage.java b/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectImage.java index 4c4ee6f92..7a51fddf3 100644 --- a/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectImage.java +++ b/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectImage.java @@ -81,4 +81,4 @@ public interface WhiteboardObjectImage extends WhiteboardObject * the object background. */ public byte[] getBackgroundImage(); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectLine.java b/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectLine.java index fa7a22389..8c3a4ed36 100644 --- a/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectLine.java +++ b/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectLine.java @@ -49,4 +49,4 @@ public interface WhiteboardObjectLine extends WhiteboardObject * @param whiteboardPointEnd the new end coordinates for this line. */ public void setWhiteboardPointEnd(WhiteboardPoint whiteboardPointEnd); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectRect.java b/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectRect.java index fe3c2f656..e9e3dcbbf 100644 --- a/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectRect.java +++ b/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectRect.java @@ -97,4 +97,4 @@ public interface WhiteboardObjectRect extends WhiteboardObject * @return the RGB value of the background color of this object. */ public int getBackgroundColor (); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectText.java b/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectText.java index 443e35c28..5d8cec565 100644 --- a/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectText.java +++ b/src/net/java/sip/communicator/service/protocol/whiteboardobjects/WhiteboardObjectText.java @@ -78,4 +78,4 @@ public interface WhiteboardObjectText extends WhiteboardObject * @param fontName the new WhiteboardObjectText's font name. */ public void setFontName(String fontName); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/provdisc/provdisc.manifest.mf b/src/net/java/sip/communicator/service/provdisc/provdisc.manifest.mf index 8790e7d2e..ac539c081 100644 --- a/src/net/java/sip/communicator/service/provdisc/provdisc.manifest.mf +++ b/src/net/java/sip/communicator/service/provdisc/provdisc.manifest.mf @@ -4,4 +4,4 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Export-Package: net.java.sip.communicator.service.provdisc, - net.java.sip.communicator.service.provdisc.event \ No newline at end of file + net.java.sip.communicator.service.provdisc.event diff --git a/src/net/java/sip/communicator/service/replacement/ReplacementProperty.java b/src/net/java/sip/communicator/service/replacement/ReplacementProperty.java index f92fe684a..179dbf791 100644 --- a/src/net/java/sip/communicator/service/replacement/ReplacementProperty.java +++ b/src/net/java/sip/communicator/service/replacement/ReplacementProperty.java @@ -31,4 +31,4 @@ public static String getPropertyName(String source) + source + ".enable"; } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/replacement/ReplacementService.java b/src/net/java/sip/communicator/service/replacement/ReplacementService.java index ca42b6b7a..f932eed73 100644 --- a/src/net/java/sip/communicator/service/replacement/ReplacementService.java +++ b/src/net/java/sip/communicator/service/replacement/ReplacementService.java @@ -41,4 +41,4 @@ public interface ReplacementService * @return the pattern of the source */ public String getPattern(); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/replacement/replacement.manifest.mf b/src/net/java/sip/communicator/service/replacement/replacement.manifest.mf index c580e7ef8..27b81e381 100644 --- a/src/net/java/sip/communicator/service/replacement/replacement.manifest.mf +++ b/src/net/java/sip/communicator/service/replacement/replacement.manifest.mf @@ -4,4 +4,4 @@ Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 System-Bundle: yes Export-Package: net.java.sip.communicator.service.replacement, - net.java.sip.communicator.service.replacement.smilies \ No newline at end of file + net.java.sip.communicator.service.replacement.smilies diff --git a/src/net/java/sip/communicator/service/replacement/smilies/Smiley.java b/src/net/java/sip/communicator/service/replacement/smilies/Smiley.java index 5354f5b0c..8aad5b5fd 100644 --- a/src/net/java/sip/communicator/service/replacement/smilies/Smiley.java +++ b/src/net/java/sip/communicator/service/replacement/smilies/Smiley.java @@ -46,4 +46,4 @@ public interface Smiley * @return the path of the image corresponding to this smiley. */ public String getImagePath(); -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/service/resources/ResourceManagementService.java b/src/net/java/sip/communicator/service/resources/ResourceManagementService.java deleted file mode 100644 index a3842df8b..000000000 --- a/src/net/java/sip/communicator/service/resources/ResourceManagementService.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.resources; - -import java.io.*; -import java.net.*; -import java.util.*; - -import javax.swing.*; - -/** - * The Resource Management Service gives easy access to - * common resources for the application including texts, images, sounds and - * some configurations. - * - * @author Damian Minkov - * @author Adam Netocny - */ -public interface ResourceManagementService -{ - // Color pack methods - /** - * Returns the int representation of the color corresponding to the - * given key. - * - * @param key The key of the color in the colors properties file. - * @return the int representation of the color corresponding to the - * given key. - */ - public int getColor(String key); - - /** - * Returns the string representation of the color corresponding to the - * given key. - * - * @param key The key of the color in the colors properties file. - * @return the string representation of the color corresponding to the - * given key. - */ - public String getColorString(String key); - - /** - * Returns the InputStream of the image corresponding to the given - * path. - * - * @param path The path to the image file. - * @return the InputStream of the image corresponding to the given - * path. - */ - public InputStream getImageInputStreamForPath(String path); - - /** - * Returns the InputStream of the image corresponding to the given - * key. - * - * @param streamKey The identifier of the image in the resource properties - * file. - * @return the InputStream of the image corresponding to the given - * key. - */ - public InputStream getImageInputStream(String streamKey); - - /** - * Returns the URL of the image corresponding to the given key. - * - * @param urlKey The identifier of the image in the resource properties file. - * @return the URL of the image corresponding to the given key - */ - public URL getImageURL(String urlKey); - - /** - * Returns the URL of the image corresponding to the given path. - * - * @param path The path to the given image file. - * @return the URL of the image corresponding to the given path. - */ - public URL getImageURLForPath(String path); - - /** - * Returns the image path corresponding to the given key. - * - * @param key The identifier of the image in the resource properties file. - * @return the image path corresponding to the given key. - */ - public String getImagePath(String key); - - // Language pack methods - /** - * Default Locale config string. - */ - public final static String DEFAULT_LOCALE_CONFIG = - "net.java.sip.communicator.service.resources.DefaultLocale"; - - /** - * All the locales in the language pack. - * @return all the locales this Language pack contains. - */ - public Iterator getAvailableLocales(); - - /** - * Returns an internationalized string corresponding to the given key. - * - * @param key The identifier of the string in the resources properties file. - * @return An internationalized string corresponding to the given key. - */ - public String getI18NString(String key); - - /** - * Returns an internationalized string corresponding to the given key. - * - * @param key The identifier of the string in the resources properties file. - * @param locale The locale. - * @return An internationalized string corresponding to the given key and - * given locale. - */ - public String getI18NString(String key, Locale locale); - - /** - * Returns an internationalized string corresponding to the given key. - * - * @param key The identifier of the string in the resources properties file. - * @param params An array of parameters to be replaced in the returned - * string. - * @return An internationalized string corresponding to the given key and - * given locale. - */ - public String getI18NString(String key, String[] params); - - /** - * Returns an internationalized string corresponding to the given key. - * - * @param key The identifier of the string in the resources properties file. - * @param params An array of parameters to be replaced in the returned - * string. - * @param locale The locale. - * @return An internationalized string corresponding to the given key. - */ - public String getI18NString(String key, String[] params, Locale locale); - - /** - * Returns an internationalized string corresponding to the given key. - * - * @param key The identifier of the string in the resources properties file. - * @return An internationalized string corresponding to the given key. - */ - public char getI18nMnemonic(String key); - - /** - * Returns an internationalized string corresponding to the given key. - * - * @param key The key of the string. - * @param l The locale. - * @return An internationalized string corresponding to the given key. - */ - public char getI18nMnemonic(String key, Locale l); - - // Settings pack methods - /** - * Returns an url for the setting corresponding to the given key. - * Used when the setting is an actual file. - * - * @param urlKey The key of the setting. - * @return Url to the corresponding resource. - */ - public URL getSettingsURL(String urlKey); - - /** - * Returns an InputStream for the setting corresponding to the given key. - * Used when the setting is an actual file. - * - * @param streamKey The key of the setting. - * @return InputStream to the corresponding resource. - */ - public InputStream getSettingsInputStream(String streamKey); - - /** - * Returns a stream from a given identifier, obtained through the class - * loader of the given resourceClass. - * - * @param streamKey The identifier of the stream. - * @param resourceClass the resource class through which the resource would - * be obtained - * @return The stream for the given identifier. - */ - public InputStream getSettingsInputStream( String streamKey, - Class resourceClass); - - /** - * Returns the int value of the corresponding configuration key. - * - * @param key The identifier of the string in the resources properties file. - * @return the int value of the corresponding configuration key. - */ - public String getSettingsString(String key); - - /** - * Returns the int value of the corresponding configuration key. - * - * @param key The identifier of the string in the resources properties file. - * @return the int value of the corresponding configuration key. - */ - public int getSettingsInt(String key); - - // Sound pack methods - /** - * Returns an url for the sound resource corresponding to the given key. - * - * @param urlKey The key of the setting. - * @return Url to the corresponding resource. - */ - public URL getSoundURL(String urlKey); - - /** - * Returns an url for the sound resource corresponding to the given path. - * - * @param path The path to the sound resource. - * @return Url to the corresponding resource. - */ - public URL getSoundURLForPath(String path); - - /** - * Returns the path of the sound corresponding to the given - * property key. - * - * @param soundKey The key of the sound. - * @return the path of the sound corresponding to the given - * property key. - */ - public String getSoundPath(String soundKey); - - /** - * Constructs an ImageIcon from the specified image ID and returns - * it. - * - * @param imageID The identifier of the image. - * @return An ImageIcon containing the image with the given - * identifier. - */ - public ImageIcon getImage(String imageID); - - /** - * Loads the image with the specified ID and returns a byte array - * containing it. - * - * @param imageID The identifier of the image. - * @return A byte array containing the image with the given identifier. - */ - public byte[] getImageInBytes(String imageID); - - /** - * Builds a new skin bundle from the zip file content. - * @param zipFile Zip file with skin information. - * @return File for the bundle. - * @throws Exception When something goes wrong. - */ - public File prepareSkinBundleFromZip(File zipFile) throws Exception; -} diff --git a/src/net/java/sip/communicator/service/resources/ResourceManagementServiceUtils.java b/src/net/java/sip/communicator/service/resources/ResourceManagementServiceUtils.java index 695ddf30f..04aa05676 100644 --- a/src/net/java/sip/communicator/service/resources/ResourceManagementServiceUtils.java +++ b/src/net/java/sip/communicator/service/resources/ResourceManagementServiceUtils.java @@ -10,6 +10,7 @@ import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/service/version/Version.java b/src/net/java/sip/communicator/service/version/Version.java deleted file mode 100644 index be58c57d5..000000000 --- a/src/net/java/sip/communicator/service/version/Version.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.version; - -/** - * Contains version information of the SIP Communicator instance that we're - * currently running. - * - * @author Emil Ivov - * @author Lyubomir Marinov - */ -public interface Version - extends Comparable -{ - /** - * The name of the System property the value of which is equal to - * the value of {@link #getApplicationName()}. Expected to be set by - * implementers of the VersionService and Version - * interfaces. - */ - public static final String PNAME_APPLICATION_NAME - = "sip-communicator.application.name"; - - /** - * The name of the System property the value of which is equal to - * the value of {@link #toString()}. Expected to be set by - * implementers of the VersionService and Version - * interfaces. - */ - public static final String PNAME_APPLICATION_VERSION - = "sip-communicator.version"; - - /** - * Returns the version major of the current SIP Communicator version. In an - * example 2.3.1 version string 2 is the version major. The version major - * number changes when a relatively extensive set of new features and - * possibly rearchitecturing have been applied to the SIP Communicator. - * - * @return the version major integer. - */ - public int getVersionMajor(); - - /** - * Returns the version minor of the current SIP Communicator version. In an - * example 2.3.1 version string 3 is the version minor. The version minor - * number changes after adding enhancements and possibly new features to a - * given SIP Communicator version. - * - * @return the version minor integer. - */ - public int getVersionMinor(); - - /** - * Returns the version revision number of the current SIP Communicator - * version. In an example 2.3.1 version string 1 is the revision number. - * The version revision number number changes after applying bug fixes and - * possible some small enhancements to a given SIP Communicator version. - * - * @return the version revision number. - */ - public int getVersionRevision(); - - /** - * Indicates if this SIP Communicator version corresponds to a nightly build - * of a repository snapshot or to an official SIP Communicator release. - * - * @return true if this is a build of a nightly repository snapshot and - * false if this is an official SIP Communicator release. - */ - public boolean isNightly(); - - /** - * If this is a nightly build, returns the build identifies (e.g. - * nightly-2007.12.07-06.45.17). If this is not a nightly build SIP - * Communicator version, the method returns null. - * - * @return a String containing a nightly build identifier or null if - */ - public String getNightlyBuildID(); - - /** - * Indicates whether this version represents a prerelease (i.e. a - * non-complete release like an alpha, beta or release candidate version). - * @return true if this version represents a prerelease and false otherwise. - */ - public boolean isPreRelease(); - - /** - * Returns the version prerelease ID of the current SIP Communicator version - * and null if this version is not a prerelease. Version pre-release id-s - * and version revisions are exclusive, so in case this version is a pre- - * release the revision will bereturn null - * - * @return a String containing the version prerelease ID. - */ - public String getPreReleaseID(); - - /** - * Compares another Version object to this one and returns a - * negative, zero or a positive integer if this version instance represents - * respectively an earlier, same, or later version as the one indicated - * by the version parameter. - * - * @param version the Version instance that we'd like to compare - * to this one. - * - * @return a negative integer, zero, or a positive integer as this object - * represents a version that is earlier, same, or more recent than the one - * referenced by the version parameter. - */ - public int compareTo(Version version); - - /** - * Compares the version parameter to this version and returns true - * if and only if both reference the same SIP Communicator version and - * false otherwise. - * - * @param version the version instance that we'd like to compare with this - * one. - * @return true if and only the version param references the same - * SIP Communicator version as this Version instance and false otherwise. - */ - public boolean equals(Object version); - - /** - * Returns the name of the application that we're currently running. Default - * MUST be SIP Communicator. - * - * @return the name of the application that we're currently running. Default - * MUST be SIP Communicator. - */ - public String getApplicationName(); - - /** - * Returns a String representation of this Version instance. If you'd just - * like to obtain the version of SIP Communicator so that you could display - * it (e.g. in a Help->About dialog) then all you need is calling this - * method. - * - * @return a major.minor.revision[.build] String containing the complete - * SIP Communicator version. - */ - public String toString(); -} diff --git a/src/net/java/sip/communicator/service/version/VersionService.java b/src/net/java/sip/communicator/service/version/VersionService.java deleted file mode 100644 index da53cae5c..000000000 --- a/src/net/java/sip/communicator/service/version/VersionService.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.version; - -/** - * The version service keeps track of the SIP Communicator version that we are - * currently running. Other modules (such as a Help->About dialog) query and - * use this service in order to show the current application version. - * - * @author Emil Ivov - */ -public interface VersionService -{ - /** - * Returns a Version object containing version details of the SIP - * Communicator version that we're currently running. - * - * @return a Version object containing version details of the SIP - * Communicator version that we're currently running. - */ - public Version getCurrentVersion(); - - /** - * Returns a Version instance corresponding to the version string. - * - * @param version a version String that we have obtained by calling a - * Version.toString() method. - * - * @return the Version object corresponding to the version - * string. - */ - public Version parseVersionString(String version); -} diff --git a/src/net/java/sip/communicator/service/version/version.manifest.mf b/src/net/java/sip/communicator/service/version/version.manifest.mf deleted file mode 100755 index 6183ebf3f..000000000 --- a/src/net/java/sip/communicator/service/version/version.manifest.mf +++ /dev/null @@ -1,6 +0,0 @@ -Bundle-Name: Version Service Implementation -Bundle-Description: Version Service Implementation. -Bundle-Vendor: jitsi.org -Bundle-Version: 0.0.1 -System-Bundle: yes -Export-Package: net.java.sip.communicator.service.version diff --git a/src/net/java/sip/communicator/util/FileHandler.java b/src/net/java/sip/communicator/util/FileHandler.java index 2f6e3a576..49b2ecb21 100644 --- a/src/net/java/sip/communicator/util/FileHandler.java +++ b/src/net/java/sip/communicator/util/FileHandler.java @@ -4,7 +4,6 @@ * Distributable under LGPL license. * See terms of license at gnu.org. */ - package net.java.sip.communicator.util; import java.io.*; diff --git a/src/net/java/sip/communicator/util/OSUtils.java b/src/net/java/sip/communicator/util/OSUtils.java deleted file mode 100644 index f79efa384..000000000 --- a/src/net/java/sip/communicator/util/OSUtils.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.util; - -/** - * Utility fields for OS detection. - * - * @author Sebastien Vincent - * @author Lubomir Marinov - */ -public class OSUtils -{ - - /** true if architecture is 32 bit. */ - public static final boolean IS_32_BIT; - - /** true if architecture is 64 bit. */ - public static final boolean IS_64_BIT; - - /** true if OS is Android */ - public static final boolean IS_ANDROID; - - /** true if OS is Linux. */ - public static final boolean IS_LINUX; - - /** true if OS is Linux 32-bit. */ - public static final boolean IS_LINUX32; - - /** true if OS is Linux 64-bit. */ - public static final boolean IS_LINUX64; - - /** true if OS is MacOSX. */ - public static final boolean IS_MAC; - - /** true if OS is MacOSX 32-bit. */ - public static final boolean IS_MAC32; - - /** true if OS is MacOSX 64-bit. */ - public static final boolean IS_MAC64; - - /** true if OS is Windows. */ - public static final boolean IS_WINDOWS; - - /** true if OS is Windows 32-bit. */ - public static final boolean IS_WINDOWS32; - - /** true if OS is Windows 64-bit. */ - public static final boolean IS_WINDOWS64; - - /** true if OS is Windows Vista. */ - public static final boolean IS_WINDOWS_VISTA; - - /** true if OS is Windows 7. */ - public static final boolean IS_WINDOWS_7; - - /** true if OS is FreeBSD. */ - public static final boolean IS_FREEBSD; - - static - { - // OS - String osName = System.getProperty("os.name"); - - if (osName == null) - { - IS_ANDROID = false; - IS_LINUX = false; - IS_MAC = false; - IS_WINDOWS = false; - IS_WINDOWS_VISTA = false; - IS_WINDOWS_7 = false; - IS_FREEBSD = false; - } - else if (osName.startsWith("Linux")) - { - String javaVmName = System.getProperty("java.vm.name"); - - if ((javaVmName != null) && javaVmName.equalsIgnoreCase("Dalvik")) - { - IS_ANDROID = true; - IS_LINUX = false; - } - else - { - IS_ANDROID = false; - IS_LINUX = true; - } - IS_MAC = false; - IS_WINDOWS = false; - IS_WINDOWS_VISTA = false; - IS_WINDOWS_7 = false; - IS_FREEBSD = false; - } - else if (osName.startsWith("Mac")) - { - IS_ANDROID = false; - IS_LINUX = false; - IS_MAC = true; - IS_WINDOWS = false; - IS_WINDOWS_VISTA = false; - IS_WINDOWS_7 = false; - IS_FREEBSD = false; - } - else if (osName.startsWith("Windows")) - { - IS_ANDROID = false; - IS_LINUX = false; - IS_MAC = false; - IS_WINDOWS = true; - IS_WINDOWS_VISTA = (osName.indexOf("Vista") != -1); - IS_WINDOWS_7 = (osName.indexOf("7") != -1); - IS_FREEBSD = false; - } - else if (osName.startsWith("FreeBSD")) - { - IS_ANDROID = false; - IS_LINUX = false; - IS_MAC = false; - IS_WINDOWS = false; - IS_WINDOWS_VISTA = false; - IS_WINDOWS_7 = false; - IS_FREEBSD = true; - } - else - { - IS_ANDROID = false; - IS_LINUX = false; - IS_MAC = false; - IS_WINDOWS = false; - IS_WINDOWS_VISTA = false; - IS_WINDOWS_7 = false; - IS_FREEBSD = false; - } - - // arch i.e. x86, amd64 - String osArch = System.getProperty("sun.arch.data.model"); - - if(osArch == null) - { - IS_32_BIT = true; - IS_64_BIT = false; - } - else if (osArch.indexOf("32") != -1) - { - IS_32_BIT = true; - IS_64_BIT = false; - } - else if (osArch.indexOf("64") != -1) - { - IS_32_BIT = false; - IS_64_BIT = true; - } - else - { - IS_32_BIT = false; - IS_64_BIT = false; - } - - // OS && arch - IS_LINUX32 = IS_LINUX && IS_32_BIT; - IS_LINUX64 = IS_LINUX && IS_64_BIT; - IS_MAC32 = IS_MAC && IS_32_BIT; - IS_MAC64 = IS_MAC && IS_64_BIT; - IS_WINDOWS32 = IS_WINDOWS && IS_32_BIT; - IS_WINDOWS64 = IS_WINDOWS && IS_64_BIT; - } -} diff --git a/src/net/java/sip/communicator/util/OrderedProperties.java b/src/net/java/sip/communicator/util/OrderedProperties.java index 369fcda2e..a0010a92e 100644 --- a/src/net/java/sip/communicator/util/OrderedProperties.java +++ b/src/net/java/sip/communicator/util/OrderedProperties.java @@ -114,4 +114,4 @@ public int size() { return linkedMap.size(); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/util/SoundFileUtils.java b/src/net/java/sip/communicator/util/SoundFileUtils.java deleted file mode 100644 index 136085ec7..000000000 --- a/src/net/java/sip/communicator/util/SoundFileUtils.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.util; - -import java.io.*; -import java.util.*; - -/** - * Defines the different permit extension file. - * - * @author Alexandre Maillard - * @author Dmitri Melnikov - * @author Vincent Lucas - */ -public class SoundFileUtils -{ - /** - * Different extension of a sound file - */ - public final static String wav = "wav"; - public final static String mid = "midi"; - public final static String mp2 = "mp2"; - public final static String mp3 = "mp3"; - public final static String mod = "mod"; - public final static String ram = "ram"; - public final static String wma = "wma"; - public final static String ogg = "ogg"; - public final static String gsm = "gsm"; - public final static String aif = "aiff"; - public final static String au = "au"; - - /** - * The file extension and the format of call recording to be used by - * default. - */ - public static final String DEFAULT_CALL_RECORDING_FORMAT = mp3; - - /** - * Checks whether this file is a sound file. - * - * @param f File to check - * @return true if it's a sound file, false otherwise - */ - public static boolean isSoundFile(File f) - { - String ext = getExtension(f); - - if (ext != null) - { - return - ext.equals(wma) - || ext.equals(wav) - || ext.equals(ram) - || ext.equals(ogg) - || ext.equals(mp3) - || ext.equals(mp2) - || ext.equals(mod) - || ext.equals(mid) - || ext.equals(gsm) - || ext.equals(au); - } - return false; - } - - /** - * Checks whether this file is a sound file. - * - * @param f File to check - * @param soundFormats The sound formats to restrict the file name - * extension. If soundFormats is null, then every sound format defined by - * SoundFileUtils is correct. - * - * @return true if it's a sound file conforming to the format given - * in parameters (if soundFormats is null, then every sound format defined - * by SoundFileUtils is correct), false otherwise. - */ - public static boolean isSoundFile(File f, String[] soundFormats) - { - // If there is no specific filters, then compare the file to all sound - // extension available. - if(soundFormats == null) - { - return SoundFileUtils.isSoundFile(f); - } - // Compare the file extension to the sound formats provided in - // parameter. - else - { - String ext = getExtension(f); - - // If the file has an extension - if (ext != null) - { - return (Arrays.binarySearch( - soundFormats, - ext, - String.CASE_INSENSITIVE_ORDER) != -1); - } - } - return false; - } - - /** - * Gets the file extension. - * TODO: There are at least 2 other methods like this scattered around - * the SC code, we should move them all to util package. - * - * @param f which wants the extension - * @return Return the extension as a String - */ - public static String getExtension(File f) - { - String s = f.getName(); - int i = s.lastIndexOf('.'); - String ext = null; - - if ((i > 0) && (i < s.length() - 1)) - ext = s.substring(i+1).toLowerCase(); - return ext; - } -} diff --git a/src/net/java/sip/communicator/util/UtilActivator.java b/src/net/java/sip/communicator/util/UtilActivator.java index 27bb1768c..852f2f8f3 100644 --- a/src/net/java/sip/communicator/util/UtilActivator.java +++ b/src/net/java/sip/communicator/util/UtilActivator.java @@ -11,11 +11,12 @@ import javax.imageio.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.keybindings.*; import net.java.sip.communicator.service.netaddr.*; import net.java.sip.communicator.service.resources.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; /** diff --git a/src/net/java/sip/communicator/util/dns/ConfigurableDnssecResolver.java b/src/net/java/sip/communicator/util/dns/ConfigurableDnssecResolver.java index 77aa37860..6733d6192 100644 --- a/src/net/java/sip/communicator/util/dns/ConfigurableDnssecResolver.java +++ b/src/net/java/sip/communicator/util/dns/ConfigurableDnssecResolver.java @@ -12,12 +12,12 @@ import javax.swing.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.notification.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; +import org.jitsi.service.resources.*; import org.xbill.DNS.*; /** diff --git a/src/net/java/sip/communicator/util/dns/DnsUtilActivator.java b/src/net/java/sip/communicator/util/dns/DnsUtilActivator.java index 49983531b..853adfc6a 100644 --- a/src/net/java/sip/communicator/util/dns/DnsUtilActivator.java +++ b/src/net/java/sip/communicator/util/dns/DnsUtilActivator.java @@ -6,11 +6,12 @@ */ package net.java.sip.communicator.util.dns; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.notification.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; import org.osgi.framework.*; import org.xbill.DNS.*; diff --git a/src/net/java/sip/communicator/util/dns/util.dns.manifest.mf b/src/net/java/sip/communicator/util/dns/util.dns.manifest.mf index dbbdaec4d..5c6b82142 100644 --- a/src/net/java/sip/communicator/util/dns/util.dns.manifest.mf +++ b/src/net/java/sip/communicator/util/dns/util.dns.manifest.mf @@ -9,8 +9,8 @@ Import-Package: org.osgi.framework, net.java.sip.communicator.util, net.java.sip.communicator.util.swing, - net.java.sip.communicator.service.resources, - net.java.sip.communicator.service.configuration, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, + org.jitsi.service.configuration, net.java.sip.communicator.service.notification, sun.net.dns, org.xbill.DNS, diff --git a/src/net/java/sip/communicator/util/event/PropertyChangeNotifier.java b/src/net/java/sip/communicator/util/event/PropertyChangeNotifier.java deleted file mode 100644 index a5f683f24..000000000 --- a/src/net/java/sip/communicator/util/event/PropertyChangeNotifier.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.util.event; - -import java.util.*; -import java.beans.*; - -/** - * Represents a source of PropertyChangeEvents which notifies - * PropertyChangeListeners about changes in the values of properties. - * - * @author Lyubomir Marinov - */ -public class PropertyChangeNotifier -{ - - /** - * The list of PropertyChangeListeners interested in and notified - * about changes in the values of the properties of this - * PropertyChangeNotifier. - */ - private final List listeners - = new Vector(); - - /** - * Adds a specific PropertyChangeListener to the list of listeners - * interested in and notified about changes in the values of the properties - * of this PropertyChangeNotifier. - * - * @param listener a PropertyChangeListener to be notified about - * changes in the values of the properties of this - * PropertyChangeNotifier. If the specified listener is already in - * the list of interested listeners (i.e. it has been previously added), it - * is not added again. - */ - public void addPropertyChangeListener(PropertyChangeListener listener) - { - if (listener != null) - synchronized (listeners) - { - if (!listeners.contains(listener)) - listeners.add(listener); - } - } - - /** - * Removes a specific PropertyChangeListener from the list of - * listeners interested in and notified about changes in the values of the - * properties of this PropertyChangeNotifer. - * - * @param listener a PropertyChangeListener to no longer be - * notified about changes in the values of the properties of this - * PropertyChangeNotifier - */ - public void removePropertyChangeListener(PropertyChangeListener listener) - { - if (listener != null) - synchronized (listeners) - { - listeners.remove(listener); - } - } - - /** - * Fires a new PropertyChangeEvent to the - * PropertyChangeListeners registered with this - * PropertyChangeNotifier in order to notify about a change in the - * value of a specific property which had its old value modified to a - * specific new value. - * - * @param property the name of the property of this - * PropertyChangeNotifier which had its value changed - * @param oldValue the value of the property with the specified name before - * the change - * @param newValue the value of the property with the specified name after - * the change - */ - protected void firePropertyChange( - String property, - Object oldValue, - Object newValue) - { - PropertyChangeListener[] listeners; - synchronized (this.listeners) - { - listeners - = this.listeners - .toArray( - new PropertyChangeListener[this.listeners.size()]); - } - - PropertyChangeEvent event - = new PropertyChangeEvent( - getPropertyChangeSource(property, oldValue, newValue), - property, - oldValue, - newValue); - - for (PropertyChangeListener listener : listeners) - listener.propertyChange(event); - } - - /** - * Gets the Object to be reported as the source of a new - * PropertyChangeEvent which is to notify the - * PropertyChangeListeners registered with this - * PropertyChangeNotifier about the change in the value of a - * property with a specific name from a specific old value to a specific new - * value. - * - * @param property the name of the property which had its value changed from - * the specified old value to the specified new value - * @param oldValue the value of the property with the specified name before - * the change - * @param newValue the value of the property with the specified name after - * the change - * @return the Object to be reported as the source of the new - * PropertyChangeEvent which is to notify the - * PropertyChangeListeners registered with this - * PropertyChangeNotifier about the change in the value of the - * property with the specified name from the specified old value to the - * specified new value - */ - protected Object getPropertyChangeSource( - String property, - Object oldValue, - Object newValue) - { - return this; - } -} diff --git a/src/net/java/sip/communicator/util/event/SizeChangeVideoEvent.java b/src/net/java/sip/communicator/util/event/SizeChangeVideoEvent.java deleted file mode 100644 index e4982bb28..000000000 --- a/src/net/java/sip/communicator/util/event/SizeChangeVideoEvent.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.util.event; - -import java.awt.*; - -/** - * Represents a VideoEvent which notifies about an update to the size - * of a specific visual Component depicting video. - * - * @author Lyubomir Marinov - */ -public class SizeChangeVideoEvent - extends VideoEvent -{ - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * The type of a VideoEvent which notifies about an update to the - * size of a specific visual Component depicting video. - */ - public static final int VIDEO_SIZE_CHANGE = 3; - - /** - * The new height of the associated visual Component. - */ - private final int height; - - /** - * The new width of the associated visual Component. - */ - private final int width; - - /** - * Initializes a new SizeChangeVideoEvent which is to notify about - * an update to the size of a specific visual Component depicting - * video. - * - * @param source the source of the new SizeChangeVideoEvent - * @param visualComponent the visual Component depicting video - * with the updated size - * @param origin the origin of the video the new - * SizeChangeVideoEvent is to notify about - * @param width the new width of visualComponent - * @param height the new height of visualComponent - */ - public SizeChangeVideoEvent( - Object source, - Component visualComponent, - int origin, - int width, - int height) - { - super(source, VIDEO_SIZE_CHANGE, visualComponent, origin); - - this.width = width; - this.height = height; - } - - @Override - public VideoEvent clone(Object source) - { - return - new SizeChangeVideoEvent( - source, - getVisualComponent(), getOrigin(), - getWidth(), getHeight()); - } - - /** - * Gets the new height of the associated visual Component. - * - * @return the new height of the associated visual Component - */ - public int getHeight() - { - return height; - } - - /** - * Gets the new width of the associated visual Component. - * - * @return the new width of the associated visual Component - */ - public int getWidth() - { - return width; - } -} diff --git a/src/net/java/sip/communicator/util/event/VideoEvent.java b/src/net/java/sip/communicator/util/event/VideoEvent.java deleted file mode 100644 index 695e0048f..000000000 --- a/src/net/java/sip/communicator/util/event/VideoEvent.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.util.event; - -import java.awt.*; -import java.util.*; - -/** - * Represents an event fired by providers of visual Components - * depicting video to notify about changes in the availability of such - * Components. - * - * @author Lyubomir Marinov - */ -public class VideoEvent - extends EventObject -{ - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * The video origin of a VideoEvent which is local to the executing - * client such as a local video capture device. - */ - public static final int LOCAL = 1; - - /** - * The video origin of a VideoEvent which is remote to the - * executing client such as a video being remotely streamed from a - * CallPeer. - */ - public static final int REMOTE = 2; - - /** - * The type of a VideoEvent which notifies about a specific visual - * Component depicting video being made available by the firing - * provider. - */ - public static final int VIDEO_ADDED = 1; - - /** - * The type of a VideoEvent which notifies about a specific visual - * Component depicting video no longer being made available by the - * firing provider. - */ - public static final int VIDEO_REMOVED = 2; - - /** - * The indicator which determines whether this event and, more specifically, - * the visual Component it describes have been consumed and should - * be considered owned, referenced (which is important because - * Components belong to a single Container at a time). - */ - private boolean consumed; - - /** - * The origin of the video this VideoEvent notifies about which is - * one of {@link #LOCAL} and {@link #REMOTE}. - */ - private final int origin; - - /** - * The type of availability change this VideoEvent notifies about - * which is one of {@link #VIDEO_ADDED} and {@link #VIDEO_REMOVED}. - */ - private final int type; - - /** - * The visual Component depicting video which had its availability - * changed and which this VideoEvent notifies about. - */ - private final Component visualComponent; - - /** - * Initializes a new VideoEvent which is to notify about a specific - * change in the availability of a specific visual Component - * depicting video and being provided by a specific source. - * - * @param source the source of the new VideoEvent and the provider - * of the visual Component depicting video - * @param type the type of the availability change which has caused the new - * VideoEvent to be fired - * @param visualComponent the visual Component depicting video - * which had its availability in the source provider changed - * @param origin the origin of the video the new VideoEvent is to - * notify about - */ - public VideoEvent( - Object source, - int type, - Component visualComponent, - int origin) - { - super(source); - - this.type = type; - this.visualComponent = visualComponent; - this.origin = origin; - } - - public VideoEvent clone(Object source) - { - return - new VideoEvent( - source, - getType(), getVisualComponent(), getOrigin()); - } - - /** - * Consumes this event and, more specifically, marks the Component - * it describes as owned, referenced in order to let other potential - * consumers know about its current ownership status (which is important - * because Components belong to a single Container at a - * time). - */ - public void consume() - { - consumed = true; - } - - /** - * Gets the origin of the video this VideoEvent notifies about - * which is one of {@link #LOCAL} and {@link #REMOTE}. - * - * @return one of {@link #LOCAL} and {@link #REMOTE} which specifies the - * origin of the video this VideoEvent notifies about - */ - public int getOrigin() - { - return origin; - } - - /** - * Gets the type of availability change this VideoEvent notifies - * about which is one of {@link #VIDEO_ADDED} and {@link #VIDEO_REMOVED}. - * - * @return one of {@link #VIDEO_ADDED} and {@link #VIDEO_REMOVED} which - * describes the type of availability change this VideoEvent - * notifies about - */ - public int getType() - { - return type; - } - - /** - * Gets the visual Component depicting video which had its - * availability changed and which this VideoEvent notifies about. - * - * @return the visual Component depicting video which had its - * availability changed and which this VideoEvent notifies about - */ - public Component getVisualComponent() - { - return visualComponent; - } - - /** - * Determines whether this event and, more specifically, the visual - * Component it describes have been consumed and should be - * considered owned, referenced (which is important because - * Components belong to a single Container at a time). - * - * @return true if this event and, more specifically, the visual - * Component it describes have been consumed and should be - * considered owned, referenced (which is important because - * Components belong to a single Container at a time); - * otherwise, false - */ - public boolean isConsumed() - { - return consumed; - } - - /** - * Returns a human-readable representation of a specific VideoEvent - * origin constant in the form of a String value. - * - * @param origin one of the VideoEvent origin constants such as - * {@link #LOCAL} or {@link #REMOTE} - * @return a String value which gives a human-readable - * representation of the specified VideoEvent origin - * constant - */ - public static String originToString(int origin) - { - switch (origin) - { - case VideoEvent.LOCAL: - return "LOCAL"; - case VideoEvent.REMOTE: - return "REMOTE"; - default: - throw new IllegalArgumentException("origin"); - } - } - - /** - * Returns a human-readable representation of a specific VideoEvent - * type constant in the form of a String value. - * - * @param type one of the VideoEvent type constants such as - * {@link #VIDEO_ADDED} or {@link #VIDEO_REMOVED} - * @return a String value which gives a human-readable - * representation of the specified VideoEvent type - * constant - */ - public static String typeToString(int type) - { - switch (type) - { - case VideoEvent.VIDEO_ADDED: - return "VIDEO_ADDED"; - case VideoEvent.VIDEO_REMOVED: - return "VIDEO_REMOVED"; - default: - throw new IllegalArgumentException("type"); - } - } -} diff --git a/src/net/java/sip/communicator/util/event/VideoListener.java b/src/net/java/sip/communicator/util/event/VideoListener.java deleted file mode 100644 index 25266a7a2..000000000 --- a/src/net/java/sip/communicator/util/event/VideoListener.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.util.event; - -import java.util.*; - -/** - * Defines the notification support informing about changes in the availability - * of visual Components representing video such as adding and - * removing. - * - * @author Lyubomir Marinov - */ -public interface VideoListener - extends EventListener -{ - - /** - * Notifies that a visual Component representing video has been - * added to the provider this listener has been added to. - * - * @param event a VideoEvent describing the added visual - * Component representing video and the provider it was added into - */ - void videoAdded(VideoEvent event); - - /** - * Notifies that a visual Component representing video has been - * removed from the provider this listener has been added to. - * - * @param event a VideoEvent describing the removed visual - * Component representing video and the provider it was removed - * from - */ - void videoRemoved(VideoEvent event); - - /** - * Notifies about an update to a visual Component representing - * video. - * - * @param event a VideoEvent describing the visual - * Component related to the update and the details of the specific - * update - */ - void videoUpdate(VideoEvent event); -} diff --git a/src/net/java/sip/communicator/util/event/VideoNotifierSupport.java b/src/net/java/sip/communicator/util/event/VideoNotifierSupport.java deleted file mode 100644 index af30eafc9..000000000 --- a/src/net/java/sip/communicator/util/event/VideoNotifierSupport.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.util.event; - -import java.awt.*; -import java.util.*; -import java.util.List; // disambiguation - -/** - * Represents a mechanism to easily add to a specific Object by means - * of composition support for firing VideoEvents to - * VideoListeners. - * - * @author Lyubomir Marinov - */ -public class VideoNotifierSupport -{ - private static final long THREAD_TIMEOUT = 5000; - - /** - * The list of VideoEvents which are to be delivered to the - * {@link #listeners} registered with this instance when - * {@link #synchronous} is equal to false. - */ - private final List events; - - /** - * The list of VideoListeners interested in changes in the - * availability of visual Components depicting video. - */ - private final List listeners - = new ArrayList(); - - /** - * The Object which is to be reported as the source of the - * VideoEvents fired by this instance. - */ - private final Object source; - - /** - * The indicator which determines whether this instance delivers the - * VideoEvents to the {@link #listeners} synchronously. - */ - private final boolean synchronous; - - /** - * The Thread in which {@link #events} are delivered to the - * {@link #listeners} when {@link #synchronous} is equal to false. - */ - private Thread thread; - - /** - * Initializes a new VideoNotifierSupport instance which is to - * facilitate the management of VideoListeners and firing - * VideoEvents to them for a specific Object. - * - * @param source the Object which is to be reported as the source - * of the VideoEvents fired by the new instance - */ - public VideoNotifierSupport(Object source) - { - this(source, true); - } - - /** - * Initializes a new VideoNotifierSupport instance which is to - * facilitate the management of VideoListeners and firing - * VideoEvents to them for a specific Object. - * - * @param source the Object which is to be reported as the source - * of the VideoEvents fired by the new instance - * @param synchronous true if the new instance is to deliver the - * VideoEvents synchronously; otherwise, false - */ - public VideoNotifierSupport(Object source, boolean synchronous) - { - this.source = source; - this.synchronous = synchronous; - - events = this.synchronous ? null : new LinkedList(); - } - - /** - * Adds a specific VideoListener to this - * VideoNotifierSupport in order to receive notifications when - * visual/video Components are being added and removed. - *

- * Adding a listener which has already been added does nothing i.e. it is - * not added more than once and thus does not receive one and the same - * VideoEvent multiple times. - *

- * - * @param listener the VideoListener to be notified when - * visual/video Components are being added or removed in this - * VideoNotifierSupport - */ - public void addVideoListener(VideoListener listener) - { - if (listener == null) - throw new NullPointerException("listener"); - - synchronized (listeners) - { - if (!listeners.contains(listener)) - listeners.add(listener); - } - } - - protected void doFireVideoEvent(VideoEvent event) - { - VideoListener[] listeners; - - synchronized (this.listeners) - { - listeners - = this.listeners.toArray( - new VideoListener[this.listeners.size()]); - } - - for (VideoListener listener : listeners) - switch (event.getType()) - { - case VideoEvent.VIDEO_ADDED: - listener.videoAdded(event); - break; - case VideoEvent.VIDEO_REMOVED: - listener.videoRemoved(event); - break; - default: - listener.videoUpdate(event); - break; - } - } - - /** - * Notifies the VideoListeners registered with this - * VideoMediaStream about a specific type of change in the - * availability of a specific visual Component depicting video. - * - * @param type the type of change as defined by VideoEvent in the - * availability of the specified visual Component depicting video - * @param visualComponent the visual Component depicting video - * which has been added or removed - * @param origin {@link VideoEvent#LOCAL} if the origin of the video is - * local (e.g. it is being locally captured); {@link VideoEvent#REMOTE} if - * the origin of the video is remote (e.g. a remote peer is streaming it) - * @param wait true if the call is to wait till the specified - * VideoEvent has been delivered to the VideoListeners; - * otherwise, false - * @return true if this event and, more specifically, the visual - * Component it describes have been consumed and should be - * considered owned, referenced (which is important because - * Components belong to a single Container at a time); - * otherwise, false - */ - public boolean fireVideoEvent( - int type, Component visualComponent, int origin, - boolean wait) - { - VideoEvent event - = new VideoEvent(source, type, visualComponent, origin); - - fireVideoEvent(event, wait); - return event.isConsumed(); - } - - /** - * Notifies the VideoListeners registered with this instance about - * a specific VideoEvent. - * - * @param event the VideoEvent to be fired to the - * VideoListeners registered with this instance - * @param wait true if the call is to wait till the specified - * VideoEvent has been delivered to the VideoListeners; - * otherwise, false - */ - public void fireVideoEvent(VideoEvent event, boolean wait) - { - if (synchronous) - doFireVideoEvent(event); - else - { - synchronized (events) - { - events.add(event); - - if (thread == null) - startThread(); - else - events.notify(); - - if (wait) - { - boolean interrupted = false; - - while (events.contains(event) && (thread != null)) - { - try - { - events.wait(); - } - catch (InterruptedException ie) - { - interrupted = true; - } - } - if (interrupted) - Thread.currentThread().interrupt(); - } - } - } - } - - /** - * Removes a specific VideoListener from this - * VideoNotifierSupport in order to have to no longer receive - * notifications when visual/video Components are being added and - * removed. - * - * @param listener the VideoListener to no longer be notified when - * visual/video Components are being added or removed - */ - public void removeVideoListener(VideoListener listener) - { - synchronized (listeners) - { - listeners.remove(listener); - } - } - - private void runInThread() - { - while (true) - { - VideoEvent event = null; - - synchronized (events) - { - long emptyTime = -1; - boolean interrupted = false; - - while (events.isEmpty()) - { - if (emptyTime == -1) - emptyTime = System.currentTimeMillis(); - else - { - long newEmptyTime = System.currentTimeMillis(); - - if ((newEmptyTime - emptyTime) >= THREAD_TIMEOUT) - { - events.notify(); - return; - } - } - - try - { - events.wait(THREAD_TIMEOUT); - } - catch (InterruptedException ie) - { - interrupted = true; - } - } - if (interrupted) - Thread.currentThread().interrupt(); - - event = events.remove(0); - } - - if (event != null) - { - try - { - doFireVideoEvent(event); - } - catch (Throwable t) - { - if (t instanceof ThreadDeath) - throw (ThreadDeath) t; - } - - synchronized (events) - { - events.notify(); - } - } - } - } - - private void startThread() - { - thread - = new Thread("VideoNotifierSupportThread") - { - @Override - public void run() - { - try - { - runInThread(); - } - finally - { - synchronized (events) - { - if (Thread.currentThread().equals(thread)) - { - thread = null; - if (events.isEmpty()) - events.notify(); - else - startThread(); - } - } - } - } - }; - thread.setDaemon(true); - thread.start(); - } -} diff --git a/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java b/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java index 844da5681..9ecda900c 100644 --- a/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java +++ b/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java @@ -12,6 +12,8 @@ import net.java.sip.communicator.util.*; +import org.jitsi.util.*; + /** * The LauncherArgHandler class handles invocation arguments that have * been passed to us when running SIP Communicator. The class supports a fixed diff --git a/src/net/java/sip/communicator/util/swing/AuthenticationWindow.java b/src/net/java/sip/communicator/util/swing/AuthenticationWindow.java index 539331cc5..e95cf74c0 100644 --- a/src/net/java/sip/communicator/util/swing/AuthenticationWindow.java +++ b/src/net/java/sip/communicator/util/swing/AuthenticationWindow.java @@ -13,6 +13,8 @@ import net.java.sip.communicator.util.*; +import org.jitsi.util.*; + /** * The AuthenticationWindow is the window where the user should type * his user identifier and password to login. diff --git a/src/net/java/sip/communicator/util/swing/EmphasizedLabel.java b/src/net/java/sip/communicator/util/swing/EmphasizedLabel.java index b63af6133..b99e68cef 100644 --- a/src/net/java/sip/communicator/util/swing/EmphasizedLabel.java +++ b/src/net/java/sip/communicator/util/swing/EmphasizedLabel.java @@ -101,4 +101,4 @@ protected void paintComponent(Graphics g) fUseEmphasisColor = false; super.paintComponent(g); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/util/swing/FitLayout.java b/src/net/java/sip/communicator/util/swing/FitLayout.java deleted file mode 100644 index 384824887..000000000 --- a/src/net/java/sip/communicator/util/swing/FitLayout.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.util.swing; - -import java.awt.*; - -/** - * Represents a LayoutManager which centers the first - * Component within its Container and, if the - * preferred size of the Component is larger than the size of the - * Container, scales the former within the bounds of the latter - * while preserving the aspect ratio. FitLayout is appropriate for - * Containers which display a single image or video - * Component in its entirety for which preserving the aspect ratio - * is important. - * - * @author Lyubomir Marinov - */ -public class FitLayout - implements LayoutManager -{ - - /* - * Does nothing because this LayoutManager lays out only the first Component - * of the parent Container and thus doesn't need String associations. - */ - public void addLayoutComponent(String name, Component comp) - { - } - - /** - * Gets the first Component of a specific - * Container if there is such a Component. - * - * @param parent the Container to retrieve the first - * Component of - * @return the first Component of a specific - * Container if there is such a Component; - * otherwise, null - */ - protected Component getComponent(Container parent) - { - Component[] components = parent.getComponents(); - - return (components.length > 0) ? components[0] : null; - } - - protected void layoutComponent(Component component, Rectangle bounds, - float alignmentX, float alignmentY) - { - Dimension componentSize = component.getPreferredSize(); - boolean scale = false; - double widthRatio; - double heightRatio; - - if ((componentSize.width != bounds.width) && (componentSize.width > 0)) - { - scale = true; - widthRatio = bounds.width / (double) componentSize.width; - } - else - widthRatio = 1; - if ((componentSize.height != bounds.height) - && (componentSize.height > 0)) - { - scale = true; - heightRatio = bounds.height / (double) componentSize.height; - } - else - heightRatio = 1; - if (scale) - { - double ratio = Math.min(widthRatio, heightRatio); - - componentSize.width = (int) (componentSize.width * ratio); - componentSize.height = (int) (componentSize.height * ratio); - - // Respect the maximumSize of the component. - if (component.isMaximumSizeSet()) - { - Dimension maximumSize = component.getMaximumSize(); - - if (componentSize.width > maximumSize.width) - componentSize.width = maximumSize.width; - if (componentSize.height > maximumSize.height) - componentSize.height = maximumSize.height; - } - } - - /* - * Why would one fit a Component into a rectangle with zero width and - * height? - */ - if (componentSize.height < 1) - componentSize.height = 1; - if (componentSize.width < 1) - componentSize.width = 1; - - component.setBounds( - bounds.x - + Math.round( - (bounds.width - componentSize.width) * alignmentX), - bounds.y - + Math.round( - (bounds.height - componentSize.height) * alignmentY), - componentSize.width, - componentSize.height); - } - - /* - * Scales the first Component if its preferred size is larger than the size - * of its parent Container in order to display the Component in its entirety - * and then centers it within the display area of the parent. - */ - public void layoutContainer(Container parent) - { - layoutContainer(parent, Component.CENTER_ALIGNMENT); - } - - protected void layoutContainer(Container parent, float componentAlignmentX) - { - Component component = getComponent(parent); - - if (component != null) - layoutComponent(component, new Rectangle(parent.getSize()), - componentAlignmentX, Component.CENTER_ALIGNMENT); - } - - /* - * Since this LayoutManager lays out only the first Component of the - * specified parent Container, the minimum size of the Container is the - * minimum size of the mentioned Component. - */ - public Dimension minimumLayoutSize(Container parent) - { - Component component = getComponent(parent); - - return (component != null) ? component.getMinimumSize() - : new Dimension(0, 0); - } - - /* - * Since this LayoutManager lays out only the first Component of the - * specified parent Container, the preferred size of the Container is the - * preferred size of the mentioned Component. - */ - public Dimension preferredLayoutSize(Container parent) - { - Component component = getComponent(parent); - - return (component != null) ? component.getPreferredSize() - : new Dimension(0, 0); - } - - /* - * Does nothing because this LayoutManager lays out only the first Component - * of the parent Container and thus doesn't need String associations. - */ - public void removeLayoutComponent(Component comp) - { - } -} diff --git a/src/net/java/sip/communicator/util/swing/FramedImage.java b/src/net/java/sip/communicator/util/swing/FramedImage.java index f1945aca6..60d741043 100644 --- a/src/net/java/sip/communicator/util/swing/FramedImage.java +++ b/src/net/java/sip/communicator/util/swing/FramedImage.java @@ -186,4 +186,4 @@ private ImageIcon getScaledImage(byte[] image) { return ImageUtils.getScaledRoundedIcon(image, width - 2, height - 2); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/util/swing/GenericFileDialog.java b/src/net/java/sip/communicator/util/swing/GenericFileDialog.java index 03309218c..86ec57cf5 100644 --- a/src/net/java/sip/communicator/util/swing/GenericFileDialog.java +++ b/src/net/java/sip/communicator/util/swing/GenericFileDialog.java @@ -8,9 +8,9 @@ import java.awt.*; -import javax.swing.JFileChooser; +import javax.swing.*; -import net.java.sip.communicator.util.*; +import org.jitsi.util.*; /** diff --git a/src/net/java/sip/communicator/util/swing/MasterPasswordInputDialog.java b/src/net/java/sip/communicator/util/swing/MasterPasswordInputDialog.java index a33c3771d..59a46ef80 100644 --- a/src/net/java/sip/communicator/util/swing/MasterPasswordInputDialog.java +++ b/src/net/java/sip/communicator/util/swing/MasterPasswordInputDialog.java @@ -10,9 +10,10 @@ import javax.swing.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; + /** * The master password input dialog. * diff --git a/src/net/java/sip/communicator/util/swing/SIPCommCheckBox.java b/src/net/java/sip/communicator/util/swing/SIPCommCheckBox.java index 1e0bcf3f8..7ddf98f7e 100644 --- a/src/net/java/sip/communicator/util/swing/SIPCommCheckBox.java +++ b/src/net/java/sip/communicator/util/swing/SIPCommCheckBox.java @@ -8,7 +8,7 @@ import javax.swing.*; -import net.java.sip.communicator.util.*; +import org.jitsi.util.*; /** * @author Lubomir Marinov diff --git a/src/net/java/sip/communicator/util/swing/SIPCommDialog.java b/src/net/java/sip/communicator/util/swing/SIPCommDialog.java index 282d4a4a4..8279e94f9 100644 --- a/src/net/java/sip/communicator/util/swing/SIPCommDialog.java +++ b/src/net/java/sip/communicator/util/swing/SIPCommDialog.java @@ -11,8 +11,11 @@ import javax.swing.*; -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; + +import org.jitsi.service.configuration.*; +import org.jitsi.util.*; /** * @author Yana Stamcheva diff --git a/src/net/java/sip/communicator/util/swing/SIPCommFrame.java b/src/net/java/sip/communicator/util/swing/SIPCommFrame.java index e00420420..158760ee4 100644 --- a/src/net/java/sip/communicator/util/swing/SIPCommFrame.java +++ b/src/net/java/sip/communicator/util/swing/SIPCommFrame.java @@ -16,10 +16,13 @@ import javax.swing.*; -import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.service.keybindings.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.Logger; + +import org.jitsi.service.configuration.*; +import org.jitsi.service.resources.*; +import org.jitsi.util.*; /** * A custom frame that remembers its size and location and could have a diff --git a/src/net/java/sip/communicator/util/swing/SIPCommRadioButton.java b/src/net/java/sip/communicator/util/swing/SIPCommRadioButton.java index 6e9ad5893..42a7f5d31 100644 --- a/src/net/java/sip/communicator/util/swing/SIPCommRadioButton.java +++ b/src/net/java/sip/communicator/util/swing/SIPCommRadioButton.java @@ -8,7 +8,7 @@ import javax.swing.*; -import net.java.sip.communicator.util.*; +import org.jitsi.util.*; /** * @author Ingo Bauersachs diff --git a/src/net/java/sip/communicator/util/swing/SIPCommTextField.java b/src/net/java/sip/communicator/util/swing/SIPCommTextField.java index 151dc7c4c..54c04f6ed 100644 --- a/src/net/java/sip/communicator/util/swing/SIPCommTextField.java +++ b/src/net/java/sip/communicator/util/swing/SIPCommTextField.java @@ -283,4 +283,4 @@ private void fireTextFieldChangeListener(int eventType) case 1: l.textRemoved(); break; } } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/util/swing/SipCommFileDialogImpl.java b/src/net/java/sip/communicator/util/swing/SipCommFileDialogImpl.java index 8c5cc1e0e..c61735b68 100644 --- a/src/net/java/sip/communicator/util/swing/SipCommFileDialogImpl.java +++ b/src/net/java/sip/communicator/util/swing/SipCommFileDialogImpl.java @@ -6,11 +6,11 @@ */ package net.java.sip.communicator.util.swing; -import net.java.sip.communicator.util.*; - import java.awt.*; import java.io.*; +import org.jitsi.util.*; + /** * Implements SipCommFileChooser for AWT's FileDialog. * diff --git a/src/net/java/sip/communicator/util/swing/SoundLevelIndicator.java b/src/net/java/sip/communicator/util/swing/SoundLevelIndicator.java index 81894bb64..92b65dd2d 100644 --- a/src/net/java/sip/communicator/util/swing/SoundLevelIndicator.java +++ b/src/net/java/sip/communicator/util/swing/SoundLevelIndicator.java @@ -10,10 +10,11 @@ import javax.swing.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.skin.*; +import org.jitsi.service.resources.*; + /** * Represents the sound level indicator for a particular peer. * diff --git a/src/net/java/sip/communicator/util/swing/SwingWorker.java b/src/net/java/sip/communicator/util/swing/SwingWorker.java index 9b193a102..aa2d90693 100644 --- a/src/net/java/sip/communicator/util/swing/SwingWorker.java +++ b/src/net/java/sip/communicator/util/swing/SwingWorker.java @@ -216,4 +216,4 @@ public void run() }); } } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/util/swing/TransparentPanel.java b/src/net/java/sip/communicator/util/swing/TransparentPanel.java index ba7600f67..d2b6cfb11 100644 --- a/src/net/java/sip/communicator/util/swing/TransparentPanel.java +++ b/src/net/java/sip/communicator/util/swing/TransparentPanel.java @@ -8,25 +8,23 @@ import java.awt.*; -import javax.swing.*; - /** - * @author Yana Stamcheva + * Provides compatibility with source code written prior to the inception of + * libjitsi. + * + * @author Lyubomir Marinov */ public class TransparentPanel - extends JPanel + extends org.jitsi.util.swing.TransparentPanel { private static final long serialVersionUID = 0L; public TransparentPanel() { - this.setOpaque(false); } public TransparentPanel(LayoutManager layout) { super(layout); - - this.setOpaque(false); } } diff --git a/src/net/java/sip/communicator/util/swing/VideoContainer.java b/src/net/java/sip/communicator/util/swing/VideoContainer.java deleted file mode 100644 index aed90a1b3..000000000 --- a/src/net/java/sip/communicator/util/swing/VideoContainer.java +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.util.swing; - -import java.awt.*; -import java.awt.event.*; -import java.lang.reflect.*; - -import net.java.sip.communicator.util.*; - -/** - * Implements a Container for video/visual Components. - * VideoContainer uses {@link VideoLayout} to layout the video/visual - * Components it contains. A specific Component can be - * displayed by default at {@link VideoLayout#CENTER_REMOTE}. - * - * @author Lyubomir Marinov - * @author Yana Stamcheva - */ -public class VideoContainer - extends TransparentPanel -{ - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * The Logger used by the VideoContainer class and its - * instances for logging output. - */ - private static final Logger logger = Logger.getLogger(VideoContainer.class); - - /** - * The default background color. - */ - public static final Color DEFAULT_BACKGROUND_COLOR - = OSUtils.IS_MAC ? Color.BLACK : null; - - /** - * The name of the instance method of Components added to - * VideoContainer which creates a new Component acting as - * a canvas in which the other Components contained in the - * VideoContainer are painted. - */ - private static final String VIDEO_CANVAS_FACTORY_METHOD_NAME - = "createCanvas"; - - /** - * The Component which is the canvas, if any, in which the other - * Components contained in this VideoContainer are - * painted. - */ - private Component canvas; - - /** - * The Component to be displayed by this VideoContainer - * at {@link VideoLayout#CENTER_REMOTE} when no other Component has - * been added to it to be displayed there. For example, the avatar of the - * remote peer may be displayed in place of the remote video when the remote - * video is not available. - */ - private final Component noVideoComponent; - - /** - * Initializes a new VideoContainer with a specific - * Component to be displayed when no remote video is available. - * - * @param noVideoComponent the component to be displayed when no remote - * video is available - * @param isConference indicates if this VideoLayout is dedicated - * to a conference interface. - */ - public VideoContainer(Component noVideoComponent, boolean isConference) - { - setLayout(new VideoLayout(isConference)); - - this.noVideoComponent = noVideoComponent; - - /* - * JAWTRenderer on Mac OS X will by default occupy the whole video - * container and will, consequently, draw a black background. In certain - * problematic cases which it will try to provide a workaround, it will - * not occupy the whole video container. To make the experience - * relatively the same, always use a black background. - */ - if (DEFAULT_BACKGROUND_COLOR != null) - { - setBackground(DEFAULT_BACKGROUND_COLOR); - addContainerListener( - new ContainerListener() - { - public void componentAdded(ContainerEvent e) - { - int componentCount = getComponentCount(); - - if ((componentCount == 1) - && (getComponent(0) - == VideoContainer.this.noVideoComponent)) - componentCount = 0; - - setOpaque(componentCount > 0); - } - - public void componentRemoved(ContainerEvent e) - { - /* - * It's all the same with respect to the purpose of this - * ContainerListener. - */ - componentAdded(e); - } - }); - } - - if (this.noVideoComponent != null) - { - add(this.noVideoComponent, VideoLayout.CENTER_REMOTE, -1); - validate(); - } - } - - /** - * Adds the given component at the {@link VideoLayout#CENTER_REMOTE} - * position in the default video layout. - * - * @param comp the component to add - * @return the added component - */ - @Override - public Component add(Component comp) - { - add(comp, VideoLayout.CENTER_REMOTE); - return comp; - } - - @Override - public Component add(Component comp, int index) - { - add(comp, null, index); - return comp; - } - - @Override - public void add(Component comp, Object constraints) - { - add(comp, constraints, -1); - } - - /** - * Overrides the default behavior of add in order to be sure to remove the - * default "no video" component when a remote video component is added. - * - * @param comp the component to add - * @param constraints - * @param index - */ - @Override - public void add(Component comp, Object constraints, int index) - { - if (VideoLayout.CENTER_REMOTE.equals(constraints) - && (noVideoComponent != null) - && !noVideoComponent.equals(comp) - || (comp.equals(noVideoComponent) - && noVideoComponent.getParent() != null)) - { - remove(noVideoComponent); - validate(); - } - - if ((canvas == null) || (canvas.getParent() != this)) - { - if (OSUtils.IS_MAC && (comp != canvas)) - { - /* - * Unless the comp has a createCanvas() method, it makes no - * sense to consider any exception a problem. - */ - boolean ignoreException; - Throwable exception; - - ignoreException = true; - exception = null; - canvas = null; - - try - { - Method m - = comp.getClass().getMethod( - VIDEO_CANVAS_FACTORY_METHOD_NAME); - - if (m != null) - { - ignoreException = false; - - Object c = m.invoke(comp); - - if (c instanceof Component) - canvas = (Component) c; - } - } - catch (ClassCastException cce) - { - exception = cce; - } - catch (ExceptionInInitializerError eiie) - { - exception = eiie; - } - catch (IllegalAccessException illegalAccessException) - { - exception = illegalAccessException; - } - catch (IllegalArgumentException illegalArgumentException) - { - exception = illegalArgumentException; - } - catch (InvocationTargetException ita) - { - exception = ita; - } - catch (NoSuchMethodException nsme) - { - exception = nsme; - } - catch (NullPointerException npe) - { - exception = npe; - } - catch (SecurityException se) - { - exception = se; - } - if (canvas != null) - add(canvas, VideoLayout.CANVAS, 0); - else if ((exception != null) && !ignoreException) - logger.error("Failed to create video canvas.", exception); - } - } - if ((canvas != null) - && (canvas.getParent() == this) - && OSUtils.IS_MAC - && (comp != canvas)) - { - /* - * The canvas in which the other components are to be painted should - * always be at index 0. And the order of adding is important so no - * index should be specified - */ - index = -1; - } - - /* - * XXX Do not call #remove(Component) beyond this point and before - * #add(Component, Object, int) because #removeCanvasIfNecessary() will - * remove the canvas. - */ - - super.add(comp, constraints, index); - } - - /** - * Overrides the default remove behavior in order to add the default no - * video component when the remote video is removed. - * - * @param comp the component to remove - */ - @Override - public void remove(Component comp) - { - super.remove(comp); - - if ((comp == canvas) - && (canvas != null) - && (canvas.getParent() != this)) - { - canvas = null; - validate(); - } - - Component[] components = getComponents(); - VideoLayout videoLayout = (VideoLayout) getLayout(); - boolean hasComponentsAtCenterRemote = false; - - for (Component c : components) - { - if (!c.equals(noVideoComponent) - && VideoLayout.CENTER_REMOTE.equals( - videoLayout.getComponentConstraints(c))) - { - hasComponentsAtCenterRemote = true; - break; - } - } - - if (!hasComponentsAtCenterRemote - && (noVideoComponent != null) - && !noVideoComponent.equals(comp)) - { - add(noVideoComponent, VideoLayout.CENTER_REMOTE); - validate(); - } - - removeCanvasIfNecessary(); - } - - /** - * Ensures noVideoComponent is displayed even when the clients of the - * videoContainer invoke its #removeAll() to remove their previous visual - * Components representing video. Just adding noVideoComponent upon - * ContainerEvent#COMPONENT_REMOVED when there is no other Component left in - * the Container will cause an infinite loop because Container#removeAll() - * will detect that a new Component has been added while dispatching the - * event and will then try to remove the new Component. - */ - @Override - public void removeAll() - { - super.removeAll(); - - if ((canvas != null) && (canvas.getParent() != this)) - canvas = null; - - if (noVideoComponent != null) - { - add(noVideoComponent, VideoLayout.CENTER_REMOTE); - validate(); - } - } - - /** - * Removes {@link #canvas} from this VideoContainer if no sibling - * Component needs it. - */ - public void removeCanvasIfNecessary() - { - if ((canvas == null) || !OSUtils.IS_MAC) - return; - - boolean removeCanvas = true; - - for (Component component : getComponents()) - { - if (component == canvas) - continue; - try - { - component.getClass().getMethod( - VIDEO_CANVAS_FACTORY_METHOD_NAME); - removeCanvas = false; - break; - } - catch (NoSuchMethodException nsme) - { - /* - * Ignore it because we already presume that component does not - * need the canvas. - */ - } - } - if (removeCanvas) - remove(canvas); - } -} diff --git a/src/net/java/sip/communicator/util/swing/VideoLayout.java b/src/net/java/sip/communicator/util/swing/VideoLayout.java deleted file mode 100644 index fb7ba7c87..000000000 --- a/src/net/java/sip/communicator/util/swing/VideoLayout.java +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.util.swing; - -import java.awt.*; -import java.util.*; -import java.util.List; - -import javax.swing.*; - -/** - * Implements the LayoutManager which lays out the local and remote - * videos in a video Call. - * - * @author Lyubomir Marinov - * @author Yana Stamcheva - */ -public class VideoLayout extends FitLayout -{ - /** - * The video canvas constraint. - */ - public static final String CANVAS = "CANVAS"; - - /** - * The center remote video constraint. - */ - public static final String CENTER_REMOTE = "CENTER_REMOTE"; - - /** - * The close local video constraint. - */ - public static final String CLOSE_LOCAL_BUTTON = "CLOSE_LOCAL_BUTTON"; - - /** - * The east remote video constraint. - */ - public static final String EAST_REMOTE = "EAST_REMOTE"; - - /** - * The local video constraint. - */ - public static final String LOCAL = "LOCAL"; - - /** - * The ration between the local and the remote video. - */ - private static final float LOCAL_TO_REMOTE_RATIO = 0.30f; - - /** - * The video canvas. - */ - private Component canvas; - - /** - * The close local video button component. - */ - private Component closeButton; - - /** - * The map of component constraints. - */ - private final HashMap constraints - = new HashMap(); - - /** - * The component containing the local video. - */ - private Component local; - - /** - * The list of Components depicting remote videos. - */ - private final List remotes = new LinkedList(); - - /** - * The x coordinate alignment of the remote video. - */ - private float remoteAlignmentX = Component.CENTER_ALIGNMENT; - - /** - * Indicates if this VideoLayout is dedicated to a conference - * interface. - */ - private final boolean isConference; - - /** - * Creates an instance of VideoLayout by also indicating if this - * video layout is dedicated to a conference interface. - * - * @param isConference indicates if this VideoLayout is dedicated - * to a conference interface. - */ - public VideoLayout(boolean isConference) - { - super(); - - this.isConference = isConference; - } - - /** - * Adds the given component in this layout on the specified by name - * position. - * - * @param name the constraint giving the position of the component in this - * layout - * @param comp the component to add - */ - @Override - public void addLayoutComponent(String name, Component comp) - { - super.addLayoutComponent(name, comp); - - synchronized (constraints) - { - this.constraints.put(comp, name); - } - - if ((name == null) || name.equals(CENTER_REMOTE)) - { - remotes.add(comp); - remoteAlignmentX = Component.CENTER_ALIGNMENT; - } - else if (name.equals(EAST_REMOTE)) - { - remotes.add(comp); - remoteAlignmentX = Component.RIGHT_ALIGNMENT; - } - else if (name.equals(LOCAL)) - local = comp; - else if (name.equals(CLOSE_LOCAL_BUTTON)) - closeButton = comp; - else if (name.equals(CANVAS)) - canvas = comp; - } - - /** - * Determines how may columns to use for the grid display of specific remote - * visual/video Components. - * - * @param remotes the remote visual/video Components to be - * displayed in a grid - * @return the number of columns to use for the grid display of the - * specified remote visual/video Components - */ - private int calculateColumnCount(List remotes) - { - int remotesCount = remotes.size(); - - if (remotesCount == 1) - return 1; - else if (remotesCount == 2 || remotesCount == 4) - return 2; - else - return 3; - } - - /** - * Returns the remote video component. - * - * @return the remote video component - */ - @Override - protected Component getComponent(Container parent) - { - return (remotes.size() == 1) ? remotes.get(0) : null; - } - - /** - * Returns the constraints for the given component. - * - * @param c the component for which constraints we're looking for - * @return the constraints for the given component - */ - public Object getComponentConstraints(Component c) - { - synchronized (constraints) - { - return constraints.get(c); - } - } - - /** - * Returns the local video component. - * - * @return the local video component - */ - public Component getLocal() - { - return local; - } - - /** - * Returns the local video close button. - * - * @return the local video close button - */ - public Component getLocalCloseButton() - { - return closeButton; - } - - /** - * Lays out this given container. - * - * @param parent the container to lay out - */ - @Override - public void layoutContainer(Container parent) - { - List remotes; - Component local = getLocal(); - - /* - * When there are multiple remote visual/video Components, the local one - * will be displayed as if it is a remote one i.e. in the same grid, not - * on top of a remote one. - */ - if ((this.remotes.size() > 1) && (local != null)) - { - remotes = new ArrayList(); - remotes.addAll(this.remotes); - remotes.add(local); - } - else - remotes = this.remotes; - - int remoteCount = remotes.size(); - - // We need to reduce parent size in order to fit also the space we've - // left between videos. - Dimension parentSize = parent.getSize(); - parentSize.width -= remoteCount*10; - - if (remoteCount == 1 && !isConference) - { - super.layoutContainer(parent, - (local == null) - ? Component.CENTER_ALIGNMENT - : remoteAlignmentX); - } - else if (remoteCount > 0) - { - int columns = calculateColumnCount(remotes); - int rows = (remoteCount + columns - 1) / columns; - Rectangle bounds - = new Rectangle( - 0, - 0, - parentSize.width / columns, - parentSize.height / rows); - int columnsMinus1 = columns - 1; - int i = 0; - - for (Component remote : remotes) - { - /* - * We want the remote videos ordered from right to left so that - * the local video does not cover a remote video when possible. - */ - bounds.x = (columnsMinus1 - (i % columns)) * bounds.width; - bounds.y = (i / columns) * bounds.height; - - if (bounds.x > 0) - bounds.x += ((columns - (i%columns))*10); - - super.layoutComponent( - remote, - bounds, - Component.CENTER_ALIGNMENT, - Component.CENTER_ALIGNMENT); - - i++; - if (i >= remoteCount) - break; - } - } - - if (local != null) - { - /* - * If the local visual/video Component is not displayed as if it is - * a remote one, it will be placed on top of a remote one. - */ - if (!remotes.contains(local) && !isConference) - { - Component remote0 = remotes.isEmpty() ? null : remotes.get(0); - int localX; - int localY; - int height - = Math.round(parentSize.height * LOCAL_TO_REMOTE_RATIO); - int width - = Math.round(parentSize.width * LOCAL_TO_REMOTE_RATIO); - - /* - * XXX The remote Component being a JLabel is meant to signal - * that there is no remote video and the remote is the - * photoLabel. - */ - if ((remotes.size() == 1) && (remote0 instanceof JLabel)) - { - localX = parentSize.width/2 - width/2; - localY = parentSize.height - height; - super.layoutComponent( - local, - new Rectangle(localX, localY, width, height), - Component.CENTER_ALIGNMENT, - Component.BOTTOM_ALIGNMENT); - } - else - { - localX = ((remote0 == null) ? 0 : remote0.getX()) + 5; - localY = parentSize.height - height - 5; - - super.layoutComponent( - local, - new Rectangle(localX, localY, width, height), - Component.LEFT_ALIGNMENT, - Component.BOTTOM_ALIGNMENT); - } - } - - if (closeButton != null) - { - super.layoutComponent( - closeButton, - new Rectangle( - local.getX() + local.getWidth() - - closeButton.getWidth(), - local.getY(), - closeButton.getWidth(), - closeButton.getHeight()), - Component.CENTER_ALIGNMENT, - Component.CENTER_ALIGNMENT); - } - } - - if (canvas != null) - { - /* - * The video canvas will get the locations of the other components - * to paint so it has to cover the parent completely. - */ - canvas.setBounds(0, 0, parentSize.width, parentSize.height); - } - } - - /** - * Returns the minimum layout size for the given container. - * - * @param parent the container which minimum layout size we're looking for - * @return a Dimension containing, the minimum layout size for the given - * container - */ - @Override - public Dimension minimumLayoutSize(Container parent) - { - // TODO Auto-generated method stub - return super.minimumLayoutSize(parent); - } - - /** - * Returns the preferred layout size for the given container. - * - * @param parent the container which preferred layout size we're looking for - * @return a Dimension containing, the preferred layout size for the given - * container - */ - @Override - public Dimension preferredLayoutSize(Container parent) - { - List remotes; - Component local = getLocal(); - - /* - * When there are multiple remote visual/video Components, the local one - * will be displayed as if it is a remote one i.e. in the same grid, not - * on top of a remote one. - */ - if ((this.remotes.size() > 1) && (local != null)) - { - remotes = new ArrayList(); - remotes.addAll(this.remotes); - remotes.add(local); - } - else - remotes = this.remotes; - - int remoteCount = remotes.size(); - - if (remoteCount == 0) - { - /* - * If there is no remote visual/video Component, the local one will - * serve the preferredSize of the Container. - */ - if (local != null) - { - Dimension preferredSize = local.getPreferredSize(); - - if (preferredSize != null) - return preferredSize; - } - } - else if (remoteCount == 1) - { - /* - * If there is a single remote visual/video Component, the local one - * will be on top of it so the remote one will serve the - * preferredSize of the Container. - */ - Dimension preferredSize = remotes.get(0).getPreferredSize(); - - if (preferredSize != null) - return preferredSize; - } - else if (remoteCount > 1) - { - int maxWidth = 0; - int maxHeight = 0; - - for (Component remote : remotes) - { - Dimension preferredSize = remote.getPreferredSize(); - - if (preferredSize != null) - { - if (maxWidth < preferredSize.width) - maxWidth = preferredSize.width; - if (maxHeight < preferredSize.height) - maxHeight = preferredSize.height; - } - } - - if ((maxWidth > 0) && (maxHeight > 0)) - { - int columns = calculateColumnCount(remotes); - int rows = (remoteCount + columns - 1) / columns; - - return new Dimension(maxWidth * columns, maxHeight * rows); - } - } - - return super.preferredLayoutSize(parent); - } - - /** - * Removes the given component from this layout. - * - * @param comp the component to remove from the layout - */ - @Override - public void removeLayoutComponent(Component comp) - { - super.removeLayoutComponent(comp); - - if (local == comp) - local = null; - else if (closeButton == comp) - closeButton = null; - else if (canvas == comp) - canvas = null; - else - remotes.remove(comp); - } -} diff --git a/src/net/java/sip/communicator/util/swing/X509CertificatePanel.java b/src/net/java/sip/communicator/util/swing/X509CertificatePanel.java index fbab15478..4673cb6d4 100644 --- a/src/net/java/sip/communicator/util/swing/X509CertificatePanel.java +++ b/src/net/java/sip/communicator/util/swing/X509CertificatePanel.java @@ -18,9 +18,10 @@ import javax.security.auth.x500.*; import javax.swing.*; -import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; + /** * Panel that shows the content of an X509Certificate. */ diff --git a/src/net/java/sip/communicator/util/swing/plaf/SIPCommTextFieldUI.java b/src/net/java/sip/communicator/util/swing/plaf/SIPCommTextFieldUI.java index fb303ed49..5b6819746 100644 --- a/src/net/java/sip/communicator/util/swing/plaf/SIPCommTextFieldUI.java +++ b/src/net/java/sip/communicator/util/swing/plaf/SIPCommTextFieldUI.java @@ -468,4 +468,4 @@ public static ComponentUI createUI(JComponent c) { return new SIPCommTextFieldUI(); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/util/swing/transparent/AWTUtilitiesWrapper.java b/src/net/java/sip/communicator/util/swing/transparent/AWTUtilitiesWrapper.java index e247c3d73..e72c385d3 100644 --- a/src/net/java/sip/communicator/util/swing/transparent/AWTUtilitiesWrapper.java +++ b/src/net/java/sip/communicator/util/swing/transparent/AWTUtilitiesWrapper.java @@ -161,4 +161,4 @@ public static void setWindowOpaque(Window window, boolean opaque) { set(mSetWindowOpaque, window, Boolean.valueOf(opaque)); } -} \ No newline at end of file +} diff --git a/src/net/java/sip/communicator/util/util.manifest.mf b/src/net/java/sip/communicator/util/util.manifest.mf index 2189026dc..9b27cfc7e 100644 --- a/src/net/java/sip/communicator/util/util.manifest.mf +++ b/src/net/java/sip/communicator/util/util.manifest.mf @@ -27,14 +27,17 @@ Import-Package: org.xml.sax, javax.naming.ldap, javax.imageio, javax.security.auth.x500, - net.java.sip.communicator.util.xml, + org.jitsi.util, + org.jitsi.util.swing, net.java.sip.communicator.util, net.java.sip.communicator.util.dns, + net.java.sip.communicator.util.xml, + org.jitsi.service.resources, net.java.sip.communicator.service.resources, net.java.sip.communicator.service.keybindings, net.java.sip.communicator.service.netaddr, net.java.sip.communicator.service.netaddr.event, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.contactlist, sun.awt.shell, sun.net.util, diff --git a/test/net/java/sip/communicator/slick/configuration/ConfigurationServiceLick.java b/test/net/java/sip/communicator/slick/configuration/ConfigurationServiceLick.java index 0c096d377..c16a9a384 100644 --- a/test/net/java/sip/communicator/slick/configuration/ConfigurationServiceLick.java +++ b/test/net/java/sip/communicator/slick/configuration/ConfigurationServiceLick.java @@ -10,7 +10,7 @@ import org.osgi.framework.*; import junit.framework.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.util.*; /** diff --git a/test/net/java/sip/communicator/slick/configuration/TestConfigurationService.java b/test/net/java/sip/communicator/slick/configuration/TestConfigurationService.java index 1713aca7b..f1bc8e24e 100644 --- a/test/net/java/sip/communicator/slick/configuration/TestConfigurationService.java +++ b/test/net/java/sip/communicator/slick/configuration/TestConfigurationService.java @@ -6,12 +6,12 @@ */ package net.java.sip.communicator.slick.configuration; -import java.util.*; import java.beans.*; +import java.util.*; import junit.framework.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import org.osgi.framework.*; /** diff --git a/test/net/java/sip/communicator/slick/configuration/TestConfigurationServicePersistency.java b/test/net/java/sip/communicator/slick/configuration/TestConfigurationServicePersistency.java index 67b56e8d6..4b91299e3 100644 --- a/test/net/java/sip/communicator/slick/configuration/TestConfigurationServicePersistency.java +++ b/test/net/java/sip/communicator/slick/configuration/TestConfigurationServicePersistency.java @@ -12,7 +12,7 @@ import org.osgi.framework.*; import org.w3c.dom.*; import junit.framework.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.util.xml.*; /** diff --git a/test/net/java/sip/communicator/slick/configuration/TestConfigurationSlickFinalizer.java b/test/net/java/sip/communicator/slick/configuration/TestConfigurationSlickFinalizer.java index 5cd3a7e11..ee4449c7d 100644 --- a/test/net/java/sip/communicator/slick/configuration/TestConfigurationSlickFinalizer.java +++ b/test/net/java/sip/communicator/slick/configuration/TestConfigurationSlickFinalizer.java @@ -9,7 +9,7 @@ import java.util.*; import junit.framework.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import org.osgi.framework.*; diff --git a/test/net/java/sip/communicator/slick/configuration/configuration.slick.manifest.mf b/test/net/java/sip/communicator/slick/configuration/configuration.slick.manifest.mf index 8814bbef4..91b33e7fe 100644 --- a/test/net/java/sip/communicator/slick/configuration/configuration.slick.manifest.mf +++ b/test/net/java/sip/communicator/slick/configuration/configuration.slick.manifest.mf @@ -5,7 +5,7 @@ Bundle-Vendor: sip-communicator.org Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: junit.framework, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, org.osgi.framework, org.w3c.dom, javax.xml.parsers, diff --git a/test/net/java/sip/communicator/slick/contactlist/meta.cl.slick.manifest.mf b/test/net/java/sip/communicator/slick/contactlist/meta.cl.slick.manifest.mf index 685edc2a5..2987fdc5c 100644 --- a/test/net/java/sip/communicator/slick/contactlist/meta.cl.slick.manifest.mf +++ b/test/net/java/sip/communicator/slick/contactlist/meta.cl.slick.manifest.mf @@ -10,7 +10,7 @@ Import-Package: net.java.sip.communicator.service.contactlist, junit.framework, net.java.sip.communicator.util, net.java.sip.communicator.util.dns, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.icqconstants, net.java.sip.communicator.service.protocol.event, diff --git a/test/net/java/sip/communicator/slick/fileaccess/FileAccessServiceLick.java b/test/net/java/sip/communicator/slick/fileaccess/FileAccessServiceLick.java index 14220b1fb..62668d767 100644 --- a/test/net/java/sip/communicator/slick/fileaccess/FileAccessServiceLick.java +++ b/test/net/java/sip/communicator/slick/fileaccess/FileAccessServiceLick.java @@ -2,11 +2,12 @@ import java.util.*; -import org.osgi.framework.*; import junit.framework.*; -import net.java.sip.communicator.service.fileaccess.*; import net.java.sip.communicator.util.*; +import org.jitsi.service.fileaccess.*; +import org.osgi.framework.*; + /** * This class launches the bundle which tests the fileaccess bundle. This bundle * is a set of (j)unit tests. It should be launched by the cruisecontrol module. diff --git a/test/net/java/sip/communicator/slick/fileaccess/TestFailSafeTransaction.java b/test/net/java/sip/communicator/slick/fileaccess/TestFailSafeTransaction.java index 89d542d6d..36872879b 100644 --- a/test/net/java/sip/communicator/slick/fileaccess/TestFailSafeTransaction.java +++ b/test/net/java/sip/communicator/slick/fileaccess/TestFailSafeTransaction.java @@ -9,12 +9,11 @@ import java.io.*; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; - -import net.java.sip.communicator.service.fileaccess.*; import junit.framework.*; +import org.jitsi.service.fileaccess.*; +import org.osgi.framework.*; + /** * Tests for the fail safe transactions * diff --git a/test/net/java/sip/communicator/slick/fileaccess/TestFileAccessService.java b/test/net/java/sip/communicator/slick/fileaccess/TestFileAccessService.java index f16e69b10..923eeb8c0 100644 --- a/test/net/java/sip/communicator/slick/fileaccess/TestFileAccessService.java +++ b/test/net/java/sip/communicator/slick/fileaccess/TestFileAccessService.java @@ -3,9 +3,10 @@ import java.io.*; import java.util.*; -import org.osgi.framework.*; import junit.framework.*; -import net.java.sip.communicator.service.fileaccess.*; + +import org.jitsi.service.fileaccess.*; +import org.osgi.framework.*; public class TestFileAccessService extends TestCase { diff --git a/test/net/java/sip/communicator/slick/fileaccess/fileaccess.slick.manifest.mf b/test/net/java/sip/communicator/slick/fileaccess/fileaccess.slick.manifest.mf index 6c9ac4cc3..f0e45ae61 100644 --- a/test/net/java/sip/communicator/slick/fileaccess/fileaccess.slick.manifest.mf +++ b/test/net/java/sip/communicator/slick/fileaccess/fileaccess.slick.manifest.mf @@ -6,8 +6,8 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: junit.framework, net.java.sip.communicator.slick.fileaccess, - net.java.sip.communicator.service.fileaccess, - net.java.sip.communicator.service.configuration, + org.jitsi.service.fileaccess, + org.jitsi.service.configuration, org.osgi.framework, org.w3c.dom, javax.xml.parsers, diff --git a/test/net/java/sip/communicator/slick/history/history.slick.manifest.mf b/test/net/java/sip/communicator/slick/history/history.slick.manifest.mf index f9d62a859..a52a32526 100644 --- a/test/net/java/sip/communicator/slick/history/history.slick.manifest.mf +++ b/test/net/java/sip/communicator/slick/history/history.slick.manifest.mf @@ -8,7 +8,7 @@ Import-Package: junit.framework, net.java.sip.communicator.slick.history, net.java.sip.communicator.service.history.records, net.java.sip.communicator.service.history, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, org.osgi.framework, org.w3c.dom, javax.xml.parsers, diff --git a/test/net/java/sip/communicator/slick/netaddr/TestNetworkAddressManagerService.java b/test/net/java/sip/communicator/slick/netaddr/TestNetworkAddressManagerService.java index fd6b10c94..18b98cf9b 100644 --- a/test/net/java/sip/communicator/slick/netaddr/TestNetworkAddressManagerService.java +++ b/test/net/java/sip/communicator/slick/netaddr/TestNetworkAddressManagerService.java @@ -5,7 +5,7 @@ import org.osgi.framework.*; import junit.framework.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.netaddr.*; import net.java.sip.communicator.util.*; diff --git a/test/net/java/sip/communicator/slick/netaddr/netaddr.slick.manifest.mf b/test/net/java/sip/communicator/slick/netaddr/netaddr.slick.manifest.mf index 5d9f631bf..ead38fdfe 100644 --- a/test/net/java/sip/communicator/slick/netaddr/netaddr.slick.manifest.mf +++ b/test/net/java/sip/communicator/slick/netaddr/netaddr.slick.manifest.mf @@ -7,7 +7,7 @@ System-Bundle: yes Import-Package: net.java.sip.communicator.util, net.java.sip.communicator.util.dns, net.java.sip.communicator.service.netaddr, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, junit, junit.framework, junit.textui, diff --git a/test/net/java/sip/communicator/slick/protocol/generic/AuthHandler.java b/test/net/java/sip/communicator/slick/protocol/generic/AuthHandler.java index ce3551dd9..63f75492a 100644 --- a/test/net/java/sip/communicator/slick/protocol/generic/AuthHandler.java +++ b/test/net/java/sip/communicator/slick/protocol/generic/AuthHandler.java @@ -41,4 +41,4 @@ public void processAuthorizationResponse( sourceContact.getAddress() + " " + response.getResponseCode().getCode()); } -} \ No newline at end of file +} diff --git a/test/net/java/sip/communicator/slick/protocol/generic/ImEventCollector.java b/test/net/java/sip/communicator/slick/protocol/generic/ImEventCollector.java index eb6a5574b..0c0d50cf3 100644 --- a/test/net/java/sip/communicator/slick/protocol/generic/ImEventCollector.java +++ b/test/net/java/sip/communicator/slick/protocol/generic/ImEventCollector.java @@ -101,4 +101,4 @@ public void waitForEvent(long waitFor) } } } -} \ No newline at end of file +} diff --git a/test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetFileTransfer.java b/test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetFileTransfer.java index 398d1107b..e846e6270 100644 --- a/test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetFileTransfer.java +++ b/test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetFileTransfer.java @@ -8,11 +8,13 @@ import java.io.*; import java.util.*; + import junit.framework.*; -import net.java.sip.communicator.service.fileaccess.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; + +import org.jitsi.service.fileaccess.*; import org.osgi.framework.*; /** diff --git a/test/net/java/sip/communicator/slick/protocol/gibberish/TestAccountUninstallationPersistence.java b/test/net/java/sip/communicator/slick/protocol/gibberish/TestAccountUninstallationPersistence.java index 4f385464c..3159c7892 100644 --- a/test/net/java/sip/communicator/slick/protocol/gibberish/TestAccountUninstallationPersistence.java +++ b/test/net/java/sip/communicator/slick/protocol/gibberish/TestAccountUninstallationPersistence.java @@ -8,7 +8,7 @@ import org.osgi.framework.*; import junit.framework.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; /** diff --git a/test/net/java/sip/communicator/slick/protocol/gibberish/gibberish.provider.slick.manifest.mf b/test/net/java/sip/communicator/slick/protocol/gibberish/gibberish.provider.slick.manifest.mf index f2b9cf294..4fe98514a 100644 --- a/test/net/java/sip/communicator/slick/protocol/gibberish/gibberish.provider.slick.manifest.mf +++ b/test/net/java/sip/communicator/slick/protocol/gibberish/gibberish.provider.slick.manifest.mf @@ -4,7 +4,7 @@ Bundle-Description: A Service Leveraging Implementation Compatibility Kit for th Bundle-Vendor: sip-communicator.org Bundle-Version: 0.0.1 System-Bundle: yes -Import-Package: net.java.sip.communicator.service.configuration, +Import-Package: org.jitsi.service.configuration, junit.framework, org.osgi.framework, net.java.sip.communicator.util, diff --git a/test/net/java/sip/communicator/slick/protocol/icq/TestAccountUninstallationPersistence.java b/test/net/java/sip/communicator/slick/protocol/icq/TestAccountUninstallationPersistence.java index b77db43ec..64508d3af 100644 --- a/test/net/java/sip/communicator/slick/protocol/icq/TestAccountUninstallationPersistence.java +++ b/test/net/java/sip/communicator/slick/protocol/icq/TestAccountUninstallationPersistence.java @@ -8,7 +8,7 @@ import org.osgi.framework.*; import junit.framework.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; /** diff --git a/test/net/java/sip/communicator/slick/protocol/icq/icq.provider.slick.manifest.mf b/test/net/java/sip/communicator/slick/protocol/icq/icq.provider.slick.manifest.mf index 9ef5144a5..057dd7475 100644 --- a/test/net/java/sip/communicator/slick/protocol/icq/icq.provider.slick.manifest.mf +++ b/test/net/java/sip/communicator/slick/protocol/icq/icq.provider.slick.manifest.mf @@ -6,7 +6,7 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: junit.framework, javax.net, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, org.osgi.framework, net.java.sip.communicator.util, net.java.sip.communicator.util.dns, @@ -14,4 +14,4 @@ Import-Package: junit.framework, net.java.sip.communicator.service.protocol.icqconstants, net.java.sip.communicator.service.protocol.aimconstants, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.fileaccess + org.jitsi.service.fileaccess diff --git a/test/net/java/sip/communicator/slick/protocol/jabber/TestAccountInstallation.java b/test/net/java/sip/communicator/slick/protocol/jabber/TestAccountInstallation.java index 7cc7635ed..72d32ee43 100644 --- a/test/net/java/sip/communicator/slick/protocol/jabber/TestAccountInstallation.java +++ b/test/net/java/sip/communicator/slick/protocol/jabber/TestAccountInstallation.java @@ -11,7 +11,7 @@ import org.osgi.framework.*; import junit.framework.*; import net.java.sip.communicator.service.certificate.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; /** diff --git a/test/net/java/sip/communicator/slick/protocol/jabber/TestAccountUninstallationPersistence.java b/test/net/java/sip/communicator/slick/protocol/jabber/TestAccountUninstallationPersistence.java index 6d41f6255..9cbaa5813 100644 --- a/test/net/java/sip/communicator/slick/protocol/jabber/TestAccountUninstallationPersistence.java +++ b/test/net/java/sip/communicator/slick/protocol/jabber/TestAccountUninstallationPersistence.java @@ -8,7 +8,7 @@ import org.osgi.framework.*; import junit.framework.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; /** diff --git a/test/net/java/sip/communicator/slick/protocol/jabber/jabber.provider.slick.manifest.mf b/test/net/java/sip/communicator/slick/protocol/jabber/jabber.provider.slick.manifest.mf index 4bcdd72b9..ab122392a 100644 --- a/test/net/java/sip/communicator/slick/protocol/jabber/jabber.provider.slick.manifest.mf +++ b/test/net/java/sip/communicator/slick/protocol/jabber/jabber.provider.slick.manifest.mf @@ -4,7 +4,7 @@ Bundle-Description: A Service Leveraging Implementation Compatibility Kit for th Bundle-Vendor: sip-communicator.org Bundle-Version: 0.0.1 System-Bundle: yes -Import-Package: net.java.sip.communicator.service.configuration, +Import-Package: org.jitsi.service.configuration, net.java.sip.communicator.service.certificate, junit.framework, org.osgi.framework, @@ -16,4 +16,4 @@ Import-Package: net.java.sip.communicator.service.configuration, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.jabberconstants, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.fileaccess + org.jitsi.service.fileaccess diff --git a/test/net/java/sip/communicator/slick/protocol/msn/TestAccountUninstallationPersistence.java b/test/net/java/sip/communicator/slick/protocol/msn/TestAccountUninstallationPersistence.java index 1b2a3655b..b3f1e7f04 100644 --- a/test/net/java/sip/communicator/slick/protocol/msn/TestAccountUninstallationPersistence.java +++ b/test/net/java/sip/communicator/slick/protocol/msn/TestAccountUninstallationPersistence.java @@ -8,7 +8,7 @@ import org.osgi.framework.*; import junit.framework.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; /** diff --git a/test/net/java/sip/communicator/slick/protocol/msn/msn.provider.slick.manifest.mf b/test/net/java/sip/communicator/slick/protocol/msn/msn.provider.slick.manifest.mf index 4e657f2c9..40b4cd5ff 100644 --- a/test/net/java/sip/communicator/slick/protocol/msn/msn.provider.slick.manifest.mf +++ b/test/net/java/sip/communicator/slick/protocol/msn/msn.provider.slick.manifest.mf @@ -8,10 +8,10 @@ Import-Package: junit.framework, org.osgi.framework, javax.net.ssl, javax.xml.parsers, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.event, net.java.sip.communicator.service.protocol.msnconstants, net.java.sip.communicator.util, net.java.sip.communicator.util.dns, - net.java.sip.communicator.service.fileaccess + org.jitsi.service.fileaccess diff --git a/test/net/java/sip/communicator/slick/protocol/rss/TestAccountUninstallationPersistence.java b/test/net/java/sip/communicator/slick/protocol/rss/TestAccountUninstallationPersistence.java index b4fef1fa2..743b37848 100755 --- a/test/net/java/sip/communicator/slick/protocol/rss/TestAccountUninstallationPersistence.java +++ b/test/net/java/sip/communicator/slick/protocol/rss/TestAccountUninstallationPersistence.java @@ -8,7 +8,7 @@ import junit.framework.*; import org.osgi.framework.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; /** diff --git a/test/net/java/sip/communicator/slick/protocol/rss/rss.provider.slick.manifest.mf b/test/net/java/sip/communicator/slick/protocol/rss/rss.provider.slick.manifest.mf index dd5adad0e..bc3e56e74 100644 --- a/test/net/java/sip/communicator/slick/protocol/rss/rss.provider.slick.manifest.mf +++ b/test/net/java/sip/communicator/slick/protocol/rss/rss.provider.slick.manifest.mf @@ -4,7 +4,7 @@ Bundle-Description: A Service Leveraging Implementation Compatibility Kit for th Bundle-Vendor: sip-communicator.org Bundle-Version: 0.0.1 System-Bundle: yes -Import-Package: net.java.sip.communicator.service.configuration, +Import-Package: org.jitsi.service.configuration, junit.framework, org.osgi.framework, net.java.sip.communicator.util, diff --git a/test/net/java/sip/communicator/slick/protocol/sip/TestAccountUninstallationPersistence.java b/test/net/java/sip/communicator/slick/protocol/sip/TestAccountUninstallationPersistence.java index dcfd1cffc..680a77587 100644 --- a/test/net/java/sip/communicator/slick/protocol/sip/TestAccountUninstallationPersistence.java +++ b/test/net/java/sip/communicator/slick/protocol/sip/TestAccountUninstallationPersistence.java @@ -8,7 +8,7 @@ import org.osgi.framework.*; import junit.framework.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; /** diff --git a/test/net/java/sip/communicator/slick/protocol/sip/sip.provider.slick.manifest.mf b/test/net/java/sip/communicator/slick/protocol/sip/sip.provider.slick.manifest.mf index d52a38b1e..b40410b96 100644 --- a/test/net/java/sip/communicator/slick/protocol/sip/sip.provider.slick.manifest.mf +++ b/test/net/java/sip/communicator/slick/protocol/sip/sip.provider.slick.manifest.mf @@ -4,7 +4,7 @@ Bundle-Description: A bundle that contains all tests for the SIP implementation Bundle-Vendor: sip-communicator.org Bundle-Version: 0.0.1 System-Bundle: yes -Import-Package: net.java.sip.communicator.service.configuration, +Import-Package: org.jitsi.service.configuration, junit.framework, org.osgi.framework, org.w3c.dom, diff --git a/test/net/java/sip/communicator/slick/protocol/yahoo/TestAccountUninstallationPersistence.java b/test/net/java/sip/communicator/slick/protocol/yahoo/TestAccountUninstallationPersistence.java index 6e6f21c2c..8aec8ca9e 100644 --- a/test/net/java/sip/communicator/slick/protocol/yahoo/TestAccountUninstallationPersistence.java +++ b/test/net/java/sip/communicator/slick/protocol/yahoo/TestAccountUninstallationPersistence.java @@ -8,7 +8,7 @@ import org.osgi.framework.*; import junit.framework.*; -import net.java.sip.communicator.service.configuration.*; +import org.jitsi.service.configuration.*; import net.java.sip.communicator.service.protocol.*; /** diff --git a/test/net/java/sip/communicator/slick/protocol/yahoo/yahoo.provider.slick.manifest.mf b/test/net/java/sip/communicator/slick/protocol/yahoo/yahoo.provider.slick.manifest.mf index f0b6b35c2..26b7ac0b6 100644 --- a/test/net/java/sip/communicator/slick/protocol/yahoo/yahoo.provider.slick.manifest.mf +++ b/test/net/java/sip/communicator/slick/protocol/yahoo/yahoo.provider.slick.manifest.mf @@ -4,7 +4,7 @@ Bundle-Description: A Service Leveraging Implementation Compatibility Kit for th Bundle-Vendor: sip-communicator.org Bundle-Version: 0.0.1 System-Bundle: yes -Import-Package: net.java.sip.communicator.service.configuration, +Import-Package: org.jitsi.service.configuration, junit.framework, org.osgi.framework, javax.net.ssl, @@ -14,4 +14,4 @@ Import-Package: net.java.sip.communicator.service.configuration, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.yahooconstants, net.java.sip.communicator.service.protocol.event, - net.java.sip.communicator.service.fileaccess + org.jitsi.service.fileaccess diff --git a/test/net/java/sip/communicator/slick/runner/slick-runner.manifest.mf b/test/net/java/sip/communicator/slick/runner/slick-runner.manifest.mf index 467e1a9a2..6de663587 100644 --- a/test/net/java/sip/communicator/slick/runner/slick-runner.manifest.mf +++ b/test/net/java/sip/communicator/slick/runner/slick-runner.manifest.mf @@ -4,7 +4,7 @@ Bundle-Description: A bundle that runs all SLICKs declared in the corresponding Bundle-Vendor: sip-communicator.org Bundle-Version: 0.0.1 System-Bundle: yes -Import-Package: net.java.sip.communicator.service.configuration, +Import-Package: org.jitsi.service.configuration, junit, junit.framework, junit.swingui, diff --git a/test/net/java/sip/communicator/slick/slickless/slickless.manifest.mf b/test/net/java/sip/communicator/slick/slickless/slickless.manifest.mf index 07a79ec71..0544e77ea 100644 --- a/test/net/java/sip/communicator/slick/slickless/slickless.manifest.mf +++ b/test/net/java/sip/communicator/slick/slickless/slickless.manifest.mf @@ -4,7 +4,7 @@ Bundle-Description: Unit testing for classes not belonging to any service implem Bundle-Vendor: sip-communicator.org Bundle-Version: 0.0.1 System-Bundle: yes -Import-Package: net.java.sip.communicator.service.configuration, +Import-Package: org.jitsi.service.configuration, junit, junit.framework, junit.swingui, diff --git a/test/net/java/sip/communicator/slick/version/version.slick.manifest.mf b/test/net/java/sip/communicator/slick/version/version.slick.manifest.mf index 9788fdf88..d9b7ee15a 100644 --- a/test/net/java/sip/communicator/slick/version/version.slick.manifest.mf +++ b/test/net/java/sip/communicator/slick/version/version.slick.manifest.mf @@ -7,7 +7,7 @@ System-Bundle: yes Import-Package: org.osgi.framework, net.java.sip.communicator.util, net.java.sip.communicator.util.dns, - net.java.sip.communicator.service.configuration, + org.jitsi.service.configuration, net.java.sip.communicator.service.protocol, net.java.sip.communicator.service.protocol.icqconstants, net.java.sip.communicator.service.protocol.event,