コード例 #1
0
ファイル: wav.c プロジェクト: BPaden/garglk
static __inline__ int read_adpcm_block_headers(Sound_Sample *sample)
{
    Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
    SDL_RWops *rw = internal->rw;
    wav_t *w = (wav_t *) internal->decoder_private;
    fmt_t *fmt = w->fmt;
    ADPCMBLOCKHEADER *headers = fmt->fmt.adpcm.blockheaders;
    int i;
    int max = fmt->wChannels;

    if (w->bytesLeft < fmt->wBlockAlign)
    {
        sample->flags |= SOUND_SAMPLEFLAG_EOF;
        return(0);
    } /* if */

    w->bytesLeft -= fmt->wBlockAlign;

    for (i = 0; i < max; i++)
        BAIL_IF_MACRO(!read_uint8(rw, &headers[i].bPredictor), NULL, 0);

    for (i = 0; i < max; i++)
        BAIL_IF_MACRO(!read_le16(rw, &headers[i].iDelta), NULL, 0);

    for (i = 0; i < max; i++)
        BAIL_IF_MACRO(!read_le16(rw, &headers[i].iSamp1), NULL, 0);

    for (i = 0; i < max; i++)
        BAIL_IF_MACRO(!read_le16(rw, &headers[i].iSamp2), NULL, 0);

    fmt->fmt.adpcm.samples_left_in_block = fmt->fmt.adpcm.wSamplesPerBlock;
    fmt->fmt.adpcm.nibble_state = 0;
    return(1);
} /* read_adpcm_block_headers */
コード例 #2
0
ファイル: pcx.c プロジェクト: harnold/astroids
int pcx_load_image(const char *path, struct image *image)
{
    FILE *file;
    uint8_t *data = NULL;

    if (!(file = fopen(path, "rb"))) {
        error_errno("Opening file '%s' failed", path);
        goto failure;
    }

    uint8_t header[PCX_HEADER_SIZE];

    if (fread(header, PCX_HEADER_SIZE, 1, file) != 1) {
        error_errno("Reading PCX header from file '%s' failed", path);
        goto failure;
    }

    int width = read_le16(header + PCX_X2) - read_le16(header + PCX_X1) + 1;
    int height = read_le16(header + PCX_Y2) - read_le16(header + PCX_Y1) + 1;
    int size = width * height;

    data = xmalloc(size);

    uint8_t *p = data;
    int pixel, count;

    for (int i = 0; i < size; ) {
        if ((pixel = fgetc(file)) == EOF) {
            error_errno("Reading image data from file '%s' failed", path);
            goto failure;
        }
        if (pixel < 192) {
            *p++ = (uint8_t) pixel;
            i++;
        } else {
            count = pixel - 192;
            if ((pixel = fgetc(file)) == EOF) {
                error_errno("Reading image data from file '%s' failed", path);
                goto failure;
            }
            while (count-- > 0) {
                *p++ = (uint8_t) pixel;
                i++;
            }
        }
    }

    fclose(file);

    init_image(image, width, height, data);
    return 0;

failure:

    if (file)
        fclose(file);
    if (data)
        xfree(data);
    return -1;
}
コード例 #3
0
ファイル: sf2load.c プロジェクト: 100GPing100/Loveprint
static void Modulator_read(Modulator *self, Reader *stream)
{
    self->mSrcOp = read_le16(stream);
    self->mDstOp = read_le16(stream);
    self->mAmount = read_le16(stream);
    self->mAmtSrcOp = read_le16(stream);
    self->mTransOp = read_le16(stream);
}
コード例 #4
0
ファイル: sf2load.c プロジェクト: 100GPing100/Loveprint
static void PresetHeader_read(PresetHeader *self, Reader *stream)
{
    Reader_read(stream, self->mName, sizeof(self->mName));
    self->mPreset = read_le16(stream);
    self->mBank = read_le16(stream);
    self->mZoneIdx = read_le16(stream);
    self->mLibrary = read_le32(stream);
    self->mGenre = read_le32(stream);
    self->mMorphology = read_le32(stream);
}
コード例 #5
0
/* Return 0 if equal. Non-zero if not equal. */
static int guid_compare(const EFI_GUID *le_guid, const EFI_GUID *native_guid)
{
	if (read_le32(&le_guid->Data1) != native_guid->Data1)
		return 1;
	if (read_le16(&le_guid->Data2) != native_guid->Data2)
		return 1;
	if (read_le16(&le_guid->Data3) != native_guid->Data3)
		return 1;
	return memcmp(le_guid->Data4, native_guid->Data4,
			ARRAY_SIZE(le_guid->Data4));
}
コード例 #6
0
ファイル: sf2load.c プロジェクト: 100GPing100/Loveprint
static void SampleHeader_read(SampleHeader *self, Reader *stream)
{
    Reader_read(stream, self->mName, sizeof(self->mName));
    self->mStart = read_le32(stream);
    self->mEnd = read_le32(stream);
    self->mStartloop = read_le32(stream);
    self->mEndloop = read_le32(stream);
    self->mSampleRate = read_le32(stream);
    self->mOriginalKey = read_8(stream);
    self->mCorrection = read_8(stream);
    self->mSampleLink = read_le16(stream);
    self->mSampleType = read_le16(stream);
}
コード例 #7
0
ファイル: cr50.c プロジェクト: canistation/coreboot
/* cr50 uses bytes 3:2 of status register for burst count and
 * all 4 bytes must be read */
