Skip to content

Instantly share code, notes, and snippets.

@dakom
Created July 25, 2014 06:52
Show Gist options
  • Save dakom/dc9004d00e9a0ad32bf4 to your computer and use it in GitHub Desktop.
Save dakom/dc9004d00e9a0ad32bf4 to your computer and use it in GitHub Desktop.
Shows data as audio and visual
/*Hard Noise
Feel free to use this program as you wish, though if you borrow a
significant peice of code please add a comment giving me credit :)
This program traverses through the directory tree from where it is run
and for each file it finds it shows the data as audio and visual..it
then starts back over at the beginning of the directory tree. During
runtime, the user may press 'b' to break out of the current directory.
It also allows the user to specify a volume level as an argument,
save the images as bitmap files in order as well as specify a
size for the screen. format is as follows:
hardnoise [width] [height] [volume level] [f/n] [imagesname]
if no imagesname is supplied it will not save any images
if "f" is supplied it will go into fullscreen mode, otherwise normal.
for example: hardnoise 800 600 128 f test
would go into fullscreen mode, and do its thing at maximum volume in
a windowed portion of 800x600 pixels and save each completed window
to test1.bmp test2.bmp test3.bmp, etc.
There is no guarantee that the audio or visual sync up as it just tries
to write the data as fast as it can using SDL, no waiting for timing or
pre-buffering or anything.
Should work on every OS that can install SDL(unix,mac,micro$oft,etc.)
compile with something like:
gcc -I/local/include/SDL/ -I/local/include/ -L/local/lib -O4 -mconsole -o hardnoise hardnoise.c `sdl-config --libs`
windows binary compiled with the above line on msys/mingw, SDL dll included too... enjoy! =)
Probably best run from the root data harddrive (C:\ on windows, /home/ on linux, / on mac)
peace love unity respect
The Tao of Knowledge
*/
//Includes
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <SDL.h>
#include <SDL_audio.h>
//Defines
#define MAX_DIR_PATH 65535
#define MAX_BITMAP_FILE 1024
#define DEFAULT_VOLUME SDL_MIX_MAXVOLUME
#define DEFAULT_WIDTH 300
#define DEFAULT_HEIGHT 300
#define BOOL unsigned char
#define TRUE 0x1
#define FALSE 0x0
#define SND_FREQUENCY 96000
#define SND_FORMAT AUDIO_S16LSB
#define SND_CHANNELS (1)
#define SND_SAMPLES 1024
//Prototypes
void Show_Usage(void);
void audio_callback(void *userdata, Uint8 *stream, int len);
void Show_File(struct dirent *nfo, SDL_AudioCVT *CurrWave, Uint8 *t_buf, Uint32 *ap_curpos, Uint32 *vp_curpos, SDL_Surface *Canvas);
void traverse_files(void (*de_caller)(struct dirent *, SDL_AudioCVT *,Uint8 *, Uint32 *, Uint32 *, SDL_Surface *),\
SDL_AudioCVT *CurrWave, Uint8 *t_buf, Uint32 *ap_curpos, Uint32 *vp_curpos, SDL_Surface *Canvas);
Uint32 Process_Events(SDL_Event event);
Uint32 Process_Keys(SDL_KeyboardEvent key);
Uint32 Process_Mouse(SDL_MouseButtonEvent mouse);
void PerrSDL(const char *s_err, ...);
BOOL Init_SDL(const char *progname, Uint32 flags);
BOOL Init_Audio(SDL_AudioSpec **audio_spec_ptr,int frequency,\
Uint16 format,\
Uint8 channels,\
Uint16 samples,\
void (*callback)(void *userdata, Uint8 *stream, int len),\
void **userdata);
BOOL Init_Screen(SDL_Surface **MainScrPtr, int w, int h, Uint32 FullScreen);
void ClearScreen(SDL_Surface *canvas);
BOOL CleanUp(void);
//Globals
Uint32 done = FALSE;
int audio_volume = DEFAULT_VOLUME;
char bitmap_file[MAX_BITMAP_FILE + 1];
Uint32 bitmap_fileno = 0;
//Sub Functions
////Initialization
void PerrSDL(const char *s_err, ...)
{
char mtxt[1024];
va_list ap;
va_start(ap, s_err);
vsnprintf(mtxt,1024,s_err,ap);
va_end(ap);
fprintf(stderr, "SDL error: %s\n", mtxt);
}
BOOL Init_SDL(const char *progname, Uint32 flags)
{
int index;
if(SDL_Init(flags) < 0 ) {
PerrSDL(SDL_GetError());
return(FALSE);
}
atexit(SDL_Quit);
if(progname != NULL) {
if(progname[0] != '\0') {
SDL_WM_SetCaption(progname, progname);
}
}
return(TRUE);
}
BOOL Init_Audio(SDL_AudioSpec **audio_spec_ptr,int frequency,\
Uint16 format,\
Uint8 channels,\
Uint16 samples,\
void (*callback)(void *userdata, Uint8 *stream, int len),\
void **userdata)
{
SDL_AudioSpec *audio_spec, *temp_spec;
int ret, index;
SDL_AudioCVT *wav_ptr;
float lambda;
audio_spec = malloc(sizeof(SDL_AudioSpec));
temp_spec = malloc(sizeof(SDL_AudioSpec));
wav_ptr = malloc(sizeof(SDL_AudioCVT));
if(audio_spec == NULL || wav_ptr == NULL || temp_spec == NULL) {
free(audio_spec); free(wav_ptr); free(temp_spec);
return(FALSE);
}
temp_spec->freq = frequency;
temp_spec->format = format;
temp_spec->channels= channels;
temp_spec->samples = samples;
temp_spec->callback = callback;
temp_spec->userdata = wav_ptr;
*userdata = wav_ptr;
if ( SDL_OpenAudio(temp_spec, audio_spec) < 0 ){
free(audio_spec); free(wav_ptr); free(temp_spec); return(FALSE);
}
*audio_spec_ptr=audio_spec;
free(temp_spec);
ret = SDL_BuildAudioCVT(wav_ptr,\
audio_spec->format, audio_spec->channels, audio_spec->freq,\
audio_spec->format, audio_spec->channels, audio_spec->freq);
if(ret==-1){
SDL_CloseAudio();
free(audio_spec);
free(wav_ptr);
return(FALSE);
}
wav_ptr->buf=(Uint8 *)malloc(audio_spec->size*wav_ptr->len_mult);
wav_ptr->len=audio_spec->size;
memset(wav_ptr->buf, 0, sizeof(wav_ptr->buf));
SDL_ConvertAudio(wav_ptr);
return(TRUE);
}
BOOL Init_Screen(SDL_Surface **MainScrPtr, int w, int h, Uint32 FullScreen)
{
SDL_Surface *MainScr;
int index;
Uint32 flags = (SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_SRCCOLORKEY | SDL_HWPALETTE | FullScreen);
SDL_VideoInfo *VidNfo = (SDL_VideoInfo *)SDL_GetVideoInfo();
if(VidNfo == NULL) { return(FALSE); }
MainScr = SDL_SetVideoMode(w, h, VidNfo->vfmt->BitsPerPixel, flags);
if ( MainScr == NULL ) {
PerrSDL(SDL_GetError());
return(FALSE);
}
*MainScrPtr = MainScr;
ClearScreen(MainScr); SDL_Flip(MainScr);
ClearScreen(MainScr); SDL_Flip(MainScr);
return(TRUE);
}
void ClearScreen(SDL_Surface *canvas)
{
if ( SDL_MUSTLOCK(canvas) ) {
if ( SDL_LockSurface(canvas) < 0 ) {
PerrSDL(SDL_GetError()); CleanUp();
}
}
SDL_FillRect(canvas, NULL, SDL_MapRGB(canvas->format, 0, 0, 0));
if ( SDL_MUSTLOCK(canvas) ) {
SDL_UnlockSurface(canvas);
}
}
BOOL CleanUp() {
SDL_Event eve;
eve.type = SDL_QUIT;
SDL_PushEvent((SDL_Event *)&eve);
return(TRUE);
}
////Events
Uint32 Process_Events(SDL_Event event)
{
switch(event.type) {
case SDL_KEYUP: return(Process_Keys(event.key));
case SDL_MOUSEBUTTONDOWN: return(Process_Mouse(event.button));
case SDL_QUIT: return(CleanUp());
default: return(FALSE);
}
}
Uint32 Process_Keys(SDL_KeyboardEvent key)
{
return(key.keysym.sym);
}
Uint32 Process_Mouse(SDL_MouseButtonEvent mouse)
{
return(TRUE);
}
////Audio Callback
void audio_callback(void *p_currwave, Uint8 *stream, int len)
{
SDL_AudioCVT *CurrWave = (SDL_AudioCVT *)p_currwave;
SDL_LockAudio();
SDL_MixAudio(stream, CurrWave->buf, len, audio_volume);
SDL_UnlockAudio();
return;
}
////Traverse Directory Stuff
void Show_File(struct dirent *nfo, SDL_AudioCVT *CurrWave, Uint8 *t_buf, Uint32 *ap_curpos, Uint32 *vp_curpos, SDL_Surface *Canvas)
{
FILE *fp_in;
size_t n_bytez, a_bytez, v_bytez;
Uint32 a_curpos, v_curpos;
SDL_Event events;
char tbmp[MAX_BITMAP_FILE + 1];
double wave_end = (double)(CurrWave->len * CurrWave->len_ratio);
Uint32 vid_end = (Uint32)(Canvas->h * Canvas->pitch);
if ( SDL_MUSTLOCK(Canvas) ) {
if ( SDL_LockSurface(Canvas) < 0 ) {
PerrSDL(SDL_GetError()); CleanUp(); exit(0);
}
}
a_curpos = *ap_curpos; v_curpos = *vp_curpos;
if(!(fp_in = fopen(nfo->d_name, "rb"))) {
fprintf(stderr, "Unable to open %s!\n", nfo->d_name);
} else {
while(!feof(fp_in) && !done) {
n_bytez = fread(t_buf, 1, ((wave_end > vid_end) ? vid_end : wave_end), fp_in);
a_bytez = v_bytez = n_bytez;
if((a_curpos + a_bytez) > wave_end) {
memcpy(CurrWave->buf + a_curpos, t_buf, (wave_end - a_curpos));
a_bytez -= (wave_end - a_curpos);
a_curpos = 0;
}
if(a_bytez) {
memcpy(CurrWave->buf + a_curpos, t_buf, a_bytez);
if((a_curpos += a_bytez) == wave_end) {
a_curpos = 0;
}
}
if((v_curpos + v_bytez) > vid_end) {
memcpy(Canvas->pixels + v_curpos, t_buf, (vid_end - v_curpos));
v_bytez -= (vid_end - v_curpos);
v_curpos = 0;
}
if(v_bytez) {
memcpy(Canvas->pixels + v_curpos, t_buf, v_bytez);
if((v_curpos += v_bytez) == vid_end) {
v_curpos = 0;
}
}
SDL_Flip(Canvas);
if(bitmap_file[0] != '\0') {
snprintf(tbmp, MAX_BITMAP_FILE, "%s%d.bmp", bitmap_file, ++bitmap_fileno);
SDL_SaveBMP(Canvas, tbmp);
}
SDL_PollEvent(&events);
done = Process_Events(events);
}
fclose(fp_in);
}
*ap_curpos = a_curpos;
*vp_curpos = v_curpos;
if ( SDL_MUSTLOCK(Canvas) ) {
SDL_UnlockSurface(Canvas);
}
}
void traverse_files(void (*de_caller)(struct dirent *, SDL_AudioCVT *,Uint8 *, Uint32 *, Uint32 *, SDL_Surface *),\
SDL_AudioCVT *CurrWave, Uint8 *t_buf, Uint32 *ap_curpos, Uint32 *vp_curpos, SDL_Surface *Canvas)
{
DIR *dir;
struct dirent *entry;
char cwd[MAX_DIR_PATH +1];
struct stat dir_stat;
if(!(getcwd(cwd, MAX_DIR_PATH))) {
fprintf(stderr, "error getting current working directory\n");
return;
}
dir = opendir(".");
if(!dir) {
fprintf(stderr, "cannot read directory %s!\n", cwd);
return;
}
while((entry = readdir(dir)) != NULL) {
if(done) { return; }
if((stat(entry->d_name, &dir_stat) == -1)) {
fprintf(stderr, "error getting status\n");
continue;
}
if(strcmp(entry->d_name, ".") == 0) {continue;}
if(strcmp(entry->d_name, "..") == 0){continue;}
if(S_ISDIR(dir_stat.st_mode)) {
if(chdir(entry->d_name) == -1) {
fprintf(stderr, "cannot change directory to %s!\n", entry->d_name);
continue;
}
traverse_files(de_caller,CurrWave,t_buf, ap_curpos, vp_curpos, Canvas);
if(chdir("..") == -1) {
fprintf(stderr, "Cannot change directory back to %s!\n", cwd);
return;
}
} else {
de_caller(entry, CurrWave, t_buf, ap_curpos, vp_curpos, Canvas);
}
}
}
////Usage
void Show_Usage(void) {
fprintf(stderr, "Usage: hardnoise [width] [height] [volume level] [f/n] [imagesname]\n\nif no imagesname is supplied it will not save any images\n\nif \"f\" is supplied it will go into fullscreen mode, otherwise normal.\n\nVolume must be between 0 and %d, default is %d",\
SDL_MIX_MAXVOLUME, SDL_MIX_MAXVOLUME);
}
//Main
int main(int argc, char **argv)
{
SDL_Event events;
SDL_AudioSpec *sound_spec;
SDL_Surface *MainScr;
SDL_AudioCVT *CurrWave;
Uint8 *t_buf;
Uint32 a_curpos = 0;
Uint32 v_curpos = 0;
int wnd_width = DEFAULT_WIDTH;
int wnd_height= DEFAULT_HEIGHT;
Uint32 wnd_fullscreen = FALSE;
sound_spec = NULL;
bitmap_file[0] = '\0';
if(argc >=2) {
wnd_width = atoi(argv[1]);
if(argc >= 3) {
wnd_height = atoi(argv[2]);
}
if(wnd_width < 0 || wnd_height < 0) {
Show_Usage();
exit(0);
}
if(argc >=4) {
audio_volume = atoi(argv[3]);
if(audio_volume < 0 || audio_volume > SDL_MIX_MAXVOLUME) {
Show_Usage();
exit(0);
}
if(argc >=5) {
if(argv[4][0] == 'f') {
wnd_fullscreen = SDL_FULLSCREEN;
}
if(argc >= 6) {
strncpy(bitmap_file, argv[5], (MAX_BITMAP_FILE - 24));
}
}
}
}
if(!(Init_SDL("_-=HardNoise=-_", SDL_INIT_AUDIO | SDL_INIT_VIDEO))) { exit(0); }
if(!(Init_Screen(&MainScr, wnd_width, wnd_height, wnd_fullscreen))) { exit(0); }
if(!(Init_Audio(&sound_spec,SND_FREQUENCY,SND_FORMAT,SND_CHANNELS,SND_SAMPLES,audio_callback,(void *)&CurrWave))) {
SDL_FreeSurface(MainScr);
exit(0);
}
t_buf = malloc((sizeof(Uint8) * (CurrWave->len * CurrWave->len_ratio)) + 1);
if(t_buf == NULL) {
SDL_CloseAudio();
free(sound_spec);
free(CurrWave);
SDL_FreeSurface(MainScr);
exit(0);
}
SDL_PauseAudio(0);
while(!done) {
traverse_files(Show_File,CurrWave,t_buf,&a_curpos,&v_curpos,MainScr);
if(done == SDLK_b) { done = FALSE; }
}
SDL_CloseAudio();
free(sound_spec);
free(CurrWave);
free(t_buf);
SDL_FreeSurface(MainScr);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment