vquality_g711.pl
上传用户:wzkunzhan
上传日期:2022-04-23
资源大小:2618k
文件大小:13k
- # File: vquality_g711.pl
- #
- # Modified OpenPhone based Voice Evaluation Tool (MOBVET) Version 0.1
- # --------------------------------------------------------------------
- # Voice Over IP Laboratory (http://www.voip.nce.ufrj.br)
- # Federal University of Rio de Janeiro
- # Copyright (c) 2002-2004 UFRJ (Federal University of Rio de Janeiro).
- # The contents of this file are subject to the Mozilla Public License
- # Version 1.0 (the "License"); you may not use this file except in
- # compliance with the License. You may obtain a copy of the License at
- # http://www.mozilla.org/MPL/
- # Versao de 10/11/2003 - Leandro
- # Versao de 11/11/2003 - Leandro
- # Modificacao no codigo para considerar perda de pacotes por "buffer full"
- # Versao de 12/03/2004 - Leandro
- # Modificado para considerar tempo de dejitter_buffer como max_time/2
- use Emodel;
- #Definindo Codec como G711
- VoIP::Emodel->setIe(0);
- VoIP::Emodel->setBpl(25.1);
- $CODEC = "G711";
- $pasta = ".";
- my $dir = "side?.H323";
- #my $dir = "sideA.H323";
- my $linha;
- print "Processing the trace files...n";
- chdir $pasta;
-
-
- open DIR, "dir /b $dir |";
- #open DIR, "ls $dir |";
- my @arqs = <DIR>;
- foreach $linha (@arqs) {
-
-
- #print "Processing file: $linha";
-
- ($nome_arq, $ext_arq) = split("H",$linha);
- $log_vql = $nome_arq . "vql";
- $log_ppl = $nome_arq . "ppl";
- $log_mos = $nome_arq . "mos";
-
- #print "File PPL Nanme: $log_ppln";
- emodel($log_ppl);
-
-
- markov_chain($linha);
-
-
- }
- close DIR;
- sub emodel {
- $log_ppl = shift;
-
- open(LOG_PPL, $log_ppl) or die "CAnnot open file $log_ppln";
-
- foreach $line (<LOG_PPL>) {
-
-
- push(@emodel_array,$line);
-
-
- }
-
- close(LOG_PPL);
-
-
-
- }
- # Recebe string no formato "mm:ss.xxxx <lixo>" ou "hh:mm:ss.xxxx <lixo>" e converte para milisegundos
- sub converte_para_Milisegundos
- {
- my $arg = shift;
- if ($arg =~ /(d*):(d*):(d*).(d*)/o ) {
- return ( (($1*3600)+$2*60+$3)*1000 +$4 );
- } elsif ($arg =~ /(d*):(d*).(d*)/o ) {
- return ( (($1*60)+$2)*1000 +$3 );
- }
- printf ("Parametro Invalido: %sn", $arg);
- }
- # Recebe valor em milisegundos e converte para string no formato "mm:ss.xxxx" ou "hh:mm:ss.xxxx"
- sub ms
- {
- my $arg = shift;
-
- my ($h, $r, $m, $s, $ms);
- $h = int ($arg / 3600000);
- $r = $arg % 3600000;
- $m = int ($r / 60000);
- $r = $r % 60000;
- $s = int ($r / 1000);
- $ms = $r % 1000;
- if ($h > 0) {
- return (sprintf("%d:%02d:%02d.%03d",$h,$m,$s,$ms));
- } else {
- return (sprintf("%d:%02d.%03d",$m,$s,$ms));
- }
-
- }
- sub markov_chain {
-
-
- my $arquivo = shift;
-
- my $status_old;
- my $time_old;
-
- $e = exp(1);
-
- $pkt = 0; # contador de pacotes recebidos
- $lost = 0; # contador de pacotes perdidos
- $gmin = 16; # tamanho do gap m�imo, normalmente 16
- $c5 = 0; # utilizaco para calcular o tempo passado desde o ultimo burst significativo de perdas
- $c14 = 0;
- $c13 = 0;
- $c11 = 0;
- $c33 = 0;
- $c23 = 0;
- $c22 = 0;
- $F = 0.03; # tamanho de frame e segundos do g711 - 1 frame per packet
-
-
- # #Valores para G.723.1 6.3k + VAD
- # $d1 = 4.25;
- # $d2 = 4.8;
- # $d3 = 12;
- # $d4 = 1.75;
- $IeCODEC = 0;
-
- $t1 = 5;
- $t2 = 15;
- $i = 0;
- ($time_emodel, $rtt, $psent, $plost, $too_late, $jitter, $buffer_size) = split(" ",shift(@emodel_array));
-
- open (LOG_VQL, ">$log_vql");
-
- open(LOG_H323, $arquivo) or die "lendo arquivo $arquivo";
-
- foreach $line (<LOG_H323>) {
-
-
-
- if ($line =~ /(.*)RTP Jitter:.*Receive statistics:.*packets=(d*).*octets=(d*).*tooLate=(d*)/o ) {
-
- $status = "received";
- $time = ms (converte_para_Milisegundos($1));
- if ($status_old eq "received") {
-
- #print "n-> PACKET RECEIVED: $time_old -----------------------------------------n";
- receive_event();
-
-
- }
-
-
-
- }elsif ($line =~ /(.*)RTP Jitter:.*Droppeds(d*)s/o ){
-
- $status = "dropped";
- $time = ms (converte_para_Milisegundos($1));
- $dropped = $2;
-
- #Considera pacotes multiframe
- for ($i = 0; $i < $dropped ; $i++) {
-
- #print "n-> PACKET LOST: $time ---------------------------------------------n";
- loss_event();
-
-
- }
-
-
- }elsif ($line =~ /(.*)Jitter buffer oldest packet.*too late/o ){
-
- $status = "late";
- $time = ms (converte_para_Milisegundos($1));
-
- if ($status_old eq "received") {
-
- #print "n-> PACKET TOO LATE: $time_old ------------------------------------------n";
- loss_event();
-
-
-
- }
- # 2:33.566 RTP Jitter:80786e0 RTP Jitter buffer full, throwing away oldest frame (31920)
- }elsif ($line =~ /(.*)Jitter buffer full, throwing away oldest frame/o ){
-
- $status = "late";
- $time = ms (converte_para_Milisegundos($1));
-
- if ($status_old eq "received") {
-
- #print "n-> BUFFER FULL: $time_old ------------------------------------------n";
- loss_event();
-
- }
- }elsif($line =~ /(.*)SentReceiverReport:s*ssrc=(d*)s*fraction=(d*)s*lost=(d*)s*last_seq=(d*)s*jitter=(d*)s*lsr=(d*)s*dlsr=(d*)/o ) {
-
- $time = ms (converte_para_Milisegundos($1));
- if ($time == $time_emodel) {
-
- calcula_markov();
- $ta = onewaydelay($rtt,$CODEC,$buffer_size);
-
- VoIP::Emodel->setTa($ta);
- if ($psent != 0){
-
- VoIP::Emodel->setPpl(($plost + $too_late ) / $psent);
- }
- else {
-
- #Caso nenhum pacote tenha sido enviado
- VoIP::Emodel->setPpl(0);
- }
-
- #print ("Ppl: ",VoIP::Emodel->getPpl()," Bpl: ",VoIP::Emodel->getBpl(), " Ie: ",VoIP::Emodel->getIe(), "n");
- $r_emodel = VoIP::Emodel->r();
- $ie_emodel = VoIP::Emodel->getIeef();
- $id_emodel = VoIP::Emodel->getId();
- $mos_emodel = VoIP::Emodel->mos(VoIP::Emodel->r());
-
- $id_emodel_ext = $id_emodel; #ler o artigo outra vez para ajustar o valor de id
- $r_emodel_ext = $R - $id_emodel_ext;
-
- #print "$R $r_emodel_ext $id_emodel_extn";
-
- if ($r_emodel_ext < 0 ) {
- #nao deixa o r do emodel extendido ficar negativo
- $r_emodel_ext = 0;
- }
- #print LOG_VQL ($time_emodel," ",$ie_emodel," ",$id_emodel," ",$r_emodel," ",$mos_emodel," ",$IeTotal," ",$id_emodel_ext," ",$r_emodel_ext," ",VoIP::Emodel->mos($r_emodel_ext)," ",$I1," ",$I2," ",$Ieav,"n");
- print LOG_VQL ($time_emodel," ",$ie_emodel," ",$id_emodel," ",$r_emodel," ",$mos_emodel," ",$IeTotal," ",$id_emodel_ext," ",$r_emodel_ext," ",VoIP::Emodel->mos($r_emodel_ext),"n");
-
-
- ($time_emodel, $lixo, $psent, $plost, $too_late, $jitter, $buffer_size) = split(" ",shift(@emodel_array));
- # a variavel lixo eh utilizada para nao se atualizar o rtt
- # o owd eh calculado sempre em relacao ao primeiro rtt calculado
- # o que varia eh o tamaho do buffer de compensacao de jitter
-
- }
-
- }
-
- $status_old = $status;
- $time_old = $time;
-
-
-
- }
-
-
-
-
- # calculo do MOS final da ligacao
- $Ie_end = $Ieav + (0.7 * ($I1 - $Ieav)) * $e ** (-$y/30);
-
- #Verificar como adicionar Id no R final da ligacao
- $R = 93.36 - $Ie_end - $IeCODEC - $id_emodel_ext;
- #print "###########################################################n";
- #print "AVALIACAO FINAL DA LIGACAOn";
- #print "Ie(End of call) = $Ie_endn";
- #print "R-Factod(End of call) = $Rn";
- #print "MOS(End of call) = ", mos($R),"n";
- open (LOG_MOS, ">$log_mos");
- print LOG_MOS (VoIP::Emodel->mos($R),"n");
- close (LOG_MOS);
-
-
- close(LOG_H323);
- close(LOG_VQL);
-
- }
- sub receive_event {
- # evento de recepcao de pacote
- $pkt++;
-
- }
- sub loss_event {
- # evento de perda de pacote
- $c5 = $c5 + $pkt;
- if ($pkt >= $gmin) {
-
- if ($lost == 1) {
-
- $c14++;
- }
- else {
-
- $c13++;
- }
-
- $lost = 1;
- $c11 = $c11 + $pkt;
- }
- else {
-
-
- $lost++;
- if ($lost > 8) {
-
- $c5 = 0;
- }
- if( $pkt == 0) {
- $c33++;
-
- }
- else {
- $c23++;
- $c22 = $c22 + $pkt;
- }
-
-
-
- }
- $pkt = 0;
-
- }
- sub calcula_markov {
- $c31 = $c13;
- $c32 = $c23;
- if ( ($c11 + $c14 + $c13) == 0 ) {
-
- $p11 = 0;
- $p13 = 0;
- }
- else {
- $p11 = ( $c11 + $c14 ) / ( $c11 + $c14 + $c13);
- $p13 = $c13 / ( $c11 + $c14 + $c13);
- }
-
- #$p13 = 1 - $p11;
-
-
- if ( ( $c31 + $c32 + $c33) ==0 ) {
-
- $p31 = 0;
- $p32 = 0;
- $p33 = 0;
-
- }
- else {
-
- $p31 = $c31 / ( $c31 + $c32 + $c33);
- $p32 = $c32 / ( $c31 + $c32 + $c33);
-
- #$p33 = 1 - $p31 - $p32;
- $p33 = $c33 / ( $c31 + $c32 + $c33);
- }
-
-
- if ( ($c22 + $c23) == 0 ) {
- $p22 = 0;
- $p23 = 0;
- } else {
- $p22 = $c22 / ( $c22 + $c23 );
- $p23 = $c23 / ( $c22 + $c23 );
- }
-
- #$p23 = 1- $p22;
-
-
- $d = ($p23 * $p31 + $p13 * $p32 + $p13 * $p23);
-
- if ($d == 0) {
- $p1 = 0;
- $p2 = 0;
- $p3 = 0;
- }
- else {
- $p1 = ($p31 * $p23) / $d;
- $p2 = ($p13 * $p32) / $d;
- $p3 = ($p13 * $p23) / $d;
- }
-
-
-
-
- $L = 100 * $p3; # porcentagem media da taxa de pacotes perdidos
-
- $y = $F * $c5; # tempo passado desde o ultimo burst significativo de perdas em segundos
-
- if ( $p11 == 1) {
- # significa que nao apareceu burst
-
- $g = $y;
-
- }else{
-
- $g = $F / ( 1 - $p11); # tamanho do gap em segundos
- }
-
- if ($c11 == 0) {
- $Dg = 0;
- }
- else {
-
- $Dg = 100 * $c14 / ( $c11 + $c14); #densidade de perda no gap (porcentagem)
- }
-
- if ( ($p1 * $p13) == 0 ) {
- $b = 0;
- }
- else {
- $b = ( $F * (1 - $p1) ) / ( $p1 * $p13); # tamanho do burst em segundos
- }
-
- if ( ($p23 + $p32) == 0 ) {
-
- $Db = 0;
- }
- else {
-
- $Db = 100 * $p23 / ($p23 + $p32); # densidade de perda no burs (porcentagem)
- }
- # Ao meu ver, esta forma de calcular Db estah errada
- #$Db = 100 * $p23;
-
-
-
- #print "Average packet loss rate = $L %n";
- #print "Gap Length = $g seg.n";
- #print "Gap loss density = $Dg %n";
- #print "Burst length = $b seg.n";
- #print "Burst loss density = $Db %n";
- #print "Delay since last burst = $y seg.n";
-
- # if ($Dg < 0.5) {
- #
- # $Ieg = 0;
- #
- # }
- # elsif ( (0.5 < $Dg) && ($Dg < $d2) ) {
- #
- # $Ieg = $d1 * $Dg;
- #
- # }
- # elsif ($d2 < $Dg) {
- #
- # $Ieg = $d3 + $d4 * $Dg;
- #
- # }
- #
- # if ($Db < 0.5) {
- #
- # $Ieb = 0;
- #
- # }
- # elsif ( (0.5 < $Db) && ($Db < $d2) ) {
- #
- #
- # $Ieb = $d1 * $Db;
- # }
- # elsif ($d2 < $Db) {
- #
- #
- # $Ieb = $d3 + $d4 * $Db;
- # }
- #
- VoIP::Emodel->setPpl($Dg/100);
- VoIP::Emodel->r();
- $Ieg = VoIP::Emodel->getIeef();
- VoIP::Emodel->setPpl($Db/100);
- VoIP::Emodel->r();
- $Ieb = VoIP::Emodel->getIeef();
- #print "Dg = $Dgn";
- #print "Db = $Dbn";
-
- #print "Ieg = $Iegn";
- #print "Ieb = $Iebn";
-
- if ( (1 - $e ** (-$b/$t1 - $g/$t2)) == 0) {
- $I2 = 0;
-
- }
- else {
-
- $I2 = ( $Ieg * ( 1 - $e ** (-$g /$t2)) + $Ieb * ( 1 - $e** (-$b/$t1)) * $e ** (-$g/$t2)) / (1 - $e ** (-$b/$t1 - $g/$t2) );
-
- }
-
- #$I1 = $Ieb - ($Ieg - $I2) * $e ** (-$b/$t1);
- $I1 = $Ieb - ($Ieb - $I2) * $e ** (-$b/$t1); # Our considerations
-
- $Ieav = ($b * $Ieb + $g * $Ieg - $t1 * ($Ieb - $I2) * (1 - $e ** (-$b/$t1)) + $t2 * ($I1 - $Ieg) * (1 - $e ** (- $g/$t2)) ) / ($b + $g);
-
-
-
- #print "I1 = $I1n";
- #print "I2 = $I2n";
- #print "g = $gn";
- #print "b = $bn";
- #print "Ie(av) = $Ieavn";
- $R = 94 - $Ieav - $IeCODEC;
- $IeTotal = $Ieav + $IeCODEC;
- if ($IeTotal > 100) {
- #nao deixa o ietotal ser negativo
- $IeTotal = 100;
- }
-
- #print "R-factior = $Rn";
- #print "MOS = ", mos($R)," at $time n";
-
-
-
- }
- sub onewaydelay
- #Parametros (rtt, codec, playoutbuffer)
- #Calcula o On Way Delay, tambe'm chamado de Absolute Delay (Ta).
- #Ta = RTT/2 + tempo de codificacao (dependente do codec utilizado) + tempo de playout buffer (fixo)
- {
- my $rtt = shift;
- my $codec = shift;
- my $plbuffer = shift;
- my $codec_time = 0;
-
- #confirmar tempo de codificacao
-
- $plbuffer = $plbuffer/2; #codecao do dejitter_buffer como max_time/2
-
- if ($codec eq "G711") { $codec_time = 0.25}
- elsif ($codec eq "GSM") { $codec_time = 40}
- elsif ($codec eq "G729") { $codec_time = 25}
- elsif ($codec eq "G723") { $codec_time = 157.5} #4 frames por pacote no caso do openam # ver g.114
- #considerando link de alta velocidade (melhor caso)
- #elsif ($codec eq "G723") { $codec_time = 277.5} #4 frames por pacote no caso do openam # ver g.114
- #considerando link de baixa velocidade (pior caso)
- #$a = ($rtt/2) + $plbuffer + $codec_time;
- #print "rtt= $rtt, buffer= $plbuffer, codec= $codec_time, total= $an";
- return ($rtt/2) + $plbuffer + $codec_time;
- }