add random stuffs
This commit is contained in:
401
Nbt.cs
Normal file
401
Nbt.cs
Normal file
@@ -0,0 +1,401 @@
|
|||||||
|
// an implementation of nbt format reader/writer
|
||||||
|
// NBTFile only supports .ToBytes() and .FromBytes() methods because i am lazy to do others
|
||||||
|
// not sure does it actually work i tested it last time like 4 months ago
|
||||||
|
|
||||||
|
namespace Nbt;
|
||||||
|
|
||||||
|
public enum CompressionType {
|
||||||
|
GZipCompressed = 1,
|
||||||
|
ZLibCompressed = 2,
|
||||||
|
Uncompressed = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class BinaryReader2(Stream stream) : BinaryReader(stream, System.Text.Encoding.UTF8, true) {
|
||||||
|
private Span<byte> ReadBytesReversed(int count) {
|
||||||
|
var data = base.ReadBytes(count);
|
||||||
|
Array.Reverse(data);
|
||||||
|
return new Span<byte>(data);
|
||||||
|
}
|
||||||
|
public override short ReadInt16() {
|
||||||
|
return BitConverter.ToInt16(ReadBytesReversed(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ushort ReadUInt16() {
|
||||||
|
return BitConverter.ToUInt16(ReadBytesReversed(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint ReadUInt24() {
|
||||||
|
return (uint)ReadByte() << 16 | (uint)ReadByte() << 8 | ReadByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override uint ReadUInt32() {
|
||||||
|
return BitConverter.ToUInt32(ReadBytesReversed(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int ReadInt32() {
|
||||||
|
return BitConverter.ToInt32(ReadBytesReversed(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long ReadInt64() {
|
||||||
|
return BitConverter.ToInt64(ReadBytesReversed(8));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override float ReadSingle() {
|
||||||
|
return BitConverter.ToSingle(ReadBytesReversed(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override double ReadDouble() {
|
||||||
|
return BitConverter.ToDouble(ReadBytesReversed(8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class BinaryWriter2(Stream stream) : BinaryWriter(stream) {
|
||||||
|
public override void Write(short value) {
|
||||||
|
var data = BitConverter.GetBytes(value);
|
||||||
|
Array.Reverse(data);
|
||||||
|
base.Write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(ushort value) {
|
||||||
|
var data = BitConverter.GetBytes(value);
|
||||||
|
Array.Reverse(data);
|
||||||
|
base.Write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteUInt24(uint value) {
|
||||||
|
Write((byte)value);
|
||||||
|
Write((byte)(value >> 8));
|
||||||
|
Write((byte)(value >> 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(uint value) {
|
||||||
|
var data = BitConverter.GetBytes(value);
|
||||||
|
Array.Reverse(data);
|
||||||
|
base.Write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(int value) {
|
||||||
|
var data = BitConverter.GetBytes(value);
|
||||||
|
Array.Reverse(data);
|
||||||
|
base.Write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(long value) {
|
||||||
|
var data = BitConverter.GetBytes(value);
|
||||||
|
Array.Reverse(data);
|
||||||
|
base.Write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(float value) {
|
||||||
|
var data = BitConverter.GetBytes(value);
|
||||||
|
Array.Reverse(data);
|
||||||
|
base.Write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(double value) {
|
||||||
|
var data = BitConverter.GetBytes(value);
|
||||||
|
Array.Reverse(data);
|
||||||
|
base.Write(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TAG_ID : byte {
|
||||||
|
TAG_End,
|
||||||
|
TAG_Byte,
|
||||||
|
TAG_Short,
|
||||||
|
TAG_Int,
|
||||||
|
TAG_Long,
|
||||||
|
TAG_Float,
|
||||||
|
TAG_Double,
|
||||||
|
TAG_Byte_Array,
|
||||||
|
TAG_String,
|
||||||
|
TAG_List,
|
||||||
|
TAG_Compound,
|
||||||
|
TAG_Int_Array,
|
||||||
|
TAG_Long_Array
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ITag {
|
||||||
|
TAG_ID Id { get; }
|
||||||
|
string Name { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class TAG<T>(string name, T value) : ITag {
|
||||||
|
public abstract TAG_ID Id { get; }
|
||||||
|
public string Name { get; set; } = name;
|
||||||
|
public T Value { get; } = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class TAG_Array<T>(string name, List<T> value) : TAG<List<T>>(name, value), IList<T> {
|
||||||
|
public void Add(T item) => Value.Add(item);
|
||||||
|
public void Clear() => Value.Clear();
|
||||||
|
public bool Contains(T item) => Value.Contains(item);
|
||||||
|
public void CopyTo(T[] array, int arrayIndex) => Value.CopyTo(array, arrayIndex);
|
||||||
|
public int Count => Value.Count;
|
||||||
|
public bool IsReadOnly => false;
|
||||||
|
public bool Remove(T item) => Value.Remove(item);
|
||||||
|
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => Value.GetEnumerator();
|
||||||
|
public int IndexOf(T item) => Value.IndexOf(item);
|
||||||
|
public IEnumerator<T> GetEnumerator() => Value.GetEnumerator();
|
||||||
|
public void Insert(int index, T item) => Value.Insert(index, item);
|
||||||
|
public void RemoveAt(int index) => Value.RemoveAt(index);
|
||||||
|
public T this[int index] {
|
||||||
|
get => Value[index];
|
||||||
|
set => Value[index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TAG_End() : TAG<object?>("", null) {
|
||||||
|
public override TAG_ID Id => TAG_ID.TAG_End;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TAG_Byte(string name, byte value) : TAG<byte>(name, value) {
|
||||||
|
public override TAG_ID Id => TAG_ID.TAG_Byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TAG_Short(string name, short value) : TAG<short>(name, value) {
|
||||||
|
public override TAG_ID Id => TAG_ID.TAG_Short;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TAG_Int(string name, int value) : TAG<int>(name, value) {
|
||||||
|
public override TAG_ID Id => TAG_ID.TAG_Int;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TAG_Long(string name, long value) : TAG<long>(name, value) {
|
||||||
|
public override TAG_ID Id => TAG_ID.TAG_Long;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TAG_Float(string name, float value) : TAG<float>(name, value) {
|
||||||
|
public override TAG_ID Id => TAG_ID.TAG_Float;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TAG_Double(string name, double value) : TAG<double>(name, value) {
|
||||||
|
public override TAG_ID Id => TAG_ID.TAG_Double;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TAG_Byte_Array(string name, List<sbyte> value) : TAG_Array<sbyte>(name, value) {
|
||||||
|
public override TAG_ID Id => TAG_ID.TAG_Byte_Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TAG_String(string name, string value) : TAG<string>(name, value) {
|
||||||
|
public override TAG_ID Id => TAG_ID.TAG_String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TAG_List(string name, List<ITag> value, TAG_ID tagsId) : TAG_Array<ITag>(name, value) {
|
||||||
|
public override TAG_ID Id => TAG_ID.TAG_List;
|
||||||
|
public TAG_ID tagsId = tagsId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TAG_Compound(string name, List<ITag> value) : TAG_Array<ITag>(name, value) {
|
||||||
|
public override TAG_ID Id => TAG_ID.TAG_Compound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TAG_Int_Array(string name, List<int> value) : TAG_Array<int>(name, value) {
|
||||||
|
public override TAG_ID Id => TAG_ID.TAG_Int_Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TAG_Long_Array(string name, List<long> value) : TAG_Array<long>(name, value) {
|
||||||
|
public override TAG_ID Id => TAG_ID.TAG_Long_Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NBTFile(string name, List<ITag> value) : TAG_Compound(name, value) {
|
||||||
|
private static string ReadString(BinaryReader2 reader) {
|
||||||
|
ushort length = reader.ReadUInt16();
|
||||||
|
string s = System.Text.Encoding.UTF8.GetString(reader.ReadBytes(length));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TAG_List ReadList(string name, BinaryReader2 reader) {
|
||||||
|
TAG_ID id = (TAG_ID)reader.ReadByte();
|
||||||
|
int length = reader.ReadInt32();
|
||||||
|
var list = new List<ITag>(length);
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
list.Add(ReadTag(id, "", reader));
|
||||||
|
|
||||||
|
return new TAG_List(name, list, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TAG_Compound ReadCompound(string name, BinaryReader2 reader) {
|
||||||
|
List<ITag> tags = [];
|
||||||
|
while (true) {
|
||||||
|
ITag tag = ReadTagWithPrefix(reader);
|
||||||
|
if (tag.Id == TAG_ID.TAG_End) break;
|
||||||
|
tags.Add(tag);
|
||||||
|
}
|
||||||
|
return new TAG_Compound(name, tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TAG_Byte_Array ReadByteArray(string name, BinaryReader2 reader) {
|
||||||
|
int length = reader.ReadInt32();
|
||||||
|
var list = new List<sbyte>(length);
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
list.Add(reader.ReadSByte());
|
||||||
|
|
||||||
|
return new TAG_Byte_Array(name, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TAG_Int_Array ReadIntArray(string name, BinaryReader2 reader) {
|
||||||
|
int length = reader.ReadInt32();
|
||||||
|
var list = new List<int>(length);
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
list.Add(reader.ReadInt32());
|
||||||
|
|
||||||
|
return new TAG_Int_Array(name, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TAG_Long_Array ReadLongArray(string name, BinaryReader2 reader) {
|
||||||
|
int length = reader.ReadInt32();
|
||||||
|
var list = new List<long>(length);
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
list.Add(reader.ReadInt64());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new TAG_Long_Array(name, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ITag ReadTag(TAG_ID id, string name, BinaryReader2 reader) => id switch {
|
||||||
|
TAG_ID.TAG_End => new TAG_End(),
|
||||||
|
TAG_ID.TAG_Byte => new TAG_Byte(name, reader.ReadByte()),
|
||||||
|
TAG_ID.TAG_Short => new TAG_Short(name, reader.ReadInt16()),
|
||||||
|
TAG_ID.TAG_Int => new TAG_Int(name, reader.ReadInt32()),
|
||||||
|
TAG_ID.TAG_Long => new TAG_Long(name, reader.ReadInt64()),
|
||||||
|
TAG_ID.TAG_Float => new TAG_Float(name, reader.ReadSingle()),
|
||||||
|
TAG_ID.TAG_Double => new TAG_Double(name, reader.ReadDouble()),
|
||||||
|
TAG_ID.TAG_Byte_Array => ReadByteArray(name, reader),
|
||||||
|
TAG_ID.TAG_String => new TAG_String(name, ReadString(reader)),
|
||||||
|
TAG_ID.TAG_List => ReadList(name, reader),
|
||||||
|
TAG_ID.TAG_Compound => ReadCompound(name, reader),
|
||||||
|
TAG_ID.TAG_Int_Array => ReadIntArray(name, reader),
|
||||||
|
TAG_ID.TAG_Long_Array => ReadLongArray(name, reader),
|
||||||
|
_ => throw new NotSupportedException($"Unknown tag type: {id}"),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static ITag ReadTagWithPrefix(BinaryReader2 reader) {
|
||||||
|
TAG_ID id = (TAG_ID)reader.ReadByte();
|
||||||
|
string name = id == TAG_ID.TAG_End ? "" : ReadString(reader);
|
||||||
|
return ReadTag(id, name, reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NBTFile FromReader(BinaryReader2 reader) {
|
||||||
|
var tags = ReadTagWithPrefix(reader);
|
||||||
|
if (tags.Id == TAG_ID.TAG_Compound) return new NBTFile(tags.Name, ((TAG_Compound)tags).Value);
|
||||||
|
throw new FormatException("The file is not TAG_Compound.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NBTFile FromBytes(byte[] bytes) => FromReader(new BinaryReader2(bytes[0] switch {
|
||||||
|
0x0A => new MemoryStream(bytes),
|
||||||
|
0x1F when bytes[1] == 0x8B => new System.IO.Compression.GZipStream(new MemoryStream(bytes), System.IO.Compression.CompressionMode.Decompress),
|
||||||
|
0x78 when bytes[1] == 0x9C || bytes[1] == 0xDA => new System.IO.Compression.ZLibStream(new MemoryStream(bytes), System.IO.Compression.CompressionMode.Decompress),
|
||||||
|
_ => throw new FormatException("Unknown compression type.")
|
||||||
|
}));
|
||||||
|
|
||||||
|
private static void WriteString(string s, BinaryWriter2 writer) {
|
||||||
|
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(s);
|
||||||
|
writer.Write((ushort)bytes.Length);
|
||||||
|
writer.Write(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteList(TAG_List list, BinaryWriter2 writer) {
|
||||||
|
writer.Write((byte)list.tagsId);
|
||||||
|
writer.Write(list.Count);
|
||||||
|
|
||||||
|
foreach (ITag tag in list) {
|
||||||
|
if (tag.Id != list.tagsId)
|
||||||
|
throw new ArgumentException($"Expected {list.tagsId} in TAG_List, not {tag.Id}");
|
||||||
|
WriteTag(tag, writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteCompound(TAG_Compound compound, BinaryWriter2 writer) {
|
||||||
|
foreach (ITag tag in compound)
|
||||||
|
WriteTagWithPrefix(tag, writer);
|
||||||
|
writer.Write((byte)TAG_ID.TAG_End);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteByteArray(TAG_Byte_Array byteArray, BinaryWriter2 writer) {
|
||||||
|
writer.Write(byteArray.Count);
|
||||||
|
|
||||||
|
foreach (sbyte b in byteArray)
|
||||||
|
writer.Write(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteIntArray(TAG_Int_Array intArray, BinaryWriter2 writer) {
|
||||||
|
writer.Write(intArray.Count);
|
||||||
|
|
||||||
|
foreach (int i in intArray) {
|
||||||
|
writer.Write(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteLongArray(TAG_Long_Array longArray, BinaryWriter2 writer) {
|
||||||
|
writer.Write(longArray.Count);
|
||||||
|
|
||||||
|
foreach (long l in longArray)
|
||||||
|
writer.Write(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteTag(ITag tag, BinaryWriter2 writer) {
|
||||||
|
switch (tag.Id) {
|
||||||
|
case TAG_ID.TAG_Byte:
|
||||||
|
writer.Write(((TAG_Byte)tag).Value);
|
||||||
|
break;
|
||||||
|
case TAG_ID.TAG_Short:
|
||||||
|
writer.Write(((TAG_Short)tag).Value);
|
||||||
|
break;
|
||||||
|
case TAG_ID.TAG_Int:
|
||||||
|
writer.Write(((TAG_Int)tag).Value);
|
||||||
|
break;
|
||||||
|
case TAG_ID.TAG_Long:
|
||||||
|
writer.Write(((TAG_Long)tag).Value);
|
||||||
|
break;
|
||||||
|
case TAG_ID.TAG_Float:
|
||||||
|
writer.Write(((TAG_Float)tag).Value);
|
||||||
|
break;
|
||||||
|
case TAG_ID.TAG_Double:
|
||||||
|
writer.Write(((TAG_Double)tag).Value);
|
||||||
|
break;
|
||||||
|
case TAG_ID.TAG_Byte_Array:
|
||||||
|
WriteByteArray((TAG_Byte_Array)tag, writer);
|
||||||
|
break;
|
||||||
|
case TAG_ID.TAG_String:
|
||||||
|
WriteString(((TAG_String)tag).Value, writer);
|
||||||
|
break;
|
||||||
|
case TAG_ID.TAG_List:
|
||||||
|
WriteList((TAG_List)tag, writer);
|
||||||
|
break;
|
||||||
|
case TAG_ID.TAG_Compound:
|
||||||
|
WriteCompound((TAG_Compound)tag, writer);
|
||||||
|
break;
|
||||||
|
case TAG_ID.TAG_Int_Array:
|
||||||
|
WriteIntArray((TAG_Int_Array)tag, writer);
|
||||||
|
break;
|
||||||
|
case TAG_ID.TAG_Long_Array:
|
||||||
|
WriteLongArray((TAG_Long_Array)tag, writer);
|
||||||
|
break;
|
||||||
|
case TAG_ID.TAG_End:
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException($"Unknown tag type: {tag.Id}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteTagWithPrefix(ITag tag, BinaryWriter2 writer) {
|
||||||
|
writer.Write((byte)tag.Id);
|
||||||
|
WriteString(tag.Name, writer);
|
||||||
|
WriteTag(tag, writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] ToBytes(CompressionType compression = CompressionType.GZipCompressed) {
|
||||||
|
MemoryStream memoryStream = new();
|
||||||
|
WriteTagWithPrefix(this, new BinaryWriter2(compression switch {
|
||||||
|
CompressionType.Uncompressed => memoryStream,
|
||||||
|
CompressionType.GZipCompressed => new System.IO.Compression.GZipStream(memoryStream, System.IO.Compression.CompressionMode.Compress),
|
||||||
|
CompressionType.ZLibCompressed => new System.IO.Compression.ZLibStream(memoryStream, System.IO.Compression.CompressionMode.Compress),
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(compression), compression, null)
|
||||||
|
}));
|
||||||
|
return memoryStream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
123
audiosort.c
Normal file
123
audiosort.c
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
// gcc audiosort.c -o audiosort -O3
|
||||||
|
// this for me so i don't lose later:
|
||||||
|
// gcc audiosort.c -o audiosort -O0 -Wall -Wextra -Werror -Wno-unused-result
|
||||||
|
// requires ffmpeg
|
||||||
|
// ./audiosort <input_file> <output_file>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 4800
|
||||||
|
#define conststrlen(s) ((sizeof(s))-1)
|
||||||
|
typedef short sample_t;
|
||||||
|
|
||||||
|
static void* safe_malloc(const size_t bytes) {
|
||||||
|
void* ptr = malloc(bytes);
|
||||||
|
if (ptr == NULL) exit(1);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define put_some_shit(text) do { \
|
||||||
|
memcpy(ptr, text, conststrlen(text)); \
|
||||||
|
ptr += conststrlen(text); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define put_SINGLE_shit(c) do { \
|
||||||
|
*ptr++ = c; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
static FILE* get_input_pipe(const char* filename) {
|
||||||
|
size_t len = conststrlen("ffmpeg -i") + conststrlen(" -f s16le -ar 48000 -ac 2 -") + 1;
|
||||||
|
for (const char* s = filename; *s; s++, len += 1 + (*s == ' ')) {}
|
||||||
|
|
||||||
|
char* command = safe_malloc(len);
|
||||||
|
char* ptr = command;
|
||||||
|
|
||||||
|
put_some_shit("ffmpeg -i ");
|
||||||
|
|
||||||
|
for (const char* c = filename; *c; c++) {
|
||||||
|
if (*c == ' ') put_SINGLE_shit('\\');
|
||||||
|
put_SINGLE_shit(*c);
|
||||||
|
}
|
||||||
|
|
||||||
|
put_some_shit(" -f s16le -ar 48000 -ac 2 -");
|
||||||
|
put_SINGLE_shit('\0');
|
||||||
|
|
||||||
|
FILE* pipe = popen(command, "r");
|
||||||
|
free(command);
|
||||||
|
if (pipe == NULL) exit(1);
|
||||||
|
return pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FILE* get_output_pipe(const char* filename) {
|
||||||
|
size_t len = conststrlen("ffmpeg -f s16le -ar 48k -ac 2 -i pipe: -y ") + 1;
|
||||||
|
for (const char* s = filename; *s; s++, len += 1 + (*s == ' ')) {}
|
||||||
|
|
||||||
|
char* command = safe_malloc(len);
|
||||||
|
char* ptr = command;
|
||||||
|
|
||||||
|
put_some_shit("ffmpeg -f s16le -ar 48k -ac 2 -i pipe: -y ");
|
||||||
|
|
||||||
|
for (const char* c = filename; *c; c++) {
|
||||||
|
if (*c == ' ') put_SINGLE_shit('\\');
|
||||||
|
put_SINGLE_shit(*c);
|
||||||
|
}
|
||||||
|
|
||||||
|
put_SINGLE_shit('\0');
|
||||||
|
|
||||||
|
FILE* pipe = popen(command, "w");
|
||||||
|
free(command);
|
||||||
|
if (pipe == NULL) exit(1);
|
||||||
|
return pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_buffers_count(FILE* file) {
|
||||||
|
int size = 0;
|
||||||
|
int16_t buffer[BUFFER_SIZE];
|
||||||
|
while (1) {
|
||||||
|
if (fread(buffer, sizeof(sample_t), BUFFER_SIZE, file) == 0) break;
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sample_sorter(const void* a, const void* b) {
|
||||||
|
int64_t diff = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < BUFFER_SIZE; i++) {
|
||||||
|
diff += abs((*(sample_t**)a)[i]) - abs((*(sample_t**)b)[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (diff > 0) - (diff < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(const int argc, const char* argv[]) {
|
||||||
|
if (argc < 3) {
|
||||||
|
fprintf(stderr, "Usage: %s <input_file> <output_file>\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
FILE* input = get_input_pipe(argv[1]);
|
||||||
|
const int bufc = get_buffers_count(input);
|
||||||
|
pclose(input);
|
||||||
|
|
||||||
|
input = get_input_pipe(argv[1]);
|
||||||
|
sample_t** pcm = safe_malloc(sizeof(sample_t*) * bufc);
|
||||||
|
for (int i = 0; i < bufc; i++) {
|
||||||
|
pcm[i] = safe_malloc(sizeof(sample_t) * BUFFER_SIZE);
|
||||||
|
fread(pcm[i], sizeof(sample_t), BUFFER_SIZE, input);
|
||||||
|
}
|
||||||
|
pclose(input);
|
||||||
|
|
||||||
|
qsort(pcm, bufc, sizeof(sample_t*), sample_sorter);
|
||||||
|
|
||||||
|
FILE* output = get_output_pipe(argv[2]);
|
||||||
|
for (int i = 0; i < bufc; i++) {
|
||||||
|
fwrite(pcm[i], sizeof(sample_t), BUFFER_SIZE, output);
|
||||||
|
free(pcm[i]);
|
||||||
|
}
|
||||||
|
pclose(output);
|
||||||
|
free(pcm);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
32
closest_path_command.c
Normal file
32
closest_path_command.c
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include "levenshtein.h"
|
||||||
|
#include "cstring_node.h"
|
||||||
|
#include "exit_error.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
if (argc != 2) exit_error("Usage: %s <command>\n", argv[0]);
|
||||||
|
|
||||||
|
cstring_node* commands = get_path_commands();
|
||||||
|
if (!commands) exit_error("No commands found.\n");
|
||||||
|
|
||||||
|
char* closest = NULL;
|
||||||
|
int min_distance = INT_MAX;
|
||||||
|
|
||||||
|
for (cstring_node* curr = commands; curr; curr = curr->next) {
|
||||||
|
int distance = levenshtein(argv[1], curr->name);
|
||||||
|
if (distance < min_distance) {
|
||||||
|
min_distance = distance;
|
||||||
|
free(closest);
|
||||||
|
closest = strdup(curr->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Did you mean '%s'?\n", closest);
|
||||||
|
|
||||||
|
free(closest);
|
||||||
|
free_commands(commands);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
60
cstring_node.h
Normal file
60
cstring_node.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
typedef struct cstring_node {
|
||||||
|
char* name;
|
||||||
|
struct cstring_node* next;
|
||||||
|
} cstring_node;
|
||||||
|
|
||||||
|
static inline void insert_command(cstring_node** head, const char* command) {
|
||||||
|
for (cstring_node* curr = *head; curr != NULL; curr = curr->next) {
|
||||||
|
if (strcmp(curr->name, command) == 0) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cstring_node* node = (cstring_node*)malloc(sizeof(cstring_node));
|
||||||
|
if (!node) return;
|
||||||
|
|
||||||
|
node->name = strdup(command);
|
||||||
|
if (!node->name) {
|
||||||
|
free(node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->next = *head;
|
||||||
|
*head = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void free_commands(cstring_node* head) {
|
||||||
|
while (head) {
|
||||||
|
cstring_node* next = head->next;
|
||||||
|
free(head->name);
|
||||||
|
free(head);
|
||||||
|
head = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline cstring_node* get_path_commands() {
|
||||||
|
char* path_env = getenv("PATH");
|
||||||
|
if (!path_env) return NULL;
|
||||||
|
|
||||||
|
cstring_node* head = NULL;
|
||||||
|
char* path_copy = strdup(path_env);
|
||||||
|
|
||||||
|
for (char* dir = strtok(path_copy, ":"); dir != NULL; dir = strtok(NULL, ":")) {
|
||||||
|
DIR* d = opendir(dir);
|
||||||
|
if (!d) continue;
|
||||||
|
|
||||||
|
struct dirent* entry;
|
||||||
|
while ((entry = readdir(d)) != NULL) {
|
||||||
|
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
|
||||||
|
insert_command(&head, entry->d_name);
|
||||||
|
}
|
||||||
|
closedir(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(path_copy);
|
||||||
|
return head;
|
||||||
|
}
|
||||||
13
exit_error.h
Normal file
13
exit_error.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
_Noreturn static inline void exit_error(const char* format, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
vfprintf(stderr, format, args);
|
||||||
|
va_end(args);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
15
forkmeower.c
Normal file
15
forkmeower.c
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
// gcc forkmeower.c -o forkmeower -O3
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#define f fork()
|
||||||
|
|
||||||
|
#ifndef _Countof
|
||||||
|
#define _Countof(a) (sizeof(a)/sizeof(a[0]))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char* meow[] = {"nya ", "miao ", "meow ", "mew ", ":3 ", "mrrp ", "miaow ", "prrr ", "mewp "};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
fputs(meow[(f^f^f^f^f^f^f^f)%_Countof(meow)], stdout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
106
graphics2d.hpp
Normal file
106
graphics2d.hpp
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
struct RGBColor {
|
||||||
|
uint8_t r = 255;
|
||||||
|
uint8_t g = 255;
|
||||||
|
uint8_t b = 255;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Window {
|
||||||
|
SDL_Window* window;
|
||||||
|
SDL_Renderer* renderer;
|
||||||
|
public:
|
||||||
|
Window(const char* name, const int w, const int h) {
|
||||||
|
if (SDL_Init(SDL_INIT_EVERYTHING) < 0 ||
|
||||||
|
!((window = SDL_CreateWindow(name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, SDL_WINDOW_SHOWN))) ||
|
||||||
|
!((renderer = SDL_CreateRenderer(window, -1, 0)))
|
||||||
|
) exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scale(const float x, const float y) const {
|
||||||
|
SDL_RenderSetScale(renderer, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void close() const {
|
||||||
|
SDL_DestroyRenderer(renderer);
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
SDL_Quit();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rect(const int x, const int y, const int w, const int h, const RGBColor c) const {
|
||||||
|
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 255);
|
||||||
|
SDL_Rect rect_ = {x, y, w, h};
|
||||||
|
SDL_RenderFillRect(renderer, &rect_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pixel(const int x, const int y, const RGBColor c) const {
|
||||||
|
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 255);
|
||||||
|
SDL_RenderDrawPoint(renderer, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void circle(const int x, const int y, const int radius, const RGBColor c) const {
|
||||||
|
for (int i = 0; i < radius*2; i++) {
|
||||||
|
for (int j = 0; j < radius*2; j++) {
|
||||||
|
int dx = i - radius;
|
||||||
|
int dy = j - radius;
|
||||||
|
int distance = dx * dx + dy * dy;
|
||||||
|
|
||||||
|
if ((radius - 1) * (radius - 1) <= distance && distance <= radius * radius) {
|
||||||
|
pixel(x - radius + i, y - radius + j, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void line(const int x1, const int y1, const int x2, const int y2, const RGBColor c) const {
|
||||||
|
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 255);
|
||||||
|
SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rect_outline(const int x1, const int y1, const int w, const int h, const RGBColor c) const {
|
||||||
|
line(x1, y1, x1 + w, y1, c);
|
||||||
|
line(x1 + w, y1, x1 + w, y1 + h, c);
|
||||||
|
line(x1 + w, y1 + h, x1, y1 + h, c);
|
||||||
|
line(x1, y1 + h, x1, y1, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void input() const {
|
||||||
|
SDL_Event e;
|
||||||
|
while (SDL_PollEvent(&e)) {
|
||||||
|
if (e.type == SDL_QUIT) {
|
||||||
|
this->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void render(const unsigned int ms) const {
|
||||||
|
SDL_RenderPresent(renderer);
|
||||||
|
SDL_Delay(ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear(const RGBColor c) const {
|
||||||
|
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 255);
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
old line() code because i dont want to lose it:
|
||||||
|
|
||||||
|
int dx = x2 - x1;
|
||||||
|
int dy = y2 - y1;
|
||||||
|
float length = sqrt(dx * dx + dy * dy);
|
||||||
|
|
||||||
|
for (int i = 0; i <= length; i++) {
|
||||||
|
int x = x1;
|
||||||
|
int y = y1;
|
||||||
|
if (length > 0) {
|
||||||
|
x += i * dx / length;
|
||||||
|
y += i * dy / length;
|
||||||
|
}
|
||||||
|
pixel(x, y, c);
|
||||||
|
}
|
||||||
|
*/
|
||||||
41
levenshtein.h
Normal file
41
levenshtein.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef min
|
||||||
|
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef min3
|
||||||
|
#define min3(a, b, c) (min(min(a, b), c))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline int levenshtein(const char* s1, const char* s2) {
|
||||||
|
int len1 = strlen(s1);
|
||||||
|
int len2 = strlen(s2);
|
||||||
|
|
||||||
|
int* row = malloc((len2 + 1) * sizeof(int));
|
||||||
|
if (!row) return -1;
|
||||||
|
|
||||||
|
for (int j = 0; j <= len2; j++)
|
||||||
|
row[j] = j;
|
||||||
|
|
||||||
|
for (int i = 1; i <= len1; i++) {
|
||||||
|
int prev_diag = row[0];
|
||||||
|
row[0] = i;
|
||||||
|
for (int j = 1; j <= len2; j++) {
|
||||||
|
int temp = row[j];
|
||||||
|
row[j] = min3(
|
||||||
|
row[j] + 1, // deletion
|
||||||
|
row[j-1] + 1, // insertion
|
||||||
|
prev_diag + (s1[i-1] != s2[j-1]) // substitution
|
||||||
|
);
|
||||||
|
prev_diag = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = row[len2];
|
||||||
|
free(row);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
14
make_zombie_process.c
Normal file
14
make_zombie_process.c
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
pid_t pid = fork();
|
||||||
|
if (pid < 0) {
|
||||||
|
perror("fork failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (pid != 0) {
|
||||||
|
sleep(30);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
61
mod2mp3.cpp
Normal file
61
mod2mp3.cpp
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/* not sure will this run on windows
|
||||||
|
*
|
||||||
|
* you can actually use any audio format not just mp3 i had no idea how to call it
|
||||||
|
*
|
||||||
|
* compiles with:
|
||||||
|
* g++ mod2mp3.cpp -o mod2mp3 -O3 -lopenmpt
|
||||||
|
*
|
||||||
|
* usage: ./mod2mp3 <input.(xm/mod/stm/s3m/it/etc.)> <output.(mp3/wav/ogg/etc.)>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <bits/stdc++.h>
|
||||||
|
#include <libopenmpt/libopenmpt.hpp>
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 480
|
||||||
|
#define SAMPLE_RATE 48000
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
if (argc < 3) {
|
||||||
|
std::cout << "nouuuuuuuuu\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
std::ifstream file(argv[1], std::ios::binary);
|
||||||
|
openmpt::module mod(file);
|
||||||
|
|
||||||
|
std::string command = "ffmpeg -f s16le -ar " + std::to_string(SAMPLE_RATE) + " -ac 2 -i pipe: ";
|
||||||
|
for (char* c = argv[2]; *c; c++) {
|
||||||
|
if (*c == ' ') command += '\\';
|
||||||
|
command += *c;
|
||||||
|
}
|
||||||
|
std::cout << command << '\n';
|
||||||
|
FILE* pipe = popen(command.c_str(), "w");
|
||||||
|
if (!pipe) {
|
||||||
|
std::cerr << "Error: failed to open pipe\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mod.set_render_param(openmpt::module::render_param::RENDER_INTERPOLATIONFILTER_LENGTH, 1); // no interpolation
|
||||||
|
mod.set_render_param(openmpt::module::render_param::RENDER_VOLUMERAMPING_STRENGTH, 0); // no volume ramping
|
||||||
|
|
||||||
|
try {
|
||||||
|
int16_t interleaved_buffer[BUFFER_SIZE * 2];
|
||||||
|
while (true) {
|
||||||
|
int16_t pcm_buffer_right[BUFFER_SIZE];
|
||||||
|
int16_t pcm_buffer_left[BUFFER_SIZE];
|
||||||
|
std::size_t count = mod.read(SAMPLE_RATE, BUFFER_SIZE, pcm_buffer_left, pcm_buffer_right);
|
||||||
|
if (count == 0) break;
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
interleaved_buffer[2 * i] = pcm_buffer_left[i];
|
||||||
|
interleaved_buffer[2 * i + 1] = pcm_buffer_right[i];
|
||||||
|
}
|
||||||
|
fwrite(interleaved_buffer, sizeof(int16_t), count * 2, pipe);
|
||||||
|
}
|
||||||
|
pclose(pipe);
|
||||||
|
}
|
||||||
|
catch (const std::exception& e) {
|
||||||
|
std::cerr << "Error: " << std::string(e.what() ? e.what() : "unknown error") << '\n';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
36
pico8_color_pallete.sh
Normal file
36
pico8_color_pallete.sh
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# https://pico-8.fandom.com/wiki/Palette
|
||||||
|
colors=(
|
||||||
|
"0 0 0"
|
||||||
|
"29 43 83"
|
||||||
|
"126 37 83"
|
||||||
|
"0 135 81"
|
||||||
|
"171 82 54"
|
||||||
|
"95 87 79"
|
||||||
|
"194 195 199"
|
||||||
|
"255 241 232"
|
||||||
|
"255 0 77"
|
||||||
|
"255 163 0"
|
||||||
|
"255 236 39"
|
||||||
|
"0 228 54"
|
||||||
|
"41 173 255"
|
||||||
|
"131 118 156"
|
||||||
|
"255 119 168"
|
||||||
|
"255 204 170"
|
||||||
|
)
|
||||||
|
|
||||||
|
placeholders=("PK" " " " " " " " " " " "PW" " " "PR" "PO" "PY" "PG" "PB" "PS" "PM" "PE")
|
||||||
|
|
||||||
|
|
||||||
|
printf "\n%s\n\n" "PICO-8 сolor palette"
|
||||||
|
|
||||||
|
for i in "${!colors[@]}"; do
|
||||||
|
IFS=' ' read -r r g b <<< "${colors[i]}"
|
||||||
|
|
||||||
|
printf "#%02X%02X%02X " "$r" "$g" "$b"
|
||||||
|
printf "\e[38;2;%d;%d;%dm" "$r" "$g" "$b"
|
||||||
|
printf "████████████████"
|
||||||
|
printf "\e[0m"
|
||||||
|
printf " %-2s\n" "${placeholders[i]}"
|
||||||
|
done
|
||||||
16
signal_handler.c
Normal file
16
signal_handler.c
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void signal_handler(int sig) {
|
||||||
|
printf("Caught signal SIG%s (%d) - %s\n", sigabbrev_np(sig), sig, strsignal(sig));
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
for (int i = 1; i < NSIG; signal(i++, signal_handler));
|
||||||
|
puts("Listening for signals");
|
||||||
|
while (pause());
|
||||||
|
}
|
||||||
11
untitled_script.sh
Normal file
11
untitled_script.sh
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
row=""
|
||||||
|
for (( i=0; i<${#line}; i++ )); do
|
||||||
|
char="${line:i:1}"
|
||||||
|
row+="$char$char"
|
||||||
|
done
|
||||||
|
echo "$row"
|
||||||
|
echo "$row"
|
||||||
|
done
|
||||||
Reference in New Issue
Block a user