Formação de software de multisessão Adobe Audition com gravações de áudio de chamadas telefônicas

No artigo anterior, escrevi sobre a geração de gráficos vetoriais SVG com um diagrama de chamada telefônica semelhante a um gráfico de Gantt. Peguei informações sobre ligações dos detalhes, que baixei de minha conta no site da operadora de celular. Faz quase quatro anos. Atualmente, tenho uma ideia para complicar ainda mais o projeto: construir uma multissessão no editor de som Adobe Audition 1.5 a partir de gravações de áudio de conversas telefônicas. Ao mesmo tempo, coloque essas gravações de áudio na multissessão estritamente de acordo com o tempo, bem como as datas a que as faixas corresponderão. Ao mesmo tempo, visualmente, essa multissessão se parecerá com o mesmo diagrama que foi criado no artigo anterior. Além disso, será possível dimensionar e ouvir rapidamente as gravações de conversas telefônicas, tanto no modo "mix" quanto no modo "solo" durante o dia.



Decidi construir a multissessão a partir de gravações de áudio acumuladas ao longo de um mês para evitar confusão desnecessária para o Adobe Audition. Claro, essa sessão pode ser construída manualmente, mas é um trabalho longo e trabalhoso. O principal interesse desta tarefa é automatizar a construção de uma multissessão por software. Mais precisamente, escreva um programa que, com base na lista de arquivos de gravação de áudio, formará um arquivo SES da multissessão Adobe Audition. Para quem não sabe: uma multissessão, em suma, é um projeto que consiste em muitas gravações de áudio diferentes distribuídas no tempo e por faixas (faixas) e projetado para criar uma mixagem a partir delas.



Em primeiro lugar, vale a pena discutir como obtenho as gravações de áudio de conversas telefônicas. Não é segredo que os smartphones modernos têm a capacidade de gravar chamadas telefônicas com várias ferramentas, tanto integradas ao sistema quanto de terceiros. Pessoalmente, eu uso um tablet Lenovo TAB3 (com processador MT8735P). O aparelho permite fazer gravações de áudio em modo manual em formato comprimido, recebendo arquivos com a extensão 3gpp. As gravações são obtidas em estéreo com canais separados: a voz do assinante é gravada em um canal e a própria voz no outro. O formato compactado das gravações de áudio afeta sua distorção durante a reprodução. Por isso, uso aplicativos de gravação de áudio de terceiros, dos quais existem inúmeros. Um dos aplicativos que mais gostei é o “Grave Minha Chamada”.Esta aplicação grava chamadas em modo automático, possui várias configurações relacionadas, nomeadamente, à escolha do formato e qualidade da gravação de áudio. E também, como um bônus, o aplicativo tem um registro de chamadas embutido muito conveniente, que é salvo no arquivo de banco de dados db (Fig. 1).





Figura: 1. Registro de chamadas no aplicativo "Gravar minha chamada".



Os melhores parâmetros de gravação de áudio para qualidade de som são WAV 8000Hz 16bit Stereo. Com essas configurações, a gravação não tem distorções, soa clara, embora ocupe mais espaço na memória. A aplicação está configurada para que a gravação de áudio comece automaticamente antes mesmo do início da conversa telefónica: quando chega uma chamada antes de “atender” ou quando disca um número durante o toque. Ou seja, as chamadas perdidas e não atendidas também são gravadas. Pode ser configurado para gravar apenas a conversa. O formato do nome do arquivo de gravação de áudio também é configurável. No meu caso, configurei-o conforme mostrado na Figura 2.





Fig. 2. Definir o formato do nome do arquivo em “Gravar minha chamada”.



Durante o desenvolvimento do programa de geração multissessão, será necessário levar informações sobre a data e hora da gravação do áudio da ligação. Essas informações serão obtidas do nome do arquivo em posições fixas.



Antes de começar a criar um arquivo SES multissessão, você precisa entender como esse arquivo funciona. Claro, não há documentação sobre este formato em lugar nenhum, então eu tive que resolver sozinho, contando com minha experiência e conhecimento pessoal. Este arquivo não é um arquivo de texto, então não faz muito sentido abri-lo no Bloco de Notas. "WinHex" - um editor hexadecimal vem ao resgate. Já escrevi vários artigos sobre como trabalhar com dados binários e informações de descriptografia, em particular, um artigo sobre como escrever um programa de reembalagem de vídeo 264-avi. Lá escrevi mais ou menos detalhes sobre o dispositivo do arquivo avi.



Primeiro, criei uma multissessão arbitrária simples no Adobe Audition 1.5, consistindo em uma trilha e um arquivo de áudio (Fig. 3), salvando-o em um arquivo com a extensão ses. O tamanho do arquivo é de 2422 bytes. Em seguida, abri este arquivo no WinHex (Fig. 4).





Figura: 3. Visualização de multissessão no Adobe Audition 1.5 - Exemplo 1.





Fig. 4. Arquivo multissessão aberto no WinHex.



À primeira vista, nada está claro. Na parte simbólica da janela, você pode ver as palavras semânticas "COOLNESS", "hdr", "Master". Se você percorrer o documento abaixo, poderá ver o texto que contém o caminho completo para o arquivo (e, em duas versões), que é usado na multissessão. Isso é mostrado na Figura 5 e destacado em verde. Imediatamente impressionantes são palavras semânticas curtas circuladas em uma moldura vermelha na mesma figura.





Figura: 5. Bytes de caminhos para arquivos de áudio multissessão.



Olhando mais de perto este documento do início ao fim, percebi algumas outras palavras semânticas curtas. Também percebi que o comprimento de qualquer palavra significativa é um múltiplo de quatro. Aparentemente, essas palavras são os cabeçalhos dos blocos que compõem todo o arquivo multissessão. Isso me lembrou da estrutura RIFF de um arquivo avi ou wav que consiste em blocos que também têm cabeçalhos do mesmo tamanho. Esses cabeçalhos foram seguidos por um número de 32 bits (4 bytes) indicando o tamanho do bloco atual. Com esse fato em mente, resolvi verificar se esse princípio funciona para o arquivo ses? Descobriu-se que, no caso do formato ses, também funciona (fig. 6).





Figura: 6. Similaridade com a estrutura RIFF (por exemplo, o bloco "WLST").



A primeira palavra "COOLNESS" no arquivo ses parece ser o cabeçalho principal e o tipo deste arquivo. Os próximos 4 bytes são o tamanho do conteúdo, que é colocado a seguir, até o final do arquivo. Ou seja, se você calcular com cuidado, esse valor é 12 bytes menor que o tamanho de todo o arquivo. E o conteúdo adicional consiste em uma coleção de blocos diferentes. O bloco tem um cabeçalho de quatro ou oito bytes, seguidos de 4 bytes indicando o tamanho deste bloco, e após eles segue o conteúdo deste bloco. Em alguns blocos, identifiquei a presença de subblocos, mas isso será discutido no decorrer de uma descrição mais detalhada de cada bloco. Nesse arquivo, que no exemplo contei 17 blocos, eles estão listados na tabela da Figura 7. A





Fig. 7. Lista dos blocos que compõem a multissessão.



