Estou trabalhando neste arquivo grande ( DATA.DAT , ~900MB) que contém vários outros arquivos. É de um jogo de PS2.
Amostras de som (que estão no formato .AIFF ), exatamente o que procuro, compõem a maior parte de seu tamanho.
Depois de pesquisar na web por extratores .DAT do PS2 , descobri que eles dependem basicamente do desenvolvedor e, como esse jogo/ferramenta é bastante obscuro e não encontro muito sobre ele online, pensei em automatizar o processo sozinho.
Inspecionando o arquivo em um editor hexadecimal, encontrei alguns cabeçalhos .AIFF , clonei os pedaços para novos arquivos .AIFF e, sem nenhum trabalho adicional, eles podiam ser reproduzidos.
Depois de passar um tempo tirando a ferrugem do meu conhecimento MUITO limitado de bash e lendo perguntas semelhantes aqui, criei esta expressão:
gcsplit -f "sample-" -b "%04d.aif" DATA.DAT /FORM/ '{*}'
(Estou no OSX usando coreutils, daí o prefixo g- no csplit)
Dado que os arquivos .AIFF começam com a string "FORM" e dado que basicamente todas as amostras no arquivo estão próximas umas das outras (espaçadas por quantidades desprezíveis de dados que não irão gerar ruído final indesejado nas amostras), pensei que o regexp
/FORM/
bastaria dividir os arquivos.
No entanto, cada arquivo dividido está sendo gerado com dados inúteis que ficam entre as amostras de som antes do cabeçalho .AIFF , tornando-o impossível de reproduzir.
Capturas de tela dos dados hexadecimais de uma amostra de som dividida abaixo:
Esta amostra real começa aproximadamente na marca de 1500 bytes:
O que está fazendo essa expressão dividir os arquivos com um deslocamento?
Csplit é um utilitário de texto. É baseado em linha. Um padrão
/FORM/
significa “uma linha contendoFORM
”. Uma linha é uma sequência de bytes diferente de LF (alimentação de linha, também conhecida como nova linha, que pode ser escrita\n
, ^J, …), seguida por um byte LF (ou pelo final do arquivo, com utilitários GNU). Assim, o “lixo” que você observa é o que quer que esteja entre o caractere LF anterior e aFORM
substring.A página do manual e a
--help
breve descrição assumem que você já sabe o que o comando faz, então eles apenas mencionam “peças” sem explicação. Você precisa ler a documentação completa para obter uma descrição do que são as peças.Você não pode fazer o que quiser com csplit. Você pode fazer isso com GNU awk. (Outras versões do awk podem não ter os recursos necessários — suporte a separadores de registro arbitrários e manipulação de bytes nulos.) Não testado:
Mas isso pode cortar em lugares espúrios se os dados compactados simplesmente contiverem os quatro bytes
FORM
. Isso pode ser bom o suficiente para uma operação única com revisão manual, mas seria melhor usar uma ferramenta com reconhecimento de formato se precisar de algo confiável.Um utilitário baseado em texto não é apropriado para manipular arquivos binários.
É provável que você obtenha melhores resultados com Lib/aifc , PySoundFile ou o aplicativo de linha de comando ffmpeg .