static int cr50_i2c_wait_burststs(struct tpm_chip *chip, uint8_t mask,
				  size_t *burst, int *status)
{
	uint8_t buf[4];
	struct stopwatch sw;

	stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_LONG_MS);

	while (!stopwatch_expired(&sw)) {
		if (cr50_i2c_read(chip, TPM_STS(chip->vendor.locality),
				  buf, sizeof(buf)) != 0) {
			mdelay(CR50_TIMEOUT_SHORT_MS);
			continue;
		}

		*status = buf[0];
		*burst = read_le16(&buf[1]);

		/* Check if mask matches and burst is valid */
		if ((*status & mask) == mask &&
		    *burst > 0 && *burst <= CR50_MAX_BUFSIZE)
			return 0;

		mdelay(CR50_TIMEOUT_SHORT_MS);
	}

	printk(BIOS_ERR, "%s: Timeout reading burst and status\n", __func__);
	return -1;
}
コード例 #8
0
ファイル: wav.c プロジェクト: BPaden/garglk
/*
 * Read in a fmt_t from disk. This makes this process safe regardless of
 *  the processor's byte order or how the fmt_t structure is packed.
 * Note that the union "fmt" is not read in here; that is handled as 
 *  needed in the read_fmt_* functions.
 */
static int read_fmt_chunk(SDL_RWops *rw, fmt_t *fmt)
{
    /* skip reading the chunk ID, since it was already read at this point... */
    fmt->chunkID = fmtID;

    BAIL_IF_MACRO(!read_le32(rw, &fmt->chunkSize), NULL, 0);
    BAIL_IF_MACRO(fmt->chunkSize < 16, "WAV: Invalid chunk size", 0);
    fmt->next_chunk_offset = SDL_RWtell(rw) + fmt->chunkSize;
    
    BAIL_IF_MACRO(!read_le16(rw, &fmt->wFormatTag), NULL, 0);
    BAIL_IF_MACRO(!read_le16(rw, &fmt->wChannels), NULL, 0);
    BAIL_IF_MACRO(!read_le32(rw, &fmt->dwSamplesPerSec), NULL, 0);
    BAIL_IF_MACRO(!read_le32(rw, &fmt->dwAvgBytesPerSec), NULL, 0);
    BAIL_IF_MACRO(!read_le16(rw, &fmt->wBlockAlign), NULL, 0);
    BAIL_IF_MACRO(!read_le16(rw, &fmt->wBitsPerSample), NULL, 0);

    return(1);
} /* read_fmt_chunk */
コード例 #9
0
ファイル: bsaarchive.cpp プロジェクト: afritz1/OpenTESArena
void BsaArchive::load(const std::string &fname)
{
    mFilename = fname;

    std::ifstream stream(mFilename.c_str(), std::ios::binary);
    if(!stream.is_open())
        throw std::runtime_error("Failed to open "+mFilename);

    size_t count = read_le16(stream);

    mEntries.reserve(count);
    loadNamed(count, stream);
}
コード例 #10
0
ファイル: bsaarchive.cpp プロジェクト: afritz1/OpenTESArena
void BsaArchive::loadNamed(size_t count, std::istream& stream)
{
    std::vector<std::string> names; names.reserve(count);
    std::vector<Entry> entries; entries.reserve(count);

    std::streamsize base = stream.tellg();
    if(!stream.seekg(std::streampos(count) * -18, std::ios_base::end))
        throw std::runtime_error("Failed to seek to archive footer ("+std::to_string(count)+" entries)");
    for(size_t i = 0;i < count;++i)
    {
        std::array<char,13> name;
        stream.read(name.data(), name.size()-1);
        name.back() = '\0'; // Ensure null termination
        std::replace(name.begin(), name.end(), '\\', '/');
        names.push_back(std::string(name.data()));

        int iscompressed = read_le16(stream);
        if(iscompressed != 0)
            throw std::runtime_error("Compressed entries not supported");

        Entry entry;
        entry.mStart = ((i == 0) ? base : entries[i-1].mEnd);
        entry.mEnd = entry.mStart + read_le32(stream);
        entries.push_back(entry);
    }
    if(!stream.good())
        throw std::runtime_error("Failed reading archive footer");

    for(const std::string &name : names)
    {
        auto iter = std::lower_bound(mLookupName.begin(), mLookupName.end(), name);
        if(iter == mLookupName.end() || *iter != name)
            mLookupName.insert(iter, name);
    }
    mEntries.resize(mLookupName.size());
    for(size_t i = 0;i < count;++i)
    {
        auto iter = std::find(mLookupName.cbegin(), mLookupName.cend(), names[i]);
        mEntries[std::distance(mLookupName.cbegin(), iter)] = entries[i];
    }
}
コード例 #11
0
static int relocate_patch_table(void *fsp, size_t size, size_t offset,
				ssize_t adjustment)
{
	struct fsp_patch_table *table;
	size_t num;
	size_t num_entries;

	table = relative_offset(fsp, offset);

	if ((offset + sizeof(*table) > size) ||
	    (read_le16(&table->header_length) + offset) > size) {
		printk(BIOS_ERR, "FSPP not entirely contained in region.\n");
		return -1;
	}

	num_entries = read_le32(&table->patch_entry_num);
	printk(FSP_DBG_LVL, "FSPP relocs: %zx\n", num_entries);

	for (num = 0; num < num_entries; num++) {
		uint32_t *reloc;
		uint32_t reloc_val;

		reloc = fspp_reloc(fsp, size,
				read_le32(&table->patch_entries[num]));

		if (reloc == NULL) {
			printk(BIOS_ERR, "Ignoring FSPP entry: %x\n",
				read_le32(&table->patch_entries[num]));
			continue;
		}

		reloc_val = read_le32(reloc);
		printk(FSP_DBG_LVL, "Adjusting %p %x -> %x\n",
			reloc, reloc_val,
			(unsigned int)(reloc_val + adjustment));

		write_le32(reloc, reloc_val + adjustment);
	}

	return 0;
}
コード例 #12
0
ファイル: vmfs_volume.c プロジェクト: antonu17/vmfs-tools
/* Open a VMFS volume */
vmfs_volume_t *vmfs_vol_open(const char *filename,vmfs_flags_t flags)
{
   vmfs_volume_t *vol;
   struct stat st;
   int file_flags;

   if (!(vol = calloc(1,sizeof(*vol))))
      return NULL;

   if (!(vol->device = strdup(filename)))
      goto err_filename;

   file_flags = (flags.read_write) ? O_RDWR : O_RDONLY;

   if ((vol->fd = open(vol->device,file_flags)) < 0) {
      perror("open");
      goto err_open;
   }

   vol->flags = flags;
   fstat(vol->fd,&st);
   vol->is_blkdev = S_ISBLK(st.st_mode);
#if defined(O_DIRECT) || defined(DIRECTIO_ON)
   if (vol->is_blkdev)
#ifdef O_DIRECT
      fcntl(vol->fd, F_SETFL, O_DIRECT);
#else
#ifdef DIRECTIO_ON
      directio(vol->fd, DIRECTIO_ON);
#endif
#endif
#endif

   vol->vmfs_base = VMFS_VOLINFO_BASE;

   /* Read volume information */
   do {
      DECL_ALIGNED_BUFFER(buf,512);
      uint16_t magic;
      /* Look for the MBR magic number */
      m_pread(vol->fd,buf,buf_len,0);
      magic = read_le16(buf, 510);
      if (magic == 0xaa55) {
         /* Scan partition table */
         int off;
         for (off = 446; off < 510; off += 16) {
            if (buf[off + 4] == 0xfb) {
                vol->vmfs_base += (off_t) read_le32(buf, off + 8) * 512;
                break;
            }
         }
      }
   } while(0);

   if (vmfs_volinfo_read(vol) == -1)
      goto err_open;

   /* We support only VMFS3 and VMFS5*/
   if ((vol->vol_info.version != 3) && (vol->vol_info.version != 5)) {
      fprintf(stderr,"VMFS: Unsupported version %u\n",vol->vol_info.version);
      goto err_open;
   }

   if ((vol->vol_info.version == 5) && flags.read_write) {
      fprintf(stderr, "VMFS: Can't open VMFS read/write\n");
      goto err_open;
   }

   if (vol->is_blkdev && (scsi_get_lun(vol->fd) != vol->vol_info.lun))
      fprintf(stderr,"VMFS: Warning: Lun ID mismatch on %s\n", vol->device);

   vmfs_vol_check_reservation(vol);

   if (vol->flags.debug_level > 0) {
      printf("VMFS: volume opened successfully\n");
   }

   vol->dev.read = vmfs_vol_read;
   if (vol->flags.read_write)
      vol->dev.write = vmfs_vol_write;
   vol->dev.close = vmfs_vol_close;
   vol->dev.uuid = &vol->vol_info.lvm_uuid;

   return vol;

 err_open:
   free(vol->device);
 err_filename:
   free(vol);
   return NULL;
}
コード例 #13
0
static ssize_t relocate_fvh(uintptr_t new_addr, void *fsp, size_t fsp_size,
				size_t fvh_offset, size_t *fih_offset)
{
	EFI_FIRMWARE_VOLUME_HEADER *fvh;
	EFI_FFS_FILE_HEADER *ffsfh;
	EFI_COMMON_SECTION_HEADER *csh;
	size_t offset;
	size_t file_offset;
	size_t size;
	size_t fv_length;

	offset = fvh_offset;
	fvh = relative_offset(fsp, offset);

	if (read_le32(&fvh->Signature) != EFI_FVH_SIGNATURE)
		return -1;

	fv_length = read_le64(&fvh->FvLength);

	printk(FSP_DBG_LVL, "FVH length: %zx Offset: %zx Mapping length: %zx\n",
		fv_length, offset, fsp_size);

	if (fv_length + offset > fsp_size)
		return -1;

	/* Parse only this FV. However, the algorithm uses offsets into the
	 * entire FSP region so make size include the starting offset. */
	size = fv_length + offset;

	if (guid_compare(&fvh->FileSystemGuid, &ffs2_guid)) {
		printk(BIOS_ERR, "FVH not an FFS2 type.\n");
		return -1;
	}

	if (read_le16(&fvh->ExtHeaderOffset) != 0) {
		EFI_FIRMWARE_VOLUME_EXT_HEADER *fveh;

		offset += read_le16(&fvh->ExtHeaderOffset);
		fveh = relative_offset(fsp, offset);
		printk(FSP_DBG_LVL, "Extended Header Offset: %zx Size: %zx\n",
			(size_t)read_le16(&fvh->ExtHeaderOffset),
			(size_t)read_le32(&fveh->ExtHeaderSize));
		offset += read_le32(&fveh->ExtHeaderSize);
		/* FFS files are 8 byte aligned after extended header. */
		offset = ALIGN_UP(offset, 8);
	} else {
		offset += read_le16(&fvh->HeaderLength);
	}

	file_offset = offset;
	while (file_offset + sizeof(*ffsfh) < size) {
		offset = file_offset;
		printk(FSP_DBG_LVL, "file offset: %zx\n", file_offset);

		/* First file and section should be FSP info header. */
		if (fih_offset != NULL && *fih_offset == 0)
			*fih_offset = file_offset;

		ffsfh = relative_offset(fsp, file_offset);

		printk(FSP_DBG_LVL, "file type = %x\n", read_le8(&ffsfh->Type));
		printk(FSP_DBG_LVL, "file attribs = %x\n",
			read_le8(&ffsfh->Attributes));

		/* Exit FV relocation when empty space found */
		if (read_le8(&ffsfh->Type) == EFI_FV_FILETYPE_FFS_MAX)
			break;

		/* Next file on 8 byte alignment. */
		file_offset += ffs_file_size(ffsfh);
		file_offset = ALIGN_UP(file_offset, 8);

		/* Padding files have no section information. */
		if (read_le8(&ffsfh->Type) == EFI_FV_FILETYPE_FFS_PAD)
			continue;

		offset += file_section_offset(ffsfh);

		while (offset + sizeof(*csh) < file_offset) {
			size_t data_size;
			size_t data_offset;

			csh = relative_offset(fsp, offset);

			printk(FSP_DBG_LVL, "section offset: %zx\n", offset);
			printk(FSP_DBG_LVL, "section type: %x\n",
				read_le8(&csh->Type));

			data_size = section_data_size(csh);
			data_offset = section_data_offset(csh);

			if (data_size + data_offset + offset > file_offset) {
				printk(BIOS_ERR, "Section exceeds FV size.\n");
				return -1;
			}

			/*
			 * The entire FSP 1.1 image can be thought of as one
			 * program with a single link address even though there
			 * are multiple TEs linked separately. The reason is
			 * that each TE is linked for XIP. So in order to
			 * relocate the TE properly we need to form the
			 * relocated address based on the TE offset within
			 * FSP proper.
			 */
			if (read_le8(&csh->Type) == EFI_SECTION_TE) {
				void *te;
				size_t te_offset = offset + data_offset;
				uintptr_t te_addr = new_addr + te_offset;

				printk(FSP_DBG_LVL, "TE image at offset %zx\n",
					te_offset);
				te = relative_offset(fsp, te_offset);
				te_relocate(te_addr, te);
			}

			offset += data_size + data_offset;
			/* Sections are aligned to 4 bytes. */
			offset = ALIGN_UP(offset, 4);
		}
	}

	/* Return amount of buffer parsed: FV size. */
	return fv_length;
}
コード例 #14
0
ファイル: tex_bmp.cpp プロジェクト: Marlinc/0ad
		BmpHeader* hdr = (BmpHeader*)file;
		const u32 ofs = read_le32(&hdr->bfOffBits);
		ENSURE(ofs >= hdr_size && "bmp_hdr_size invalid");
		return ofs;
	}
	return hdr_size;
}