Como você pode ver na tabela, algumas das mesmas informações são apresentadas em diferentes versões por diferentes blocos. Isso provavelmente é feito para a compatibilidade de diferentes versões do programa. Olhando para o futuro, esses blocos são destacados em verde, sem os quais a multissessão apresentada no exemplo não pode existir. Dois blocos de 4 bytes são destacados em cinza, que são fictícios nesta sessão. Na verdade, eu tinha uma pergunta: o que acontecerá se você excluir alguns dos blocos do arquivo? Afinal, eu, por exemplo, não preciso de informações sobre o metrônomo e o tempo, e os envelopes nos clipes (mais precisamente, em um clipe) estão faltando em meu exemplo simples. Envelopes são curvas no topo de um clipe de áudio que definem a dinâmica dos parâmetros de som (volume, equilíbrio) ao longo do tempo. Eu comecei a cortar blocos sequencialmente do arquivo fornecido,não esquecendo de recalcular e corrigir o valor após a palavra "COOLNESS". Como resultado, a multissessão foi aberta com sucesso com pelo menos cinco blocos destacados em verde. A sessão contém dois blocos da lista de arquivos de áudio. Qualquer um deles pode ser deixado. Eu prefiro a segunda opção (o bloco "LISTFILE"), pois na primeira opção (o bloco "WLST") existem dois bytes por caractere na descrição do caminho do arquivo. Isso pode ter sido feito para um alfabeto de caracteres estendido, mas o alfabeto ASCII padrão é suficiente para mim. Além disso, os caracteres russos, como você pode ver, são bem suportados. A descrição dos clipes de áudio é apresentada em três versões. Escolhi a primeira opção (bloco "bk20"), pois descobri a descrição mais rápido.A sessão contém dois blocos da lista de arquivos de áudio. Qualquer um deles pode ser deixado. Eu prefiro a segunda opção (o bloco "LISTFILE"), pois na primeira opção (o bloco "WLST") existem dois bytes por caractere na descrição do caminho do arquivo. Isso pode ter sido feito para o alfabeto de caracteres estendido, mas o alfabeto ASCII padrão é suficiente para mim. Além disso, os caracteres russos, como você pode ver, são bem suportados. A descrição dos clipes de áudio é apresentada em três versões. Escolhi a primeira opção (bloco "bk20"), pois descobri a descrição mais rápido.A sessão contém dois blocos da lista de arquivos de áudio. Qualquer um deles pode ser deixado. Eu prefiro a segunda opção (o bloco "LISTFILE"), pois na primeira opção (o bloco "WLST") existem dois bytes por caractere na descrição do caminho do arquivo. Isso pode ter sido feito para um alfabeto de caracteres estendido, mas o alfabeto ASCII padrão é suficiente para mim. Além disso, os caracteres russos, como você pode ver, são bem suportados. As descrições dos clipes de áudio são apresentadas em três versões. Escolhi a primeira opção (bloco "bk20"), pois descobri sua descrição o mais rápido.mas o alfabeto ASCII padrão é suficiente para mim. Além disso, os caracteres russos, como você pode ver, são bem suportados. As descrições dos clipes de áudio são apresentadas em três versões. Escolhi a primeira opção (bloco "bk20"), pois descobri a descrição mais rápido.mas o alfabeto ASCII padrão é suficiente para mim. Além disso, os caracteres russos, como você pode ver, são bem suportados. As descrições dos clipes de áudio são apresentadas em três versões. Escolhi a primeira opção (bloco "bk20"), pois descobri sua descrição o mais rápido.



Uma multissessão de gravações de áudio de conversas telefônicas será semelhante em complexidade à multissessão apresentada neste exemplo. A única diferença é que será mais volumoso: o número de arquivos de áudio será bem grande e o número de faixas será igual ao número de dias de um mês. Para tal multisessão, nenhum outro "sinos e assobios" são necessários. Os tamanhos de bloco "hdr" e "stat" são estáticos e sempre têm 936 e 40 bytes, respectivamente, independentemente do tamanho da multissessão. Os tamanhos dos blocos "trks" e "bk20" dependem do número de trilhas e clipes de áudio na multissessão, respectivamente. Mas o tamanho do bloco "LISTFILE" é o mais imprevisível: ele depende não apenas do número de arquivos de áudio em uma multissessão, mas também do comprimento de seus nomes e caminhos de localização.



Decifrar e compor uma descrição completa dos blocos de um arquivo multissessão é uma tarefa bastante demorada. Portanto, decodifiquei parcialmente a informação, prestando atenção apenas às seções de bytes que devem ser levadas em consideração ao formar uma multissessão de conteúdo simplificado. Neste artigo, descreverei o conteúdo de cada bloco que consegui decifrar.



No conteúdo do bloco de cabeçalho multissessão "hdr" (há um espaço no final), os bytes da chave são os primeiros 12 bytes, ou seja, 3 palavras de 4 bytes cada (Fig. 8). A primeira palavra é a taxa de amostragem de amostras em uma multissessão. Para minha multissessão, esse valor é 8000 Hz (0x1F40). Na Figura 8, ele é destacado com preenchimento em verde. Deixe-me lembrá-lo de que os bytes em palavras para valores numéricos são lidos de trás para frente. A segunda palavra é a duração (comprimento) da multissessão, expressa no número de amostras (preenchimento em laranja na figura). Neste exemplo, esse valor é 0x1A365E (1717854). Se traduzido em minutos, você obtém 1717854/8000/60, que é aproximadamente três minutos e meio. E assim é: em uma escala mínima, uma multissessão tem exatamente essa duração.E para uma multissessão de registros de chamadas telefônicas, a duração deve ser de 24 * 3600 * 8000 = 691200000 = 0x2932E000 amostras. Nesta situação, aliás, o tempo atual de playback da multissessão no painel abaixo, que é um tempo relativo, vai coincidir exatamente com o valor do tempo absoluto da ligação atual (ou grupo de ligações por dia). A próxima palavra destacada em amarelo indica o número de clipes de áudio na multissessão. No exemplo, esse valor é igual a um, mas no caso de ligações, a quantidade de clipes será igual à quantidade de arquivos de áudio. Olhando para o futuro, a última afirmação não está totalmente correta. Na verdade, o número de clipes de áudio pode ser um pouco maior do que o número de arquivos de áudio. Um arquivo pode ter dois clipes no caso dese um novo dia chegou durante uma conversa telefônica. Nesse caso, você terá que "transferir" a gravação para uma nova trilha, e um clipe não funcionará. Mas esses casos são raros na prática, já que a transição para um novo dia ocorre à noite, quando a atividade de ligações telefônicas é mínima. A propósito, não levei esse ponto em consideração ao formar o diagrama SVG no artigo anterior. Depois da palavra do valor do número de blocos segue, muito provavelmente, uma "meia palavra" de dois bytes 0x0020, ou 32 em forma decimal. Também pode ser destacado com um preenchimento de cor, já que, provavelmente, significa a profundidade de bits da mistura. No Adobe Audition, a barra de status na parte inferior diz: 8000 Hz, mixagem de 32 bits. Além das três palavras mais essenciais do conteúdo "hdr", existem outros bytes obscuros. Por exemplo, eu nem sei a palavra "Mestre"a que se refere. Aparentemente, esse é o nome do barramento de mixagem principal. Mas os grupos de bytes mais interessantes circulei em um quadro cinza. O fato é que essa sequência é freqüentemente encontrada em outros blocos do arquivo multissessão. Não é por acaso que combinei exatamente 8 bytes em um grupo, já que, muito provavelmente, este é um tipo de dados real. Em particular, esta constante "00 00 00 00 00 00 F0 3F" HEX pelo editor no tipo Double é interpretada como 1.0e + 0, ou seja, como uma unidade. Muito provavelmente, esses são os valores dos níveis de volume e outras "variações", mas especificados não em decibéis, mas na forma de um coeficiente. Devo dizer desde já que todos os bytes de qualquer bloco que não pude reconhecer (ou não foram necessários) serão gravados no arquivo multisessão gerado sem alterações, como no exemplo.Mas os grupos de bytes mais interessantes circulei em um quadro cinza. O fato é que essa sequência é freqüentemente encontrada em outros blocos do arquivo multissessão. Não é por acaso que combinei exatamente 8 bytes em um grupo, já que, muito provavelmente, este é um tipo de dados real. Em particular, esta constante "00 00 00 00 00 00 F0 3F" HEX pelo editor no tipo Double é interpretada como 1.0e + 0, ou seja, como uma unidade. Muito provavelmente, esses são os valores dos níveis de volume e outras "variações", mas especificados não em decibéis, mas na forma de um coeficiente. Devo dizer desde já que todos os bytes de qualquer bloco que não pude reconhecer (ou não foram necessários) serão gravados no arquivo multisessão gerado sem alterações, como no exemplo.Mas os grupos de bytes mais interessantes circulei em um quadro cinza. O fato é que essa sequência é freqüentemente encontrada em outros blocos do arquivo multissessão. Não é por acaso que combinei exatamente 8 bytes em um grupo, já que, muito provavelmente, este é um tipo de dados real. Em particular, esta constante "00 00 00 00 00 00 F0 3F" HEX pelo editor no tipo Double é interpretada como 1.0e + 0, ou seja, como uma unidade. Muito provavelmente, esses são os valores dos níveis de volume e outras "variações", mas especificados não em decibéis, mas na forma de um coeficiente. Devo dizer desde já que todos os bytes de qualquer bloco que não pude reconhecer (ou não foram necessários) serão gravados no arquivo multisessão gerado sem alterações, como no exemplo.Não é por acaso que combinei exatamente 8 bytes em um grupo, já que, provavelmente, este é um tipo de dados real. Em particular, esta constante "00 00 00 00 00 00 F0 3F" HEX pelo editor no tipo Double é interpretada como 1.0e + 0, ou seja, como uma unidade. Muito provavelmente, esses são os valores dos níveis de volume e outras "variações", mas especificados não em decibéis, mas na forma de um coeficiente. Devo dizer desde já que todos os bytes de qualquer bloco que não pude reconhecer (ou não foi necessário) serão gravados no arquivo multisessão gerado sem alterações, como no exemplo.Não é por acaso que combinei exatamente 8 bytes em um grupo, já que, muito provavelmente, este é um tipo de dados real. Em particular, esta constante "00 00 00 00 00 00 F0 3F" HEX pelo editor no tipo Double é interpretada como 1.0e + 0, ou seja, como uma unidade. Muito provavelmente, esses são os valores dos níveis de volume e outras "variações", mas especificados não em decibéis, mas na forma de um coeficiente. Devo dizer desde já que todos os bytes de qualquer bloco que não pude reconhecer (ou não foram necessários) serão gravados no arquivo multisessão gerado sem alterações, como no exemplo.e como um coeficiente. Devo dizer desde já que todos os bytes de qualquer bloco que não pude reconhecer (ou não foram necessários) serão gravados no arquivo multisessão gerado sem alterações, como no exemplo.e como um coeficiente. Devo dizer desde já que todos os bytes de qualquer bloco que não pude reconhecer (ou não foram necessários) serão gravados no arquivo multisessão gerado sem alterações, como no exemplo.





