Estou trabalhando neste arquivo grande (DADOS.DAT, ~900MB) que contém vários outros arquivos. É de um jogo de PS2.
Amostras de som (que estão em.AIFFformato), precisamente o que procuro, compõe a maior parte do seu tamanho.
Depois de pesquisar na web por PS2.DATextratores descobri que eles são basicamente dependentes do desenvolvedor e como esse jogo/ferramenta é um tanto obscuro e não encontro muito sobre ele online, pensei em automatizar o processo sozinho.
Inspecionando o arquivo em um editor hexadecimal me deparei com alguns.AIFFcabeçalhos, clonou os pedaços para novos.AIFFarquivos e sem qualquer trabalho adicional, eles eram reproduzíveis.
Depois de passar um tempo tirando a ferrugem do meu conhecimento MUITO limitado do bash e de ler 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.AIFFarquivos 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 gerarão ruído final indesejado nas amostras), pensei que o regexp
/FORM/
seria suficiente para dividir os arquivos.
No entanto, cada arquivo dividido está sendo produzido com dados inúteis que ficam entre as amostras de som antes do.AIFFcabeçalho, 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 em torno da marca de 1.500 bytes:
O que faz esta expressão dividir os arquivos com um deslocamento?
Responder1
Csplit é um utilitário de texto. É baseado em linha. Um padrão /FORM/
significa “uma linha contendo FORM
”. Uma linha é uma sequência de bytes diferente de LF (line feed, também conhecido como nova linha, que pode ser escrito \n
, ^J,…), seguido por um byte LF (ou pelo final do arquivo, com utilitários GNU). Assim, o “lixo” que você observa é tudo o que está entre o caractere LF anterior e a FORM
substring.
A página de manual e a --help
breve descrição presumem que você já sabe o que o comando faz, então apenas mencionam “peças” sem explicação. Você precisa ler odocumentação completapara obter uma descrição de quais são as peças.
Você não pode fazer o que quiser com o csplit. Você pode fazer isso com o GNU awk. (Outras versões do awk podem não ter os recursos necessários — suporte a separadores de registros arbitrários e capacidade de lidar com bytes nulos.) Não testado:
gawk -v RS='FORM' -v ORS='' '{
print "FORM" $0 >sprintf("sample-%04d.aif", n++)
}' DATA.DAT
Mas isso pode diminuir em locais espúrios se os dados compactados 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.
Responder2
Um utilitário baseado em texto não é apropriado para manipular arquivos binários.
É provável que você obtenha melhores resultados comBiblioteca/aifc,Arquivo PySound, ou offmpegaplicativo de linha de comando.