// requirements: uncompressed, direct colour, bottom up
static Status bmp_decode(rpU8 data, size_t UNUSED(size), Tex* RESTRICT t)
{
	const BmpHeader* hdr = (const BmpHeader*)data;
	const long w       = (long)read_le32(&hdr->biWidth);
	const long h_      = (long)read_le32(&hdr->biHeight);
	const u16 bpp      = read_le16(&hdr->biBitCount);
	const u32 compress = read_le32(&hdr->biCompression);

	const long h = abs(h_);

	size_t flags = 0;
	flags |= (h_ < 0)? TEX_TOP_DOWN : TEX_BOTTOM_UP;
	if(bpp > 16)
		flags |= TEX_BGR;
	if(bpp == 32)
		flags |= TEX_ALPHA;

	// sanity checks
	if(compress != BI_RGB)
		WARN_RETURN(ERR::TEX_COMPRESSED);
コード例 #15
0
static int te_relocate(uintptr_t new_addr, void *te)
{
	EFI_TE_IMAGE_HEADER *teih;
	EFI_IMAGE_DATA_DIRECTORY *relocd;
	EFI_IMAGE_BASE_RELOCATION *relocb;
	uintptr_t image_base;
	size_t fixup_offset;
	size_t num_relocs;
	uint16_t *reloc;
	size_t relocd_offset;
	uint8_t *te_base;
	uint32_t adj;

	teih = te;

	if (read_le16(&teih->Signature) != EFI_TE_IMAGE_HEADER_SIGNATURE) {
		printk(BIOS_ERR, "TE Signature mismatch: %x vs %x\n",
			read_le16(&teih->Signature),
			EFI_TE_IMAGE_HEADER_SIGNATURE);
		return -1;
	}

	/*
	 * A TE image is created by converting a PE file. Because of this
	 * the offsets within the headers are off. In order to calculate
	 * the correct releative offets one needs to subtract fixup_offset
	 * from the encoded offets.  Similarly, the linked address of the
	 * program is found by adding the fixup_offset to the ImageBase.
	 */
	fixup_offset = read_le16(&teih->StrippedSize);
	fixup_offset -= sizeof(EFI_TE_IMAGE_HEADER);
	/* Keep track of a base that is correctly adjusted so that offsets
	 * can be used directly. */
	te_base = te;
	te_base -= fixup_offset;

	image_base = read_le64(&teih->ImageBase);
	adj = new_addr - (image_base + fixup_offset);

	printk(FSP_DBG_LVL, "TE Image %p -> %p adjust value: %x\n",
		(void *)image_base, (void *)new_addr, adj);

	/* Adjust ImageBase for consistency. */
	write_le64(&teih->ImageBase, (uint32_t)(image_base + adj));

	relocd = &teih->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC];

	relocd_offset = 0;
	/* Though the field name is VirtualAddress it's actually relative to
	 * the beginning of the image which is linked at ImageBase. */
	relocb = relative_offset(te,
			read_le32(&relocd->VirtualAddress) - fixup_offset);
	while (relocd_offset < read_le32(&relocd->Size)) {
		size_t rva_offset = read_le32(&relocb->VirtualAddress);

		printk(FSP_DBG_LVL, "Relocs for RVA offset %zx\n", rva_offset);
		num_relocs = read_le32(&relocb->SizeOfBlock) - sizeof(*relocb);
		num_relocs /= sizeof(uint16_t);
		reloc = relative_offset(relocb, sizeof(*relocb));

		printk(FSP_DBG_LVL, "Num relocs in block: %zx\n", num_relocs);

		while (num_relocs > 0) {
			uint16_t reloc_val = read_le16(reloc);
			int type = reloc_type(reloc_val);
			size_t offset = reloc_offset(reloc_val);

			printk(FSP_DBG_LVL, "reloc type %x offset %zx\n",
				type, offset);

			if (type == EFI_IMAGE_REL_BASED_HIGHLOW) {
				uint32_t *reloc_addr;
				uint32_t val;

				offset += rva_offset;
				reloc_addr = (void *)&te_base[offset];
				val = read_le32(reloc_addr);

				printk(FSP_DBG_LVL, "Adjusting %p %x -> %x\n",
					reloc_addr, val, val + adj);
				write_le32(reloc_addr, val + adj);
			} else if (type != EFI_IMAGE_REL_BASED_ABSOLUTE) {
				printk(BIOS_ERR, "Unknown reloc type: %x\n",
					type);
				return -1;
			}
			num_relocs--;
			reloc++;
		}

		/* Track consumption of relocation directory contents. */
		relocd_offset += read_le32(&relocb->SizeOfBlock);
		/* Get next relocation block to process. */
		relocb = relative_offset(relocb,
					read_le32(&relocb->SizeOfBlock));
	}

	return 0;
}
コード例 #16
0
ファイル: nif_file.hpp プロジェクト: hanikesn/openmw
 short getShort() { return read_le16(); }