. 8. «hdr ».



Decidi não estudar o bloco "stat" do estado multissessão atual (o mais curto). Criei outra amostra multissessão a partir de um arquivo de áudio, estiquei-a por 24 horas e fiz sua visualização completa (escala) horizontalmente. E verticalmente, a visualização das trilhas foi dimensionada para que, quando a janela do Adobe Audition fosse expandida, 31 trilhas coubessem na tela FullHD. Este é o número máximo de dias em um mês. O cursor multissessão foi posicionado bem no início. Em seguida, salvei essa multissessão em outro arquivo e retirei o bloco "stat" com todos os seus cabeçalhos. Salvei esses bytes no arquivo "stat_31_full.BLK" para uso posterior no desenvolvimento do programa. A visualização do conteúdo desse arquivo é mostrada na Figura 9. O tamanho deste arquivo era de 48 bytes (40 bytes do conteúdo do bloco + 4 bytes do cabeçalho + 4 bytes da descrição do tamanho do conteúdo).





. 9. «stat» .



Para uma descrição mais visual dos próximos três blocos no decorrer da redação deste artigo, decidi criar uma multissessão mais complexa, consistindo em duas trilhas, dois arquivos e três clipes (Fig. 10). O primeiro arquivo "Incoming_Call - 20200622_124844 - + 74999545237.wav" tem uma duração de 281280 amostras. O segundo arquivo "Outgoing_Call - 20200621_231753 - + 79536170218.wav" tem uma duração de 63360 amostras. A primeira faixa chamada "First" (renomeada) contém dois clipes. O primeiro clipe é deslocado desde o início da sessão em 10 segundos (em 80.000 amostras). O clipe é representado pelo conteúdo completo do primeiro arquivo de áudio, ou seja, a duração do clipe é igual à duração do arquivo. O segundo clipe é deslocado em 50 segundos desde o início da sessão (em 50 * 8000 = 400000 amostras). O clipe é representado pelo conteúdo incompleto do segundo arquivo de áudio. Dentro de um determinado clipe, o áudio começa do início do arquivo,mas dura apenas 5 segundos (40.000 amostras). Ou seja, a duração do clipe é de 5 segundos. A segunda faixa chamada “Second” contém um clipe. É deslocado desde o início da sessão em um segundo (em 8.000 amostras). Este clipe é representado pelo conteúdo incompleto do primeiro arquivo de áudio. Nesse clipe, o áudio não começa do início, mas após 3 segundos, mas o contém até o final. Portanto, o deslocamento dos dados de áudio neste clipe é de 3 segundos (24.000 amostras). E a duração de um determinado clipe é calculada como a diferença entre a duração do áudio correspondente e o deslocamento dos dados de áudio dentro do clipe. Nesse caso, a duração do clipe é 281280-24000 = 257280 amostras.Este clipe é representado pelo conteúdo incompleto do primeiro arquivo de áudio. Nesse clipe, o áudio não começa do início, mas após 3 segundos, mas o contém até o fim. Portanto, o deslocamento dos dados de áudio neste clipe é de 3 segundos (24.000 amostras). E a duração de um determinado clipe é calculada como a diferença entre a duração do áudio correspondente e o deslocamento dos dados de áudio dentro do clipe. Nesse caso, a duração do clipe é 281280-24000 = 257280 amostras.Este clipe é representado pelo conteúdo incompleto do primeiro arquivo de áudio. Nesse clipe, o áudio não começa do início, mas após 3 segundos, mas o contém até o fim. Portanto, o deslocamento dos dados de áudio neste clipe é de 3 segundos (24.000 amostras). E a duração de um determinado clipe é calculada como a diferença entre a duração do áudio correspondente e o deslocamento dos dados de áudio dentro do clipe. Nesse caso, a duração do clipe é 281280-24000 = 257280 amostras.Nesse caso, a duração do clipe é 281280-24000 = 257280 amostras.Nesse caso, a duração do clipe é 281280-24000 = 257280 amostras.





. 10. Adobe Audition 1.5 — 2.



