-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit f4c5e7e
Showing
14 changed files
with
339 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "CCLArgs"] | ||
path = CCLArgs | ||
url = https://github.com/RuiDGPires/CCLArgs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
C_FILES := $(wildcard src/*.c) | ||
H_FILES := $(wildcard src/*.h) $(wildcard src/include/*.h) | ||
TARGET := vis | ||
CC := gcc | ||
|
||
$(TARGET): $(C_FILES) $(H_FILES) | ||
gcc $(C_FILES) -o $@ | ||
|
||
.PHONY: clean | ||
clean: | ||
rm $(TARGET) |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#!/bin/sh | ||
|
||
VIDEO_FILE=output.mp4 | ||
|
||
make | ||
./vis ${VIDEO_FILE} | ||
vlc ${VIDEO_FILE} >/dev/null 2>&1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
#include <stdlib.h> | ||
#include <unistd.h> | ||
#include "canvas.h" | ||
#include "err.h" | ||
|
||
u32 point_dist_sqrd(point_t p1, point_t p2) { | ||
i32 dx = (i32) (p1.x - p2.x), dy = (i32) (p1.y - p2.y); | ||
return dx*dx + dy*dy; | ||
} | ||
|
||
canvas_t *canvas_create(u32 width, u32 height) { | ||
u32 *buffer = (u32*) malloc(sizeof(u32) * width * height); | ||
canvas_t *canvas = canvas_from_buffer(buffer, width, height); | ||
canvas->is_static = FALSE; | ||
return canvas; | ||
} | ||
|
||
canvas_t *canvas_from_buffer(u32 *buffer, u32 width, u32 height) { | ||
canvas_t *canvas = (canvas_t *) malloc(sizeof(canvas_t)); | ||
canvas->width = width; | ||
canvas->height = height; | ||
canvas->buffer = buffer; | ||
canvas->is_static = TRUE; | ||
return canvas; | ||
} | ||
|
||
void canvas_destroy(canvas_t **canvas) { | ||
if ((*canvas)->is_static == FALSE) | ||
free((*canvas)->buffer); | ||
|
||
free(*canvas); | ||
*canvas = NULL; | ||
} | ||
|
||
void canvas_fill(canvas_t *canvas, color_t color) { | ||
for (usize i = 0; i < canvas->width * canvas->height; i++) { | ||
canvas->buffer[i] = color; | ||
} | ||
} | ||
|
||
void canvas_dump(canvas_t *canvas, int fd) { | ||
write(fd, canvas->buffer, sizeof(color_t)*canvas->width*canvas->height); | ||
} | ||
|
||
void canvas_draw_point(canvas_t *canvas, point_t point, color_t color) { | ||
canvas->buffer[point.x + point.y*canvas->width] = color; | ||
} | ||
|
||
void canvas_draw_circle(canvas_t *canvas, point_t center, u32 radius, color_t color) { | ||
ERR_ASSERT(center.x - radius >= 0 && center.x + radius < canvas->width && center.y - radius >= 0 && center.y + radius < canvas->height, "Invalid circle"); | ||
for (u32 x = center.x - radius; x < center.x + radius; x++){ | ||
for (u32 y = center.y - radius; y < center.y + radius; y++){ | ||
point_t p = (point_t) {.x = x, .y = y}; | ||
|
||
if (point_dist_sqrd(p, center) <= radius*radius) { | ||
canvas_draw_point(canvas, p, color); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#ifndef __CANVAS_H__ | ||
#define __CANVAS_H__ | ||
|
||
#include "defs.h" | ||
|
||
typedef u32 color_t; | ||
|
||
#define RGBA(r, g, b, a) ((((r)&0xFF)<<(8*0)) | (((g)&0xFF)<<(8*1)) | (((b)&0xFF)<<(8*2)) | (((a)&0xFF)<<(8*3))) | ||
|
||
#define COLOR_RED RGBA(0xFF, 0x00, 0x00, 0xFF) | ||
#define COLOR_GREEN RGBA(0x00, 0xFF, 0x00, 0xFF) | ||
#define COLOR_BLUE RGBA(0x00, 0x00, 0xFF, 0xFF) | ||
#define COLOR_BLACK RGBA(0x00, 0x00, 0x00, 0xFF) | ||
#define COLOR_WHITE RGBA(0xFF, 0xFF, 0xFF, 0xFF) | ||
|
||
typedef struct { | ||
u32 width, height; | ||
color_t *buffer; | ||
u8 is_static; | ||
} canvas_t; | ||
|
||
typedef struct { | ||
usize x, y; | ||
} point_t; | ||
|
||
u32 point_dist_sqrd(point_t, point_t); | ||
|
||
canvas_t *canvas_create(u32, u32); | ||
canvas_t *canvas_from_buffer(u32 *, u32, u32); | ||
void canvas_destroy(canvas_t **); | ||
|
||
void canvas_fill(canvas_t *, color_t); | ||
void canvas_dump(canvas_t *, int); | ||
void canvas_draw_point(canvas_t *, point_t, color_t); | ||
void canvas_draw_circle(canvas_t *, point_t, u32, color_t); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#ifndef __DEFS_H__ | ||
#define __DEFS_H__ | ||
|
||
#include <stddef.h> | ||
#include <stdint.h> | ||
|
||
#define TRUE 1 | ||
#define FALSE 0 | ||
|
||
#define STR2(v) #v | ||
#define STR(v) STR2(v) | ||
|
||
typedef uint32_t u32; | ||
typedef uint16_t u16; | ||
typedef uint8_t u8; | ||
|
||
typedef int32_t i32; | ||
typedef int16_t i16; | ||
typedef int8_t i8; | ||
|
||
typedef size_t usize; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#ifndef __ERR_H__ | ||
#define __ERR_H__ | ||
|
||
#include <stdio.h> | ||
#include <errno.h> | ||
#include <string.h> | ||
#include <assert.h> | ||
|
||
#define ERR(...) {fprintf(stderr, "ERR: " __VA_ARGS__); fprintf(stderr, "\n"); exit(1);} | ||
|
||
#define ERR_ASSERT(cond, ...) {if (!(cond)) ERR(__VA_ARGS__)} | ||
#define ERR_ASSERT_CLN(cond, cln, ...) {if (!(cond)) {{cln;} ERR(__VA_ARGS__)}} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#include <stdlib.h> | ||
#include <unistd.h> | ||
#include "ffmpeg.h" | ||
#include "err.h" | ||
|
||
#define PIPE_READ 0 | ||
#define PIPE_WRITE 1 | ||
|
||
#define MAX_CHARS_DIM 100 | ||
#define MAX_CHARS_FPS 4 | ||
|
||
int open_ffmpeg(const char *filename, u32 width, u32 height, u32 fps) { | ||
int pipefd[2]; | ||
ERR_ASSERT(pipe(pipefd) >= 0, "Unable to open pipe"); | ||
|
||
int child = fork(); | ||
|
||
char dims_s[MAX_CHARS_DIM]; | ||
char fps_s[MAX_CHARS_FPS]; | ||
snprintf(dims_s, MAX_CHARS_DIM, "%ux%u", width, height); | ||
snprintf(fps_s, MAX_CHARS_FPS, "%u", fps); | ||
|
||
ERR_ASSERT(child >= 0, "Unable to fork"); | ||
|
||
if (child == 0) { | ||
ERR_ASSERT(dup2(pipefd[PIPE_READ], STDIN_FILENO) >= 0, "Unable to reopen read pipe as stdin"); | ||
close(pipefd[PIPE_WRITE]); | ||
|
||
ERR_ASSERT(execlp("ffmpeg", | ||
"ffmpeg", | ||
"-loglevel", "verbose", | ||
"-y", | ||
"-f", "rawvideo", | ||
"-pix_fmt", "rgba", | ||
"-s", dims_s, | ||
"-r", fps_s, | ||
"-an", | ||
"-i", "-", | ||
"-c:v", "libx264", | ||
|
||
filename, | ||
// ... | ||
NULL | ||
) >= 0, "Unable to open FFMPEG: %s", strerror(errno)); | ||
assert(0 && "Unreachable"); | ||
} | ||
|
||
close(pipefd[PIPE_READ]); | ||
return pipefd[PIPE_WRITE]; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#ifndef __FFMPEG_H__ | ||
#define __FFMPEG_H__ | ||
|
||
#include "defs.h" | ||
|
||
int open_ffmpeg(const char *, u32 width, u32 height, u32 fps); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <unistd.h> | ||
#include <sys/wait.h> | ||
#include "../CCLArgs/cclargs.h" | ||
#include "ffmpeg.h" | ||
#include "defs.h" | ||
#include "err.h" | ||
#include "wav.h" | ||
#include "canvas.h" | ||
|
||
#define WIDTH 600 | ||
#define HEIGHT 400 | ||
#define FPS 30 | ||
#define DURATION 5 | ||
|
||
#define MAX_FILENAME 100 | ||
|
||
#define USAGE "vis <output_name>" | ||
#define DEFAULT_NAME "a.mp4" | ||
|
||
int main(ARGS) { | ||
char *output_file = DEFAULT_NAME; | ||
|
||
BEGIN_PARSE_ARGS("") | ||
ARG_STRING(output_file, "-o") | ||
END_PARSE_ARGS | ||
|
||
color_t pixels[WIDTH*HEIGHT]; | ||
canvas_t *canvas = canvas_from_buffer(pixels, WIDTH, HEIGHT); | ||
|
||
int outfd = open_ffmpeg(output_file, WIDTH, HEIGHT, FPS); | ||
|
||
canvas_fill(canvas, COLOR_BLUE); | ||
canvas_draw_circle(canvas, (point_t){.x = WIDTH/2, .y = HEIGHT/2}, HEIGHT/3, COLOR_RED); | ||
|
||
for (usize i = 0; i < FPS * DURATION; i++) { | ||
canvas_dump(canvas, outfd); | ||
} | ||
|
||
close(outfd); | ||
canvas_destroy(&canvas); | ||
wait(NULL); | ||
printf("Operation completed\n"); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#include <stdlib.h> | ||
|
||
#include "wav.h" | ||
#include "err.h" | ||
|
||
#define BUFFER_SIZE 4096 | ||
|
||
// Function to read audio file and retrieve its contents | ||
wav_t *wav_from_file(const char* filename) { | ||
FILE* file = fopen(filename, "rb"); | ||
ERR_ASSERT(file != NULL, "Failed to open file"); | ||
|
||
wav_t *wav = (wav_t *) malloc(sizeof(wav_t)); | ||
wav_header_t header; | ||
|
||
// Read the WAV file header | ||
size_t headerSize = fread(&header, 1, sizeof(wav_header_t), file); | ||
|
||
ERR_ASSERT_CLN(headerSize == sizeof(wav_header_t), fclose(file), "Invalid WAV File"); | ||
|
||
// Check if the file format is valid | ||
ERR_ASSERT_CLN(header.chunkID[0] == 'R' && header.chunkID[1] == 'I' && header.chunkID[2] == 'F' && header.chunkID[3] == 'F' && header.format[0] == 'W' && header.format[1] == 'A' && header.format[2] == 'V' && header.format[3] == 'E', | ||
fclose(file), "Invalid WAV file format"); | ||
|
||
// Allocate memory to store audio data | ||
u32 dataSize = header.subchunk2Size; | ||
|
||
wav->header = header; | ||
u8* buffer = (uint8_t*)malloc(sizeof(u8) * dataSize); | ||
|
||
ERR_ASSERT_CLN(buffer != NULL, fclose(file), "Failed to allocate memory"); | ||
wav->buffer = buffer; | ||
|
||
// Read the audio data into the buffer | ||
usize bytesRead = fread(buffer, 1, dataSize, file); | ||
fclose(file); | ||
|
||
ERR_ASSERT_CLN(bytesRead == dataSize, free(buffer), "Error occurred while reading the audio data") | ||
|
||
return wav; | ||
} | ||
|
||
void destroy_wav(wav_t **wav) { | ||
free((*wav)->buffer); | ||
free(*wav); | ||
*wav = NULL; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#ifndef __WAV_H__ | ||
#define __WAV_H__ | ||
|
||
#include "defs.h" | ||
|
||
// WAV file header structure | ||
typedef struct { | ||
char chunkID[4]; | ||
u32 chunkSize; | ||
char format[4]; | ||
char subchunk1ID[4]; | ||
u32 subchunk1Size; | ||
u16 audioFormat; | ||
u16 numChannels; | ||
u32 sampleRate; | ||
u32 byteRate; | ||
u16 blockAlign; | ||
u16 bitsPerSample; | ||
char subchunk2ID[4]; | ||
u32 subchunk2Size; | ||
} wav_header_t; | ||
|
||
typedef struct { | ||
wav_header_t header; | ||
u8 *buffer; | ||
} wav_t; | ||
|
||
wav_t *wav_from_file(const char *); | ||
void wav_destroy(wav_t **); | ||
|
||
#endif |