コード例 #17
0
ファイル: nif_file.hpp プロジェクト: hanikesn/openmw
 unsigned short getUShort() { return read_le16(); }
コード例 #18
0
ファイル: codec_wav.cpp プロジェクト: AnsonX10/bitfighter
    wavStream(std::istream *_fstream)
      : alureStream(_fstream), format(0), dataStart(0)
    {
        ALubyte buffer[25];
        ALuint length;

        if(!fstream->read(reinterpret_cast<char*>(buffer), 12) ||
           memcmp(buffer, "RIFF", 4) != 0 || memcmp(buffer+8, "WAVE", 4) != 0)
            return;

        while(!dataStart || format == AL_NONE)
        {
            char tag[4];
            if(!fstream->read(tag, 4))
                break;

            /* read chunk length */
            length = read_le32(fstream);

            if(memcmp(tag, "fmt ", 4) == 0 && length >= 16)
            {
                /* Data type (should be 1 for PCM data, 3 for float PCM data,
                 * 7 for muLaw, and 17 for IMA4 data) */
                int type = read_le16(fstream);
                if(type != 0x0001 && type != 0x0003 && type != 0x0007 &&
                   type != 0x0011)
                    break;

                /* mono or stereo data */
                channels = read_le16(fstream);

                /* sample frequency */
                samplerate = read_le32(fstream);

                /* skip average bytes per second */
                fstream->ignore(4);

                /* bytes per block */
                blockAlign = read_le16(fstream);
                if(blockAlign == 0)
                    break;

                /* bits per sample */
                sampleSize = read_le16(fstream);

                length -= 16;

                /* Look for any extra data and try to find the format */
                ALuint extrabytes = 0;
                if(length >= 2)
                {
                    extrabytes = read_le16(fstream);
                    length -= 2;
                }
                extrabytes = std::min<ALuint>(extrabytes, length);

                if(type == 0x0001)
                    format = GetSampleFormat(channels, sampleSize, false);
                else if(type == 0x0003)
                    format = GetSampleFormat(channels, sampleSize, true);
                else if(type == 0x0007)
                {
                    if(sampleSize == 8)
                    {
                        if(channels == 1)
                            format = AL_FORMAT_MONO_MULAW;
                        else if(channels == 2)
                            format = AL_FORMAT_STEREO_MULAW;
                        else if(channels == 4)
                            format = AL_FORMAT_QUAD_MULAW;
                        else if(channels == 6)
                            format = AL_FORMAT_51CHN_MULAW;
                        else if(channels == 7)
                            format = AL_FORMAT_61CHN_MULAW;
                        else if(channels == 8)
                            format = AL_FORMAT_71CHN_MULAW;
                    }
                }
                else if(type == 0x0011 && extrabytes >= 2)
                {
                    int samples = read_le16(fstream);
                    length -= 2;

                    /* AL_EXT_IMA4 only supports 36 bytes-per-channel block
                     * alignment, which has 65 uncompressed sample frames */
                    if(blockAlign == 36*channels && samples == 65*channels &&
                       alIsExtensionPresent("AL_EXT_IMA4"))
                    {
                         if(channels == 1)
                             format = AL_FORMAT_MONO_IMA4;
                         else if(channels == 2)
                             format = AL_FORMAT_STEREO_IMA4;
                    }
                }
            }
            else if(memcmp(tag, "data", 4) == 0)
            {
                dataStart = fstream->tellg();
                dataLen = remLen = length;
            }

            fstream->seekg(length, std::ios_base::cur);
        }

        if(dataStart > 0 && format != AL_NONE)
            fstream->seekg(dataStart);
    }