A Figura 11 mostra o conteúdo do bloco de descrição da trilha "trks". 4 bytes do cabeçalho do bloco são destacados no quadro vermelho, o tamanho do conteúdo do bloco está no verde. Isso já foi discutido acima. Em seguida, vem o conteúdo do bloco, cujos bytes são destacados no editor WinHex com um preenchimento azulado característico. O tamanho da seleção, cujo valor é mostrado no canto inferior direito do editor (também circulado em verde), coincide com o valor dos bytes após o cabeçalho, e já neste exemplo é 308 bytes. Se no primeiro (anterior) exemplo de uma trilha o tamanho do bloco era de 156 bytes, e no atual - 308 bytes, então a seguinte conclusão pode ser tirada. Devido ao pressuposto de homogeneidade e equivalência das pistas, as áreas de descrição de cada pista devem ter o mesmo tamanho. Essas áreas, por assim dizer, são sub-blocos do bloco "trks".Eles estão destacados em azul na figura. Descobriu-se que o tamanho de um desses sub-blocos é de 152 bytes. E logo no início dos sub-blocos consecutivos há um subtítulo de quatro bytes, marcado na figura com preenchimento amarelo. Esses quatro bytes nada mais são do que o valor do número de trilhas em uma multissessão ou o número de sub-blocos. E assim, o tamanho S do conteúdo do bloco "trks" pode ser calculado pela fórmula S = 4 + 152 * n, onde n é o número de trilhas na sessão. Assim é: 4 + 152 * 1 = 156 e 4 + 152 * 2 = 308.o tamanho S do conteúdo do bloco "trks" pode ser calculado pela fórmula S = 4 + 152 * n, onde n é o número de faixas na sessão. Assim é: 4 + 152 * 1 = 156 e 4 + 152 * 2 = 308.o tamanho S do conteúdo do bloco "trks" pode ser calculado pela fórmula S = 4 + 152 * n, onde n é o número de faixas na sessão. Assim é: 4 + 152 * 1 = 156 e 4 + 152 * 2 = 308.





. 11. «trks».



Agora vamos descrever o conteúdo do sub-bloco. Há muita coisa aí, mas decifrei apenas o mais essencial. Existem apenas três parâmetros: 4 bytes de sinalizadores binários (circulados em vermelho), nome da trilha (circulado em marrom) e ID da trilha (circulado em azul). O identificador da trilha é o seu número de sequência. É necessário indicar um link para uma trilha na descrição dos clipes de áudio (mais sobre isso mais tarde). O nome da trilha ocupa uma área de 36 bytes. Este é o número máximo de caracteres no nome da faixa, mas pode ser menor, como no exemplo atual. Os bytes não utilizados são zero. Em uma multissessão com gravações de áudio de chamadas telefônicas, os nomes das faixas corresponderão à gravação das datas correspondentes. Você pode adicionar o dia da semana correspondente ao lado da data em duas letras maiúsculas de forma abreviada.Quatro bytes de sinalizadores binários (32 sinalizadores no total) destinam-se a descrever os parâmetros binários inerentes à trilha. Na verdade, pode haver menos de 32. Eu decodifiquei apenas parte das bandeiras. Destes, pelo menos três bandeiras indicam se a faixa é “R” (Registro), “S” (Solo) ou “M” (Mudo). No exemplo fornecido, nenhum desses três botões nas trilhas é pressionado e o valor dos sinalizadores binários é zero (0x00000000). Mas se você pressionar o botão "R" na trilha (ou seja, colocar a trilha no registro) e salvar novamente a sessão, o valor dos sinalizadores binários se tornará 0x00000004, em outras palavras, o terceiro bit da direita (bit2) se tornará único. É esse bit o responsável pela propriedade de "registro" da trilha. Esta propriedade não tem significado em meu projeto, já que minha multissessão foi projetada para visualização e reprodução visual.Porém, pensei que o botão "R" foi pressionado nas faixas que correspondem ao fim de semana. Esta técnica facilitará a visualização da multissessão.



O bloco da lista de arquivos de áudio da multissessão "LISTFILE" (Fig. 12) é composto pelas seguintes partes. Como no caso do bloco de descrição da faixa, ele também pode ser dividido em sub-blocos de acordo com o número de arquivos da sessão. Semelhante à Figura 11, também destaquei o cabeçalho do bloco de 8 bytes em uma caixa vermelha e o tamanho de seu conteúdo em uma caixa verde. Neste exemplo específico, esse valor é 188 bytes. O conteúdo é destacado por analogia com a Fig. 11. Está dividido em duas zonas destacadas com uma linha azul. Estes são os sub-blocos do bloco da lista de arquivos.





Figura: 12. Bytes do bloco de descrição dos arquivos de áudio "LISTFILE".



Cada sub-bloco corresponde a um arquivo de áudio. O exemplo usa dois arquivos de áudio, portanto, o número de sub-blocos é apropriado. Em contraste com o caso anterior com descrições de faixas, não há subtítulo sobre o número de sub-blocos. O sub-bloco contém 4 bytes de seu cabeçalho "wav" (destacado em preto) e 4 bytes indicando o tamanho do conteúdo adicional (destacado em magenta). Para ambos os sub-blocos, este valor é o mesmo neste exemplo e é 0x56 (86) bytes. Isso ocorre porque os arquivos estão localizados no mesmo caminho e possuem o mesmo nome. Mais precisamente, os nomes de arquivo totalmente qualificados têm o mesmo número de caracteres. Caso contrário, as subunidades teriam tamanhos diferentes. A área de conteúdo do sub-bloco (bytes adicionais) contém as seguintes informações. Um número que identifica um arquivo de áudio é destacado em uma moldura azul.Ao contrário do ID da faixa, este número não é um número de sequência de arquivo. Pelo que entendi, ao salvar uma multissessão, ela é atribuída aleatoriamente ou pseudo-aleatoriamente para cada arquivo. O principal é que não há coincidência entre esses valores. Fiquei convencido disso quando salvei a multissessão duas vezes e comparei os arquivos ses por conteúdo. Como resultado, descobriu-se que os arquivos diferem por esses bytes. E não só isso. Um número aleatório também é atribuído ao ID das camadas do envelope no bloco “ep20”. Mas neste bloco, como mencionado acima, não há necessidade de forma alguma, e sua descrição não será considerada neste artigo. IDs de áudio são necessários para vinculá-los aos clipes. Este link ocorre no bloco com a descrição dos clipes.No meu caso, para uma multissessão com registros telefônicos, os identificadores dos arquivos de áudio serão uma sequência de números naturais, mas começando não de zero, mas, por exemplo, de 1000. Os próximos 4 bytes, que não destaquei, em ambos os sub-blocos têm o valor 0x13. Provavelmente, este valor indica o tipo de formato de arquivo de áudio. Você pode considerar este valor condicionalmente uma constante, uma vez que todos os meus arquivos de áudio são do mesmo tipo. A sequência de bytes a seguir descreve o nome completo do arquivo de áudio, com um terminador nulo (como um terminador de linha). O tamanho desta cadeia é mais um que o número de caracteres no nome completo do arquivo de áudio. Em seguida, vem a constante 0xFFFFFFFF. Ele é seguido por um valor que indica o número de amostras neste arquivo de áudio (na Fig. 12 destacado em um quadro amarelo). Para o primeiro arquivo, esse valor é 0x44AC0 e, para o segundo, é 0xF780.Eles correspondem apenas aos valores decimais 281280 e 63360, respectivamente, que já apareceram acima na descrição do segundo exemplo de multissessão.



Finalmente, resta considerar a descrição do bloco mais difícil - o bloco para descrever clipes de áudio "bk20" (Fig. 13). Por analogia com as duas figuras anteriores, o título e o tamanho do conteúdo do bloco são destacados.





Figura: 13. Bytes do bloco de descrição dos clipes de áudio "bk20".



