Ejemplo n.º 1
0
def write_adsc(fname: str, data: np.array, header: dict = {}):
    """Write adsc format."""
    if 'SIZE1' not in header and 'SIZE2' not in header:
        dim2, dim1 = data.shape
        header['SIZE1'] = dim1
        header['SIZE2'] = dim2

    out = b'{\n'
    for key in header:
        out += '{:}={:};\n'.format(key, header[key]).encode()
    if 'HEADER_BYTES' in header:
        pad = int(header['HEADER_BYTES']) - len(out) - 2
    else:
        #         hsize = ((len(out) + 23) // 512 + 1) * 512
        hsize = (len(out) + 533) & ~(512 - 1)
        out += f'HEADER_BYTES={hsize:d};\n'.encode()
        pad = hsize - len(out) - 2
    out += b'}' + (pad + 1) * b'\x00'
    assert len(out) % 512 == 0, 'Header is not multiple of 512'

    # NOTE: XDS can handle only "SMV" images of TYPE=unsigned_short.
    dtype = np.uint16
    data = np.round(data, 0).astype(
        dtype, copy=False
    )  # copy=False ensures that no copy is made if dtype is already satisfied
    if swap_needed(header):
        data.byteswap(True)

    with open(fname, 'wb') as outf:
        outf.write(out)
        outf.write(data.tostring())
Ejemplo n.º 2
0
def write_adsc(fname: str, data: np.array, header: dict = {}):
    """
    Write adsc format
    """
    out = b'{\n'
    for key in header:
        out += "{:}={:};\n".format(key, header[key]).encode()
    if "HEADER_BYTES" in header:
        pad = int(header["HEADER_BYTES"]) - len(out) - 2
    else:
        #         hsize = ((len(out) + 23) // 512 + 1) * 512
        hsize = (len(out) + 533) & ~(512 - 1)
        out += "HEADER_BYTES={:d};\n".format(hsize).encode()
        pad = hsize - len(out) - 2
    out += b"}" + (pad + 1) * b'\x00'
    assert len(out) % 512 == 0, "Header is not multiple of 512"

    # NOTE: XDS can handle only "SMV" images of TYPE=unsigned_short.
    dtype = np.uint16
    data = np.round(data, 0).astype(
        dtype, copy=False
    )  # copy=False ensures that no copy is made if dtype is already satisfied
    if swap_needed(header):
        data.byteswap(True)

    with open(fname, "wb") as outf:
        outf.write(out)
        outf.write(data.tostring())
Ejemplo n.º 3
0
def write_wav(handle: T.IO[bytes], rate: int, data: np.array) -> None:
    """Write a numpy array of samples as a single uncompressed WAV file.

    To write multiple-channels, use a 2-D array of shape (Nsamples, Nchannels).
    The bits-per-sample and PCM/float will be determined by the data-type.

    :param handle: handle to write the file to
    :param rate: the sample rate in samples/sec
    :param data: a 1D or 2D numpy array of either integer or float data-type
    """
    dkind = data.dtype.kind

    if not (dkind == "i" or dkind == "f" or
            (dkind == "u" and data.dtype.itemsize == 1)):
        raise ValueError(f"unsupported data type {data.dtype!r}")

    header_data = b"RIFF"
    header_data += b"\x00\x00\x00\x00"
    header_data += b"WAVE"

    # fmt chunk
    header_data += b"fmt "
    if dkind == "f":
        format_tag = WAVE_FORMAT_IEEE_FLOAT
    else:
        format_tag = WAVE_FORMAT_PCM
    if data.ndim == 1:
        channels = 1
    else:
        channels = data.shape[1]

    bit_depth = data.dtype.itemsize * 8
    bytes_per_second = rate * (bit_depth // 8) * channels
    block_align = channels * (bit_depth // 8)

    fmt_chunk_data = struct.pack(
        "<HHIIHH",
        format_tag,
        channels,
        rate,
        bytes_per_second,
        block_align,
        bit_depth,
    )
    if dkind not in "iu":
        # add cbSize field for non-PCM files
        fmt_chunk_data += b"\x00\x00"

    header_data += struct.pack("<I", len(fmt_chunk_data))
    header_data += fmt_chunk_data

    # fact chunk (non-PCM files)
    if dkind not in "iu":
        header_data += b"fact"
        header_data += struct.pack("<II", 4, data.shape[0])

    # check data size (needs to be immediately before the data chunk)
    if ((len(header_data) - 4 - 4) + (4 + 4 + data.nbytes)) > 0xFFFFFFFF:
        raise ValueError("data exceeds wave file size limit")

    handle.write(header_data)
    handle.write(b"data")
    handle.write(struct.pack("<I", data.nbytes))
    if data.dtype.byteorder == ">" or (data.dtype.byteorder == "="
                                       and sys.byteorder == "big"):
        data = data.byteswap()
    handle.write(data.ravel().view("b").data)

    # Determine file size and place it at start of the file.
    size = handle.tell()
    handle.seek(4)
    handle.write(struct.pack("<I", size - 8))