コード例 #19
0
ファイル: wave.cpp プロジェクト: kcat/alure
ALuint WaveDecoder::read(ALvoid *ptr, ALuint count)
{
    mFile->clear();

    auto pos = mFile->tellg();
    size_t len = count * mFrameSize;
    ALuint total = 0;

    if(pos < mEnd)
    {
        len = std::min<std::istream::pos_type>(len, mEnd-pos);
#ifdef __BIG_ENDIAN__
        switch(mSampleType)
        {
            case SampleType_Float32:
                while(total < len && mFile->good() && !mFile->eof())
                {
                    char temp[256];
                    size_t todo = std::min(len-total, sizeof(temp));

                    mFile->read(temp, todo);
                    std::streamsize got = mFile->gcount();

                    for(std::streamsize i = 0;i < got;++i)
                        reinterpret_cast<char*>(ptr)[total+i] = temp[i^3];

                    total += got;
                }
                total /= mFrameSize;
                break;

            case SampleType_Int16:
                while(total < len && mFile->good() && !mFile->eof())
                {
                    char temp[256];
                    size_t todo = std::min(len-total, sizeof(temp));

                    mFile->read(temp, todo);
                    std::streamsize got = mFile->gcount();

                    for(std::streamsize i = 0;i < got;++i)
                        reinterpret_cast<char*>(ptr)[total+i] = temp[i^1];

                    total += got;
                }
                total /= mFrameSize;
                break;

            case SampleType_UInt8:
            case SampleType_Mulaw:
#else
        {
#endif
                mFile->read(reinterpret_cast<char*>(ptr), len);
                total = mFile->gcount() / mFrameSize;
        }
    }

    return total;
}


SharedPtr<Decoder> WaveDecoderFactory::createDecoder(SharedPtr<std::istream> file)
{
    ChannelConfig channels = ChannelConfig_Mono;
    SampleType type = SampleType_UInt8;
    ALuint frequency = 0;
    ALuint framesize = 0;
    ALuint loop_pts[2]{0, 0};
    ALuint blockalign = 0;
    ALuint framealign = 0;

    char tag[4]{};
    if(!file->read(tag, 4) || file->gcount() != 4 || memcmp(tag, "RIFF", 4) != 0)
        return SharedPtr<Decoder>(nullptr);
    ALuint totalsize = read_le32(*file) & ~1u;
    if(!file->read(tag, 4) || file->gcount() != 4 || memcmp(tag, "WAVE", 4) != 0)
        return SharedPtr<Decoder>(nullptr);

    while(file->good() && !file->eof() && totalsize > 8)
    {
        if(!file->read(tag, 4) || file->gcount() != 4)
            return SharedPtr<Decoder>(nullptr);
        ALuint size = read_le32(*file);
        if(size < 2)
            return SharedPtr<Decoder>(nullptr);
        totalsize -= 8;
        size = std::min((size+1) & ~1u, totalsize);
        totalsize -= size;

        if(memcmp(tag, "fmt ", 4) == 0)
        {
            /* 'fmt ' tag needs at least 16 bytes. */
            if(size < 16) goto next_chunk;

            /* format type */
            ALushort fmttype = read_le16(*file); size -= 2;

            /* mono or stereo data */
            int chancount = read_le16(*file); size -= 2;

            /* sample frequency */
            frequency = read_le32(*file); size -= 4;

            /* skip average bytes per second */
            read_le32(*file); size -= 4;

            /* bytes per block */
            blockalign = read_le16(*file); size -= 2;

            /* bits per sample */
            int bitdepth = read_le16(*file); size -= 2;

            /* Look for any extra data and try to find the format */
            ALuint extrabytes = 0;
            if(size >= 2)
            {
                extrabytes = read_le16(*file);
                size -= 2;
            }
            extrabytes = std::min<ALuint>(extrabytes, size);

            /* Format type should be 0x0001 for integer PCM data, 0x0003 for
             * float PCM data, 0x0007 for muLaw, and 0xFFFE extensible data.
             */
            if(fmttype == 0x0001)
            {
                if(chancount == 1)
                    channels = ChannelConfig_Mono;
                else if(chancount == 2)
                    channels = ChannelConfig_Stereo;
                else
                    goto next_chunk;

                if(bitdepth == 8)
                    type = SampleType_UInt8;
                else if(bitdepth == 16)
                    type = SampleType_Int16;
                else
                    goto next_chunk;
            }
            else if(fmttype == 0x0003)
            {
                if(chancount == 1)
                    channels = ChannelConfig_Mono;
                else if(chancount == 2)
                    channels = ChannelConfig_Stereo;
                else
                    goto next_chunk;

                if(bitdepth == 32)
                    type = SampleType_Float32;
                else
                    goto next_chunk;
            }
            else if(fmttype == 0x0007)
            {
                if(chancount == 1)
                    channels = ChannelConfig_Mono;
                else if(chancount == 2)
                    channels = ChannelConfig_Stereo;
                else
                    goto next_chunk;

                if(bitdepth == 8)
                    type = SampleType_Mulaw;
                else
                    goto next_chunk;
            }
            else if(fmttype == 0xFFFE)
            {
                if(size < 22)
                    goto next_chunk;

                char subtype[16];
                ALushort validbits = read_le16(*file); size -= 2;
                ALuint chanmask = read_le32(*file); size -= 4;
                file->read(subtype, 16); size -= file->gcount();

                /* Padded bit depths not supported */
                if(validbits != bitdepth)
                    goto next_chunk;

                if(memcmp(subtype, SUBTYPE_BFORMAT_PCM, 16) == 0 || memcmp(subtype, SUBTYPE_BFORMAT_FLOAT, 16) == 0)
                {
                    if(chanmask != 0)
                        goto next_chunk;

                    if(chancount == 3)
                        channels = ChannelConfig_BFmt_WXY;
                    else if(chancount == 4)
                        channels = ChannelConfig_BFmt_WXYZ;
                    else
                        goto next_chunk;
                }
                else if(memcmp(subtype, SUBTYPE_PCM, 16) == 0 || memcmp(subtype, SUBTYPE_FLOAT, 16) == 0)
                {
                    if(chancount == 1 && chanmask == CHANNELS_MONO)
                        channels = ChannelConfig_Mono;
                    else if(chancount == 2 && chanmask == CHANNELS_STEREO)
                        channels = ChannelConfig_Stereo;
                    else if(chancount == 4 && chanmask == CHANNELS_QUAD)
                        channels = ChannelConfig_Quad;
                    else if(chancount == 6 && (chanmask == CHANNELS_5DOT1 || chanmask == CHANNELS_5DOT1_REAR))
                        channels = ChannelConfig_X51;
                    else if(chancount == 7 && chanmask == CHANNELS_6DOT1)
                        channels = ChannelConfig_X61;
                    else if(chancount == 8 && chanmask == CHANNELS_7DOT1)
                        channels = ChannelConfig_X71;
                    else
                        goto next_chunk;
                }

                if(memcmp(subtype, SUBTYPE_PCM, 16) == 0 || memcmp(subtype, SUBTYPE_BFORMAT_PCM, 16) == 0)
                {
                    if(bitdepth == 8)
                        type = SampleType_UInt8;
                    else if(bitdepth == 16)
                        type = SampleType_Int16;
                    else
                        goto next_chunk;
                }
                else if(memcmp(subtype, SUBTYPE_FLOAT, 16) == 0 || memcmp(subtype, SUBTYPE_BFORMAT_FLOAT, 16) == 0)
                {
                    if(bitdepth == 32)
                        type = SampleType_Float32;
                    else
                        goto next_chunk;
                }
                else
                    goto next_chunk;
            }
            else
                goto next_chunk;

            framesize = FramesToBytes(1, channels, type);

            /* Calculate the number of frames per block (ADPCM will need extra
             * consideration). */
            framealign = blockalign / framesize;
        }
        else if(memcmp(tag, "smpl", 4) == 0)
        {
            /* sampler data needs at least 36 bytes */
            if(size < 36) goto next_chunk;

            /* Most of this only affects MIDI sampling, but we only care about
             * the loop definitions at the end. */
            /*ALuint manufacturer =*/ read_le32(*file);
            /*ALuint product =*/ read_le32(*file);
            /*ALuint smpperiod =*/ read_le32(*file);
            /*ALuint unitynote =*/ read_le32(*file);
            /*ALuint pitchfrac =*/ read_le32(*file);
            /*ALuint smptefmt =*/ read_le32(*file);
            /*ALuint smpteoffset =*/ read_le32(*file);
            ALuint loopcount = read_le32(*file);
            /*ALuint extrabytes =*/ read_le32(*file);
            size -= 36;

            for(ALuint i = 0;i < loopcount && size >= 24;++i)
            {
                /*ALuint id =*/ read_le32(*file);
                ALuint type = read_le32(*file);
                ALuint loopstart = read_le32(*file);
                ALuint loopend = read_le32(*file);
                /*ALuint frac =*/ read_le32(*file);
                ALuint numloops = read_le32(*file);
                size -= 24;

                /* Only handle indefinite forward loops. */
                if(type == 0 || numloops == 0)
                {
                    loop_pts[0] = loopstart;
                    loop_pts[1] = loopend;
                    break;
                }
            }
        }
        else if(memcmp(tag, "data", 4) == 0)
        {
            if(framesize == 0)
                goto next_chunk;

            /* Make sure there's at least one sample frame of audio data. */
            std::istream::pos_type start = file->tellg();
            std::istream::pos_type end = start + std::istream::pos_type(size - (size%framesize));
            if(end-start >= framesize)
            {
                /* Loop points are byte offsets relative to the data start.
                 * Convert to sample frame offsets. */
                return SharedPtr<Decoder>(new WaveDecoder(file,
                    channels, type, frequency, framesize, start, end,
                    loop_pts[0] / blockalign * framealign,
                    loop_pts[1] / blockalign * framealign
                ));
            }
        }

    next_chunk:
        if(size > 0)
            file->ignore(size);
    }

    return SharedPtr<Decoder>(nullptr);
}
コード例 #20
0
ファイル: jack.c プロジェクト: BG2BKK/cmus
static jack_default_audio_sample_t read_sample_le16(const char *buffer)
{
	int16_t s = (int16_t)read_le16(buffer);
	uint16_t upper_bound = (uint16_t)INT16_MAX + (s <= 0);
	return (jack_default_audio_sample_t)s / (jack_default_audio_sample_t)upper_bound;
}
コード例 #21
0
ファイル: jack.c プロジェクト: BG2BKK/cmus
static jack_default_audio_sample_t read_sample_le16u(const char *buffer)
{
	uint32_t u = read_le16(buffer);
	return (((jack_default_audio_sample_t) u)
		/ ((jack_default_audio_sample_t) UINT16_MAX)) * 2.0 - 2.0;
}
コード例 #22
0
ファイル: sf2load.c プロジェクト: 100GPing100/Loveprint
static void Zone_read(Zone *self, Reader *stream)
{
    self->mGenIdx = read_le16(stream);
    self->mModIdx = read_le16(stream);
}
コード例 #23
0
ファイル: sf2load.c プロジェクト: 100GPing100/Loveprint
static void Generator_read(Generator *self, Reader *stream)
{
    self->mGenerator = read_le16(stream);
    self->mAmount = read_le16(stream);
}
コード例 #24
0
ファイル: sf2load.c プロジェクト: 100GPing100/Loveprint
static void InstrumentHeader_read(InstrumentHeader *self, Reader *stream)
{
    Reader_read(stream, self->mName, sizeof(self->mName));
    self->mZoneIdx = read_le16(stream);
}