No conteúdo do bloco, em primeiro lugar, existem dois subtítulos de 4 bytes cada. Eles são realçados com preenchimentos em magenta e ciano. A primeira legenda é o número de clipes da sessão. Existem três deles no exemplo. O segundo subtítulo é a constante 0x48 (72). Aparentemente, indica o tamanho de cada sub-bloco, e eles vão além. Seu número coincide com o número de clipes na sessão. Cada um desses sub-blocos descreve os parâmetros de um clipe. A propósito, o tamanho D do conteúdo do bloco “bk20”, ao que parece, pode ser calculado pela fórmula D = 8 + 72 * b, onde b é o número de clipes de áudio em uma multissessão. Na figura, não há alocações de bytes explicativas dentro dos subblocos, uma vez que existem muitos parâmetros necessários. Eles estão listados em uma tabela separada (Fig. 14). O preenchimento azul marca os parâmetros que são necessários em meu projeto, e o preenchimento cinza - constantes não reconhecidas.Esta tabela também mostra os valores dos parâmetros para cada um dos três clipes multissessão do último exemplo.





. 14. .



A primeira palavra (grupo de 4 bytes) é uma referência ao envelope, de que não precisamos. O segundo parâmetro é um link para o arquivo de áudio. O valor deste parâmetro é igual ao valor do identificador do arquivo de áudio ao qual este clipe de áudio corresponde. Depois, há duas constantes reais, que já apareceram antes. Eles são seguidos por três parâmetros de coordenação expressos no número de amostras: o deslocamento do clipe desde o início da sessão, a duração (duração) do clipe na sessão e o deslocamento do áudio dentro do clipe. Tudo deve ficar claro a partir dos nomes desses parâmetros. Um pouco antes, ao descrever em detalhes o segundo exemplo de uma multissessão, indiquei os valores numéricos de todos os deslocamentos e durações. Na Figura 14, a tabela lista os parâmetros de cada clipe em formato hexadecimal. Insirai esses valores na tabela reescrevendo-os diretamente da Figura 13.Mas se você convertê-los para a forma decimal, eles coincidirão com os valores correspondentes da descrição do segundo exemplo (verificado separadamente). Deve-se notar que os links para o arquivo de áudio para o primeiro e terceiro clipes têm o mesmo valor 0x3F5B050, já que ambos os clipes se referem ao mesmo arquivo de áudio com o identificador correspondente. Isso é seguido por um bloco de bytes de parâmetros binários (4 bytes). Como no caso da descrição das faixas, decodifiquei apenas parte dos bits. O valor padrão é 0x00080000, ou seja, se convertido em binário, apenas um bit19 é "elevado" a um, e os 31 bits restantes são iguais a zero. Sem esse único bit, como a prática tem mostrado, a multissessão se recusa a carregar. No exemplo atual, esse valor é característico do primeiro e do segundo clipes, mas para o terceiro, por algum motivo, o valor dos sinalizadores é igual a 0x000A0000.Se você contar, então, neste valor, dois bits são "elevados": ainda o bit19 e outro bit17. Eu não sei por que isso aconteceu. Tentei zerar o bit17 para zero, mudando o valor de todo o parâmetro para 0x00080000, como nos clipes vizinhos. Como resultado, a sessão no Adobe Audition foi aberta sem nenhuma alteração visível. Enquanto trabalhava no Adobe Audition, percebi propriedades do clipe como "Fix in Time" e "Fix for Playback Only". É lógico supor que certos bits no bloco de parâmetros binários são responsáveis ​​por armazenar essas propriedades. Existem também outras propriedades binárias para clipes, mas não precisamos delas. E as duas propriedades listadas serão muito úteis. A propriedade "Fix in time" é útil porque o clipe ficará protegido da possibilidade de movimento acidental do ponteiro do mouse na direção horizontal.Mas em tal clipe, um símbolo na forma de um cadeado em um círculo será desenhado visualmente no canto esquerdo inferior, e esta é uma informação gráfica desnecessária para visualização. A segunda propriedade do clipe "Fix for playback only" é útil porque quando o parâmetro "R" (Record) é ativado na trilha correspondente, o clipe não adquire uma cor vermelha forçada. Pelo que decidi usar o parâmetro "R" em algumas faixas - está escrito acima. Empiricamente, descobri que o bit1 é responsável pela primeira propriedade do clipe e o bit3 pela segunda. De tudo o que foi dito, segue-se o seguinte. Para definir a propriedade Clip in Time, você precisa escrever o valor 0x00080002 nos parâmetros binários. Para a propriedade "Confirmar somente para reprodução" - 0x00080008. Para ambas as propriedades, sua soma lógica é 0x0008000A. Lidou com parâmetros binários.Após esses bytes, há um link para a trilha na qual o clipe está localizado. Na verdade, o identificador da faixa é registrado, que coincide com seu número de série. O Adobe Audition 1.5, por falar nisso, não oferece suporte a mais de 128 trilhas, portanto, esse identificador se encaixa em um byte, embora seja listado como um valor de 32 bits. Então, há constantes zero não decifradas (4 constantes, 4 bytes cada). Finalmente, o último parâmetro significativo é a cor do clipe. O editor Adobe Audition 1.5 permite definir um valor de cor de 0 a 239 para um clipe na caixa de diálogo correspondente ou selecioná-lo em uma paleta (Fig. 15). A paleta de cores não é particularmente agradável, mas outras opções não são fornecidas. A cor padrão do clipe é 102 (0x66) (verde).a propósito, ele não suporta mais de 128 trilhas, portanto, esse identificador cabe em um byte, embora esteja listado como um valor de 32 bits. Então, há constantes zero não decifradas (4 constantes, 4 bytes cada). Finalmente, o último parâmetro significativo é a cor do clipe. O editor Adobe Audition 1.5 permite definir um valor de cor de 0 a 239 para um clipe na caixa de diálogo correspondente ou selecioná-lo em uma paleta (Fig. 15). A paleta de cores não é particularmente agradável, mas outras opções não são fornecidas. A cor padrão do clipe é 102 (0x66) (verde).a propósito, ele não suporta mais de 128 trilhas, portanto, esse identificador cabe em um byte, embora seja listado como um valor de 32 bits. Então, há constantes zero não decifradas (4 constantes, 4 bytes cada). Finalmente, o último parâmetro significativo é a cor do clipe. O editor Adobe Audition 1.5 permite definir um valor de cor de 0 a 239 para um clipe na caixa de diálogo correspondente ou selecioná-lo em uma paleta (Fig. 15). A paleta de cores não é particularmente agradável, mas outras opções não são fornecidas. A cor padrão do clipe é 102 (0x66) (verde).5 permite definir um valor de cor de 0 a 239 para o clipe na caixa de diálogo correspondente ou selecioná-lo na paleta (Fig. 15). A paleta de cores não é particularmente agradável, mas outras opções não são fornecidas. A cor padrão do clipe é 102 (0x66) (verde).5 permite definir um valor de cor de 0 a 239 para o clipe na caixa de diálogo correspondente ou selecioná-lo na paleta (Fig. 15). A paleta de cores não é particularmente agradável, mas outras opções não são fornecidas. A cor padrão do clipe é 102 (0x66) (verde).





. 15. Adobe Audition 1.5.



O parâmetro de cor no arquivo ses é de 32 bits e, na verdade, existem apenas 240 cores, que cabem em um byte. Os outros três bytes mais significativos são zero. Tive a ideia de que, se eu tentar editar esses bytes para valores diferentes, ao abrir uma multissessão, novas cores aparecerão no clipe. Mas esse truque não funcionou. Conforme discutido no artigo anterior, as cores em um gráfico são úteis para destacar visualmente um recurso específico de uma chamada telefônica. Uma multissessão de gravações de áudio de chamadas telefônicas se parecerá com um diagrama semelhante, portanto, a cor dos clipes será muito útil. O parâmetro de cor do clipe é seguido por duas palavras de zeros. Isso completa a descrição da subunidade. Esses oito bytes de zeros são os últimos no sub-bloco do último bloco. Portanto, eles também serão os últimos em todo o arquivo ses.



