working dos vga writes!
This commit is contained in:
1 parent
5789cafd4e
commit
55ac075e4d
25 files changed
+454
-149
No files matched your search
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
Tracker program to create awesome music!
|
||||
Is supposed to only work on Linux, as it's where the development happens.
|
||||
*/
|
||||
|
||||
#include "../../Common/Snd/oscs.h"
|
||||
#include "../../Common/Std/libc.c"
|
||||
#include "../../Common/Timer/posix.c"
|
||||
#include "../../Common/fix.c"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct com_snd_swave swave = com_snd_swave_init(COM_CFG_A4FIX, 0, UINT16_MAX);
|
||||
|
||||
FILE *f = fopen("test.raw", "w");
|
||||
if (!f) {
|
||||
printf("Can't open file %s\n", "test.raw");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Generate 5 seconds of sinwave. */
|
||||
int16_t frames[COM_CFG_SNDFRMRATE * 5];
|
||||
for (int i = 0; i < COM_CFG_SNDFRMRATE * 5; ++i)
|
||||
frames[i] = com_snd_swave_pump(&swave);
|
||||
|
||||
fwrite(frames, 2, COM_CFG_SNDFRMRATE * 5, f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
Executable
+100
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env python3
|
||||
# Compression testing for image data for expected cases of ours.
|
||||
|
||||
# TODO: Implement our own CLI tool that uses our LZW implementation, as it differs.
|
||||
|
||||
import imageio.v3 as iio
|
||||
import ncompress
|
||||
import numpy as np
|
||||
import sys
|
||||
|
||||
uncompressed = iio.imread(sys.argv[1])
|
||||
compressed = ncompress.compress(uncompressed.tobytes())
|
||||
print("Uncompressed:", uncompressed.nbytes)
|
||||
print("Compressed:", len(compressed), len(compressed) / uncompressed.nbytes)
|
||||
|
||||
with open(sys.argv[1] + "-indexed.raw", "rb") as file:
|
||||
raw_bytes = file.read()
|
||||
indexmapping = {}
|
||||
indexset = set(raw_bytes)
|
||||
for idx, value in enumerate(indexset):
|
||||
indexmapping[value] = idx
|
||||
print(indexmapping)
|
||||
indexmap = np.zeros((uncompressed.shape[0] * uncompressed.shape[1], 1), dtype=np.uint8)
|
||||
for y in range(uncompressed.shape[0]):
|
||||
for x in range(uncompressed.shape[1]):
|
||||
indexmap[y * uncompressed.shape[0] + x] = indexmapping[raw_bytes[y * uncompressed.shape[0] + x]]
|
||||
indexedcompressed = ncompress.compress(indexmap.tobytes())
|
||||
print("Indexed:", len(indexedcompressed), len(indexedcompressed) / len(raw_bytes))
|
||||
|
||||
# https://arxiv.org/html/2006.02639v2
|
||||
def pixel_art_predictive_filter(image_channel):
|
||||
"""
|
||||
Applies a spatial prediction filter to a 2D image matrix
|
||||
to prepare it for lossless compression.
|
||||
"""
|
||||
rows, cols = image_channel.shape
|
||||
residual_map = np.zeros((rows, cols), dtype=np.int16)
|
||||
|
||||
for r in range(rows):
|
||||
for c in range(cols):
|
||||
# Handle edge cases (boundaries where neighbors don't exist)
|
||||
if r == 0 and c == 0:
|
||||
pred = 0
|
||||
elif r == 0:
|
||||
pred = image_channel[r, c-1] # Only Left neighbor exists
|
||||
elif c == 0:
|
||||
pred = image_channel[r-1, c] # Only Top neighbor exists
|
||||
else:
|
||||
# Core DSP Neighborhood definition
|
||||
A = image_channel[r, c-1] # Left
|
||||
B = image_channel[r-1, c] # Top
|
||||
C = image_channel[r-1, c-1] # Top-Left
|
||||
|
||||
# Median Edge Detector logic
|
||||
if C >= max(A, B):
|
||||
pred = min(A, B)
|
||||
elif C <= min(A, B):
|
||||
pred = max(A, B)
|
||||
else:
|
||||
pred = int(A) + int(B) - int(C)
|
||||
|
||||
# Map the actual value to the residual difference
|
||||
residual_map[r, c] = int(image_channel[r, c]) - int(pred)
|
||||
|
||||
return residual_map
|
||||
|
||||
predictivefilter = pixel_art_predictive_filter(indexmap)
|
||||
predictivefiltercompressed = ncompress.compress(predictivefilter.tobytes())
|
||||
print("Predictive filter:", len(predictivefiltercompressed), len(predictivefiltercompressed) / len(raw_bytes))
|
||||
|
||||
def encode_zorder_2d(x: int, y: int) -> int:
|
||||
z = 0
|
||||
for i in range(16):
|
||||
z |= ((x & (1 << i)) << i) | ((y & (1 << i)) << (i + 1))
|
||||
return z
|
||||
|
||||
zordered = np.zeros((uncompressed.shape[0] * uncompressed.shape[1], 1), dtype=np.uint8)
|
||||
for y in range(uncompressed.shape[0]):
|
||||
for x in range(uncompressed.shape[1]):
|
||||
idx = encode_zorder_2d(x, y)
|
||||
zordered[idx] = uncompressed[y, x]
|
||||
|
||||
zcompressed = ncompress.compress(zordered.tobytes())
|
||||
print("Zordered:", len(zcompressed), len(zcompressed) / uncompressed.nbytes)
|
||||
|
||||
delta = np.zeros((uncompressed.shape[0] * uncompressed.shape[1], 1), dtype=np.int8)
|
||||
for y in range(uncompressed.shape[0]):
|
||||
for x in range(uncompressed.shape[1]):
|
||||
delta[y * uncompressed.shape[0] + x] = int(uncompressed[y, x]) - int(uncompressed[y, (x + 1) % uncompressed.shape[0]])
|
||||
deltacompressed = ncompress.compress(delta.tobytes())
|
||||
print("Delta:", len(deltacompressed), len(deltacompressed) / uncompressed.nbytes)
|
||||
|
||||
deltaz = np.zeros((uncompressed.shape[0] * uncompressed.shape[1], 1), dtype=np.int8)
|
||||
for y in range(uncompressed.shape[0]):
|
||||
for x in range(uncompressed.shape[1]):
|
||||
idx = encode_zorder_2d(x, y)
|
||||
deltaz[idx] = int(uncompressed[y, x]) - int(uncompressed[y, (x + 1) % uncompressed.shape[0]])
|
||||
deltazcompressed = ncompress.compress(deltaz.tobytes())
|
||||
print("Deltaz:", len(deltazcompressed), len(deltazcompressed) / uncompressed.nbytes)
|
||||
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python3
|
||||
# Compression testing for sound sample data for expected cases of ours.
|
||||
|
||||
# TODO: Implement our own CLI tool that uses our LZW implementation, as it differs.
|
||||
|
||||
import ncompress
|
||||
import sys
|
||||
import wave
|
||||
import audioop
|
||||
import numpy as np
|
||||
import array
|
||||
|
||||
with wave.open(sys.argv[1], 'rb') as wf:
|
||||
channels = wf.getnchannels()
|
||||
samplerate = wf.getframerate()
|
||||
frames = wf.getnframes()
|
||||
uncompressed = wf.readframes(frames)
|
||||
depth = wf.getsampwidth()
|
||||
|
||||
compressed = ncompress.compress(uncompressed)
|
||||
print("Uncompressed:", len(uncompressed))
|
||||
print("Compressed:", len(compressed), len(compressed) / len(uncompressed))
|
||||
|
||||
delta = bytearray(uncompressed[0].to_bytes(2, signed=False))
|
||||
for i in range(len(uncompressed)-1):
|
||||
delta += (uncompressed[i+1] - uncompressed[i]).to_bytes(2, signed=True)
|
||||
|
||||
dtcompressed = ncompress.compress(bytes(delta))
|
||||
print("Delta:", len(dtcompressed), len(dtcompressed) / len(uncompressed))
|
||||
assert(len(delta) == len(uncompressed)*2)
|
||||
|
||||
ulaw = audioop.lin2ulaw(uncompressed, depth)
|
||||
ulawcompressed = ncompress.compress(ulaw)
|
||||
print("Ulaw:", len(ulawcompressed), len(ulawcompressed) / len(uncompressed))
|
||||
|
||||
absfold = bytearray()
|
||||
for i in range(len(uncompressed)):
|
||||
absfold.append(uncompressed[i] - 128 if uncompressed[i] >= 128 else uncompressed[i])
|
||||
absfoldulaw = audioop.lin2ulaw(absfold, depth)
|
||||
absfoldulawcompressed = ncompress.compress(absfoldulaw)
|
||||
print("Ulawabs:", len(absfoldulawcompressed), len(absfoldulawcompressed) / len(absfold))
|
||||
|
||||
with open(sys.argv[1] + ".ulaw", "wb") as file:
|
||||
file.write(audioop.ulaw2lin(ulaw, depth))
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env python3
|
||||
# Generator for sin/cos fixed point LUT tables.
|
||||
import math
|
||||
|
||||
def generate_pi():
|
||||
print(f"#define COM_FIXED_PI (com_fixed_t){int(math.pi * (1 << 16))}\n")
|
||||
|
||||
# Idea is to generate only one quadrant, as the values repeat later with different sign and order.
|
||||
def generate_sin_table(n_entries=128):
|
||||
r = []
|
||||
for n in range(n_entries):
|
||||
r += [math.sin(math.pi*n/(n_entries*2))]
|
||||
# r[n_entries-1]=1 # Make it converge to unit precisely
|
||||
print(f"static const uint16_t com_fixed_sin_lut[{n_entries}] =", "{", ",\n".join((str(int(a * (1 << 16))) for a in r)), "};\n")
|
||||
|
||||
generate_pi()
|
||||
generate_sin_table()
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
magick $1 -resize 32x32 +dither -type Palette -depth 8 -colors 16 PNG8:$1-indexed
|
||||
magick stream -map r -storage-type char $1-indexed $1-indexed.raw
|
||||
Reference in new issue
Block a user