Пример #1
0
int write_wav_header(FILE *file, int rate, int mapping_family, int channels, int fp)
{
   int ret;
   int extensible;

   /* Multichannel files require a WAVEFORMATEXTENSIBLE header to declare the
      proper channel meanings. */
   extensible = mapping_family == 1 && 3 <= channels && channels <= 8;

   /* >16 bit audio also requires WAVEFORMATEXTENSIBLE. */
   extensible |= fp;

   ret = fprintf (file, "RIFF") >= 0;
   ret &= fwrite_le32 (0x7fffffff, file);

   ret &= fprintf (file, "WAVEfmt ") >= 0;
   ret &= fwrite_le32 (extensible ? 40 : 16, file);
   ret &= fwrite_le16 (extensible ? 0xfffe : (fp?3:1), file);
   ret &= fwrite_le16 (channels, file);
   ret &= fwrite_le32 (rate, file);
   ret &= fwrite_le32 ((fp?4:2)*channels*rate, file);
   ret &= fwrite_le16 ((fp?4:2)*channels, file);
   ret &= fwrite_le16 (fp?32:16, file);

   if(extensible)
   {
      static const unsigned char ksdataformat_subtype_pcm[16]=
      {
        0x01, 0x00, 0x00, 0x00,
        0x00, 0x00,
        0x10, 0x00,
        0x80, 0x00,
        0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
      };
      static const unsigned char ksdataformat_subtype_float[16]=
      {
        0x03, 0x00, 0x00, 0x00,
        0x00, 0x00,
        0x10, 0x00,
        0x80, 0x00,
        0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
      };
      static const int wav_channel_masks[8] =
      {
         1,                      /* 1.0 mono */
         1|2,                    /* 2.0 stereo */
         1|2|4,                  /* 3.0 channel ('wide') stereo */
         1|2|16|32,              /* 4.0 discrete quadrophonic */
         1|2|4|16|32,            /* 5.0 */
         1|2|4|8|16|32,          /* 5.1 */
         1|2|4|8|256|512|1024,   /* 6.1 */
         1|2|4|8|16|32|512|1024, /* 7.1 */
      };
      ret &= fwrite_le16 (22, file);
      ret &= fwrite_le16 (fp?32:16, file);
      ret &= fwrite_le32 (wav_channel_masks[channels-1], file);
      if (!fp)
      {
         ret &= fwrite (ksdataformat_subtype_pcm, 16, 1, file);
      } else {
         ret &= fwrite (ksdataformat_subtype_float, 16, 1, file);
      }
   }

   ret &= fprintf (file, "data") >= 0;
   ret &= fwrite_le32 (0x7fffffff, file);

   return !ret ? -1 : extensible ? 40 : 16;
}
Пример #2
0
int
main(int argc, char *argv[])
{
  const char *infile, *outfile;
  FILE *in, *out;
  static const uint8_t buf[4096];
  size_t elems;

  uint8_t properties;
  uint32_t dictsize;
  uint64_t datasize;

  uint32_t magic = 0xfeed1281L;
  uint32_t reclength = 0;
  fpos_t reclengthpos;
  uint32_t loadaddress = 0;
  uint32_t type = 0x075a0201L; /* might be 7Z 2.1? */
  uint32_t checksum = 0;

  uint32_t compsize = 0;
  fpos_t compsizepos;
  uint32_t datasize32 = 0;
  uint32_t datacrc32 = crc32(0, 0, 0);

  uint32_t entry = 0;

  if (argc != 5)
    usage();

  /* "parse" command line */
  loadaddress = strtoul(argv[1], 0, 0);
  entry = strtoul(argv[2], 0, 0);
  infile = argv[3];
  outfile = argv[4];

  in = fopen(infile, "rb");
  if (!in)
    pexit("fopen");
  out = fopen(outfile, "w+b");
  if (!out)
    pexit("fopen");

  /* read LZMA header */
  if (fread_8(&properties, in))
    pexit("fread");
  if (fread_le32(&dictsize, in))
    pexit("fread");
  if (fread_le64(&datasize, in))
    pexit("fread");

  /* write EVA header */
  if (fwrite_le32(magic, out))
    pexit("fwrite");
  if (fgetpos(out, &reclengthpos))
    pexit("fgetpos");
  if (fwrite_le32(reclength, out))
    pexit("fwrite");
  if (fwrite_le32(loadaddress, out))
    pexit("fwrite");
  if (fwrite_le32(type, out))
    pexit("fwrite");

  /* write EVA LZMA header */
  if (fgetpos(out, &compsizepos))
    pexit("fgetpos");
  if (fwrite_le32(compsize, out))
    pexit("fwrite");
  /* XXX check length */
  datasize32 = (uint32_t)datasize;
  if (fwrite_le32(datasize32, out))
    pexit("fwrite");
  if (fwrite_le32(datacrc32, out))
    pexit("fwrite");

  /* write modified LZMA header */
  if (fwrite_8(properties, out))
    pexit("fwrite");
  if (fwrite_le32(dictsize, out))
    pexit("fwrite");
  if (fwrite_le32(0, out))
    pexit("fwrite");

  /* copy compressed data, calculate crc32 */
  while (0 < (elems = fread(&buf, sizeof buf[0], sizeof buf, in))) {
    compsize += elems;
    if (elems != fwrite(&buf, sizeof buf[0], elems, out))
      pexit("fwrite");
    datacrc32 = crc32(datacrc32, buf, elems);
  }
  if (ferror(in))
    pexit("fread");
  fclose(in);

  /* re-write record length */
  reclength = compsize + 24;
  if (fsetpos(out, &reclengthpos))
    pexit("fsetpos");
  if (fwrite_le32(reclength, out))
    pexit("fwrite");

  /* re-write EVA LZMA header including size and data crc */
  if (fsetpos(out, &compsizepos))
    pexit("fsetpos");
  if (fwrite_le32(compsize, out))
    pexit("fwrite");
  if (fwrite_le32(datasize32, out))
    pexit("fwrite");
  if (fwrite_le32(datacrc32, out))
    pexit("fwrite");

  /* calculate record checksum */
  checksum += reclength;
  checksum += loadaddress;
  checksum_add32(checksum, type);
  checksum_add32(checksum, compsize);
  checksum_add32(checksum, datasize32);
  checksum_add32(checksum, datacrc32);
  if (fseek(out, 0, SEEK_CUR))
    pexit("fseek");
  while (0 < (elems = fread(&buf, sizeof buf[0], sizeof buf, out))) {
    size_t i;
    for (i = 0; i < elems; ++i)
      checksum += buf[i];
  }
  if (ferror(out))
    pexit("fread");
  if (fseek(out, 0, SEEK_CUR))
    pexit("fseek");

  checksum = ~checksum + 1;
  if (fwrite_le32(checksum, out))
    pexit("fwrite");

  /* write entry record */
  if (fwrite_le32(0, out))
    pexit("fwrite");
  if (fwrite_le32(entry, out))
    pexit("fwrite");

  if (fclose(out))
    pexit("fclose");

  return 0;
}