Enquanto pensava no projeto, tive outra ideia: adicionar marcadores (cue points) à multissessão, colocando-os a cada hora e assinando as respectivas marcas. Se compararmos esta ideia com o artigo anterior, então esta é uma analogia completa das linhas verticais no diagrama, desenhadas a cada hora. Para que os cue points estejam presentes na multissessão, é necessário levar em consideração o sexto bloco denominado "cues". Não comecei a entender os bytes desse bloco. Por analogia com o bloco "stat", na multissessão criada por 24 horas, coloquei 23 pontos de sinalização manualmente a cada hora e dei a eles os nomes apropriados. Em seguida, salvei a multisessão como um arquivo ses separado, recortei o conteúdo do bloco "cues" e salvei-o no arquivo "cues_24h.BLK". Este arquivo será levado em consideração no desenvolvimento do programa. Os bytes deste arquivo são mostrados na Figura 16. Não sei por quê,mas salvei exatamente o conteúdo, sem o título e o campo de tamanho do conteúdo (ao contrário de "stat_31_full.BLK"). Essas duas palavras serão adicionadas no código do programa. E o tamanho do conteúdo é de 556 bytes. Destes, 4 bytes são ocupados pela legenda (o número de cue points) e 23 sub-blocos de 24 bytes cada. Na Figura 16, os bytes de conteúdo do primeiro sub-bloco são preenchidos. Decidi fazer os nomes dos pontos de sinalização (rótulos) da seguinte forma: 01h, 02h,…, 23h.





. 16. «cues» .



Isso conclui a descrição do formato multissessão. Agora temos a base de conhecimento necessária para começar a escrever um programa para a criação de uma multissessão. Escrever um programa é uma tarefa mais fácil do que aprender e descriptografar o formato ses. Concluí o programa em duas noites e passei pelo menos uma semana estudando o formato. Além disso, escrevi o programa usando funções utilizadas anteriormente, em particular, trabalhando com arquivos e diretórios. Portanto, o principal suporte para escrever o programa não foram os livros de referência ou a Internet, mas meus projetos anteriores, sobre os quais também escrevi no Habré. Da Internet, tirei apenas uma função que retorna o dia da semana por data. Mas antes de citar o texto do programa, decidi compartilhar mais algumas informações, sobre as quais inicialmente não queria escrever neste artigo.



A ideia de formar uma multissessão a partir de gravações telefônicas surgiu quando eu estava trabalhando em uma versão mais recente do Adobe Audition 3.0, que oferece suporte para entrada / saída de áudio via ASIO. Ao salvar a multissessão, descobri que ela pode ser salva em dois formatos à escolha: o usual clássico SES e o novo formato XML, que não existia nas versões anteriores do programa. Tendo salvo a sessão no formato XML, imediatamente abri este arquivo no "notepad", onde encontrei uma descrição de um monte de parâmetros ligados entre si em uma estrutura hierárquica complexa. Para facilitar a visualização dessa hierarquia, usei o programa WMHelp XmlPad. A Figura 17 mostra uma captura de tela deste programa com um arquivo multissessão simples de teste aberto nele. À esquerda está a hierarquia do documento. O elemento ativo (selecionado) da hierarquia é o parâmetro de comprimento do primeiro arquivo de áudio,no primeiro sub-bloco do bloco de descrição do arquivo de áudio.





. 17. XML Adobe Audition 3.0.



Decidi estudar esse formato específico e, no futuro, gerar programaticamente o texto XML necessário, obtendo a multissessão desejada na saída. Houve até uma ideia de usar o Excel para esse fim. A dificuldade era que cerca de 95% de todo o arquivo XML é ocupado pelo bloco de descrição da faixa. Há um número colossal de parâmetros, que não poderia excluir sem prejudicar a multissessão. O fato é que nesta versão do Adobe Audition existem muito mais funções relacionadas às trilhas. Logicamente, não há necessidade dessas funções para minha multissessão simples. No entanto, ao excluir os campos correspondentes do documento XML, a sessão cessa de viver. E eu teria que "puxar" esse grande pedaço de texto na descrição de cada faixa para a sessão mais simples. Este é o único inconveniente ao gerar um arquivo XML multissessão. Conhecimento,as variantes multissessão obtidas durante o estudo de XML textual, é claro, foram úteis durante o estudo de ses binárias. E mesmo em XML, não consegui descriptografar alguns parâmetros. Os campos de cada parâmetro têm um nome abreviado em inglês, mas mesmo assim, nem sempre entendi o que era esse parâmetro. O principal é que consegui estudar e decifrar os principais parâmetros necessários, seus blocos hierárquicos e campos. Então fiquei muito tempo atormentado com a pergunta: como abrir tal sessão em uma versão mais antiga do Adobe Audition? As novas versões dos programas têm uma interface muito sofisticada (quase 3D), o que é muito inconveniente para visualizar uma multisessão como diagramas. E por causa deste "três-te" no Adobe Audition 3.0 com uma janela totalmente expandida na tela FullHD, um máximo (na escala mínima) de 28 faixas se encaixa. E no Adobe Audition 1.5, 37 caberia (Fig.18, escala 1: 2). No total, 31 faixas precisam ser mostradas na tela.





. 18. Adobe Audition .



Mas acima de tudo acabei com a qualidade do som ao jogar uma multissessão com frequência de 8000 Hz na nova versão do programa. O som não é muito bom, há distorção harmônica. Isso se deve ao fato de que o som sai em uma taxa de amostragem diferente (48 kHz) e o ASIO não pode fazer de outra forma. Se você selecionar outro dispositivo de saída "Audition 3.0 Windows Sound" nas configurações, a situação não muda. A nova versão do programa não suporta dispositivos de saída "DirectSound" clássicos (eu chamo de versão 3.0 nova). A Figura 19 mostra o espectro de áudio ao reproduzir áudio de 8 kHz (ou sessão) no Adobe Audition 3.0 com uma distorção harmônica de espectro invertido presente. Essas frequências estão circuladas em verde, que deve soar idealmente (e nada mais). E as frequências estão circuladas em vermelho,que são distorção adicional. Este efeito é provavelmente devido à falta de filtragem após o procedimento de upsampling. Foi depois disso que decidi estudar o formato binário SES do programa Adobe Audition 1.5, mais simples e agradável. Eu esperava que, depois de aprender o formato XML "humano" de uma versão mais recente do programa, não fosse difícil para mim descobrir, dada minha experiência com arquivos binários. E assim aconteceu: eu rapidamente "promovi" o formato SES. E o principal é que a compatibilidade com versões anteriores, olhando para o futuro, funciona muito bem: uma sessão formada para a versão 1.5 abre com sucesso na versão 3.0. Acima, apontei as desvantagens do Adobe Audition 3.0 relacionadas à qualidade de som e interface gráfica. Mas esta versão do programa tem vantagens na navegação multissessão. Por exemplo,existe a possibilidade de ouvir um clipe de áudio em uma multissessão, clicando nele com o mouse e, em seguida, deslocando-o para a direita.





Figura: 19. Distorção harmônica durante a reprodução.



Agora vou dar o texto do programa sob o spoiler. O programa, é claro, não possui interface gráfica, pois não é necessário para essa tarefa. O texto do programa é fornecido com comentários detalhados, portanto, nenhuma explicação adicional é necessária. O programa é iniciado na linha de comando e em um segundo processa uma lista de quatrocentos arquivos, formando um arquivo multissessão. Dentro do programa, existem quatro variáveis ​​paramétricas que, se desejado, permitem que você não gere marcadores de sinalização, não coloque um "R" nas faixas nos fins de semana, não defina a propriedade "Fix in time" nos clipes e selecione o critério para colorir os clipes (por tipo de chamada ou por número de telefone) ... Essas três variáveis ​​teriam que ser excluídas do texto do programa e "trazidas", ou seja, em um arquivo separado com os parâmetros do programa.



Código fonte do programa C
/********************************************************************
  "RMC"     ,  
  wav    .   
 ,    .
       yyyy-mn, 
  .      .
      (.. -),  
   .  
    ,    ,
    "RMC"   "I:".
*********************************************************************/
#include <windows.h>
#include <stdio.h>
#include <string.h>

DWORD wr; // ,   ;
DWORD ww; // ,   ;
DWORD wi; // ,   ;

//    (     );
int Date( int D, int M, int Y ){
    int a, y, m, R;
    a = ( 14 - M ) / 12;
    y = Y - a;
    m = M + 12 * a - 2;
    R = 6999 + ( D + y + y / 4 - y / 100 + y / 400 + (31 * m) / 12 );
    return R % 7;
}

//   ;
HANDLE openInputFile(const char * filename) {
       return CreateFile ( filename,      // Open Two.txt.
            GENERIC_READ,          // Open for writing
            0,                      // Do not share
            NULL,                   // No security
            OPEN_ALWAYS,            // Open or create
            FILE_ATTRIBUTE_NORMAL,  // Normal file
            NULL);                  // No template file       
}

//   ;
HANDLE openOutputFile(const char * filename) {
       return CreateFile ( filename,      // Open Two.txt.
            GENERIC_WRITE,          // Open for writing
            0,                      // Do not share
            NULL,                   // No security
            OPEN_ALWAYS,            // Open or create
            FILE_ATTRIBUTE_NORMAL,  // Normal file
            NULL);                  // No template file       
}

//    ;
void filepos(HANDLE f, __int64 p){
  LONG HPos;
  LONG LPos;
  HPos = p>>32;
  LPos = p;
  SetFilePointer (f, LPos, &HPos, FILE_BEGIN);
}

// 32-  ;
void write32(HANDLE f, signed long int a){
  WriteFile(f, &a, 4, &ww, NULL);  
}

//  ;
void fill(HANDLE f, signed long int a, unsigned char c){
  unsigned char i;
  for(i=0;i<c;i++){
    write32(f,a);
  }
}

int main(){
  HANDLE out; //   Adobe Audition;
  HANDLE stat; //     "stat" (+ );
  HANDLE cues; //     "cues";
  HANDLE lf; //     "LISTFILE";
  HANDLE blk; //     "bk20";
  char* week[7]={"", "", "", "", "", "", ""}; //  -;
  unsigned char dm[]={31,29,31,30,31,30,31,31,30,31,30,31}; //   ;
  unsigned char p_cues=1; //:    (cues);
  unsigned char p_R=1; //:   "R" (  )    ;
  unsigned char p_lock=1; //:    ;
  unsigned char p_color=2; //   ;
  unsigned char flg; // ,    .   ;
  unsigned long int lfsize=0; //  "LISTFILE";
  unsigned long int blksize=0; //  "bk20";
  unsigned long int smp; //   ;
  unsigned long int offset; //    ;
  unsigned int cfile=0; //  ;
  unsigned int cblk=0; //  ;
  char name[100]; //   (  ...);
  char fullname[100]; //      ;
  char infld[8]; //  ;
  char number[11]; //    . ;
  unsigned char len; //    ;
  printf("Input yyyy-dd name of folder:\n"); //   ;
  scanf("%s",infld); //      ;
  WIN32_FIND_DATA fld; //       ;
  HANDLE hf; //  (   ,     );
  char buf1[48],buf2[556]; //     "stat"  "cues";
  char str[16]; //   ;
  unsigned long int outpos=0; //   ;
  unsigned char byte; //      "LISTFILE"  "bk20";
  unsigned char i; //  ;
  unsigned char mn,d,dw,h,m,s; // -;
  unsigned char cdm; //    ;
  int yy; //  ;
  yy=2000+(infld[2]-48)*10+(infld[3]-48); //    ;
  mn=(infld[5]-48)*10+(infld[6]-48); //    ;
  sprintf(name,"I:\\RMC\\%s.ses",infld); //     ( );
  out=openOutputFile(name); //    ;
  WriteFile(out, "COOLNESS", 8, &wi, NULL); // :    ;
  write32(out,0); //   (  ,     );
  WriteFile(out, "hdr ", 4, &wi, NULL); //,    :  ;
  write32(out,936); //   ,  936;
  write32(out,8000); //   ;
  write32(out,24*3600*8000); //    (. 24 );
  write32(out,0); //    ( );
  write32(out,0x00010020);
  write32(out,0);
  write32(out,0x3ff00000);
  write32(out,0);
  write32(out,0x3ff00000);
  filepos(out,328); //   ;
  write32(out,0x20);
  WriteFile(out, "", 6, &wi, NULL); //  ;
  filepos(out,376); //   ;
  write32(out,0x3ff00000);
  filepos(out,892); //   ;
  write32(out,0x0430041c);
  write32(out,0x04420441);
  write32(out,0x04400435);
  filepos(out,956); //   ;
  stat=openInputFile("stat_31_full.BLK"); //     ,
  ReadFile(stat, &buf1, 48, &wr, NULL); //       ;
  WriteFile(out, buf1, 48, &wi, NULL);
  CloseHandle(stat);
  if(mn==2){ // ,
    if(!(yy%4)){ //   ,
      cdm=29; // 29 ,
    }else{
      cdm=28; // - 28;
    }
  }else{ //  ,
    cdm=dm[mn-1]; //       ;
  }
  WriteFile(out, "trks", 4, &wi, NULL); //    ;
  write32(out,4+cdm*152); //      ;
  write32(out,cdm); //       ;
  outpos=1016; //     ;
  for(i=0;i<cdm;i++){ //      
    dw=Date(i+1,mn,yy); //     ;
    write32(out,0); //      ses,       ;
    write32(out,0x3ff00000); 
    write32(out,0); //   8-  double;
    write32(out,0x3ff00000);
    if((dw%7==5||dw%7==6)&&p_R){ //   -  ,      "R",
      write32(out,4); //     "R",
    }else{
      write32(out,0); // -   ;
    }
    sprintf(str,"%02d.%02d.%i %s",i+1,mn,yy,week[dw]); //  ,    ;
    WriteFile(out, str, strlen(str), &wi, NULL);
    filepos(out,1072+152*i); //      (i+1)- ;
    write32(out,1); //  ,     ;
    write32(out,1);
    write32(out,4);
    write32(out,0);
    write32(out,0);
    write32(out,0x40590000);
    write32(out,0);
    write32(out,0);
    write32(out,0xffffff9d);
    write32(out,0xffffff9d);
    write32(out,i+1); //  ,    ;
    fill(out,0,11);
    write32(out,4);
    write32(out,0);
    outpos+=152; //  ;
  }
  if(p_cues){ //        ,    "cues";
    WriteFile(out, "cues", 4, &wi, NULL); //  ,
    write32(out,556); //  -  ;
    cues=openInputFile("cues_24h.BLK"); //   ,   ;
    ReadFile(cues, &buf2, 556, &wr, NULL); //(    ,   "stat");
    WriteFile(out, buf2, 556, &wi, NULL);
    CloseHandle(cues);
    outpos+=564;
  }
  DeleteFile("LISTFILE"); //  (      )
  DeleteFile("bk20"); //  "LISTFILE"  "bk20",
  lf=openOutputFile("LISTFILE"); // ()    
  blk=openOutputFile("bk20"); //      ;
  WriteFile(lf, "LISTFILE", 8, &wi, NULL); //     ;
  WriteFile(blk, "bk20", 4, &wi, NULL);
  write32(lf,0);
  write32(blk,0);
  write32(blk,0);
  write32(blk,0x48); //  ,      ;
  sprintf(name,"I:\\RMC\\%s\\*.wav",infld); //   wav    ;
  hf=FindFirstFile(name,&fld); //  ;
  do{ //  ;
    len=strlen(fld.cFileName); //    ;
    for(i=10;i>=1;i--){ //  10      ;
      number[10-i]=fld.cFileName[len-i-4]; //  ;
    }
    number[10]=0; //   ,    ;
    cfile+=1; //   ;
    sprintf(fullname,"I:\\RMC\\%s\\%s",infld,fld.cFileName); //     ;
    d=(fld.cFileName[22]-48)*10+(fld.cFileName[23]-48); //  ()   ;
    h=(fld.cFileName[25]-48)*10+(fld.cFileName[26]-48); //    ;
    m=(fld.cFileName[27]-48)*10+(fld.cFileName[28]-48); //    ;
    s=(fld.cFileName[29]-48)*10+(fld.cFileName[30]-48); //    ;
    offset=(h*3600+m*60+s)*8000; //    ;
    smp=(fld.nFileSizeLow-44)/4; //     (   );
    WriteFile(lf, "wav ", 4, &wi, NULL); //     ;
    write32(lf,17+strlen(fullname)); //   (    );
    write32(lf,1000+cfile); //  ( ,      1000   );
    write32(lf,0x14); //  ( );
    WriteFile(lf, fullname, strlen(fullname), &wi, NULL); //   ( );
    WriteFile(lf, "\0", 1, &wi, NULL); //   ;
    write32(lf,0xffffffff); //;
    write32(lf,smp); //   ;
    lfsize+=(25+strlen(fullname)); //   "LISTFILE";
    cblk+=1; //     ;
    write32(blk,0); //     ,       ;
    write32(blk,1000+cfile); //   ();
    write32(blk,0); //   ;
    write32(blk,0x3ff00000);
    write32(blk,0);
    write32(blk,0x3ff00000);
    write32(blk,offset); //    ;
    if(((24*3600*8000)-offset)>smp){ //  ( )     ,
      write32(blk,smp); //     ,
    }else{
      write32(blk,(24*3600*8000)-offset); //       ;
    }
    write32(blk,0); //     ;
    if(p_lock){ //       ,
      write32(blk,0x0008000a); //     (3   32 ),
    }else{
      write32(blk,0x00080008); //    (2   32 );
    } //     -   "   ";
    write32(blk,d); //   ( );
    fill(blk,0,4); // ;
    switch(p_color){ //   ;
      case 1: //   ;
        switch(fld.cFileName[0]){ //     ;
          case 'I': // "I" (   ),
            write32(blk,0); //  ;
          break;
          case 'O': // "O" (   ),
            write32(blk,102); //   (  );
          break;
          default: //  - ,
            write32(blk,102); //   ;
          break;
        }
      break;
      case 2: //  ;
        flg=0; // ;
        if(!strcmp("9530000000",number)){ // - - ,
          write32(blk,05); //  - -,
          flg=1; //( );
        }
        #include "numbers_and_colors.cpp" //      -    ();
        if(!flg){ //     (     ),
          write32(blk,102); //    ;
        }
      break;
    }
    write32(blk,0);
    write32(blk,0);
    if(((24*3600*8000)-offset)<=smp){ //  ( )     ( ),
      cblk+=1; //      ;
      write32(blk,0); //   ,  ;
      write32(blk,1000+cfile);
      write32(blk,0);
      write32(blk,0x3ff00000);
      write32(blk,0);
      write32(blk,0x3ff00000);
      write32(blk,0); //        ,
      write32(blk,smp-((24*3600*8000)-offset)); //    ,
      write32(blk,(24*3600*8000)-offset); //    ,     ;
      if(p_lock){
        write32(blk,0x0008000a);
      }else{
        write32(blk,0x00080008);
      }
      write32(blk,d+1); //  ()     ();
      fill(blk,0,4);
      switch(p_color){ //     ;
        case 1: //   ;
          switch(fld.cFileName[0]){ //       ( );
            case 'I': // ,
              write32(blk,0); //  ;
            break;
            case 'O': // ,
              write32(blk,102); //  ,   ;
            break;
            default: //  -  (  ),
              write32(blk,102); //   ;
            break;
          }
        break;
        case 2: //  ;
          flg=0;
          if(!strcmp("9530000000",number)){ // - - ,
            write32(blk,05); //  - -,
            flg=1; //( );
          }
          #include "numbers_and_colors.cpp" //      ( );
          if(!flg){ //   ,
            write32(blk,102); //   ;
          }
        break;
      }
      write32(blk,0);
      write32(blk,0);
    }  
  }while(FindNextFile(hf,&fld)); //    wav ;
  filepos(lf,8);
  write32(lf,lfsize); //   "LISTFILE",    ;
  filepos(blk,4);
  blksize=8+72*cblk; //   "bk20",   ;
  write32(blk,blksize); //   "bk20";
  write32(blk,cblk); //  ;
  blksize+=8; //   "bk20",     .  ;
  lfsize+=12; //   "LISTFILE",     .  ;
  CloseHandle(lf); // . ;
  CloseHandle(blk); // . ;
  lf=openInputFile("LISTFILE"); // .       ;
  do{ //  ,     (   );
    ReadFile(lf, &byte, 1, &wr, NULL);
    if(wr){
      WriteFile(out, &byte, 1, &wi, NULL);
    }
  }while(wr);
  CloseHandle(lf); // . ;
  blk=openInputFile("bk20"); // .       ;
  do{ //  ,     (   );
    ReadFile(blk, &byte, 1, &wr, NULL);
    if(wr){
      WriteFile(out, &byte, 1, &wi, NULL);
    }
  }while(wr);
  CloseHandle(blk); // . ;
  outpos=outpos+blksize+lfsize; //    ;
  filepos(out,8);
  write32(out,outpos-12); //      ;
  filepos(out,28);
  write32(out,cblk); //      ;
  CloseHandle(out); //   !  ;
  printf("c_files: %i\nc_block: %i\n",cfile,cblk); //    (   );
  system("PAUSE");
  return 0;
}




Agora você pode mostrar capturas de tela dos resultados. Haverá vários deles: em diferentes escalas de visualização, em diferentes versões do programa e com diferentes critérios de coloração. Estava em processamento o catálogo “2020-05”, ou seja, os registros de maio do corrente ano. Um total de 446 registros foram processados. O número de blocos é o mesmo, pois não há registros de transição para um novo dia.





Figura: 20. Visualização da multissessão em escala real com coloração por telefone. números.





Figura: 21. Visualização de multissessão em escala real com coloração por tipo de chamada.





Figura: 22. Tipo de multissessão em média escala.





Figura: 23. Visão de uma multissessão em grande escala.





Figura: 24. Visualização da mesma multissessão no Adobe Audition 3.0.






All Articles