int main(int argc, char** argv) { xm_context_t* ctx; float buffer[buffer_size]; if(argc != 2) FATAL("Usage: %s <filename>\n", argv[0]); create_context_from_file(&ctx, rate, argv[1]); xm_set_max_loop_count(ctx, 1); puts_uint32_be(0x2E736E64); /* .snd magic number */ puts_uint32_be(24); /* Header size */ puts_uint32_be((uint32_t)(-1)); /* Data size, unknown */ puts_uint32_be(6); /* Encoding: 32-bit IEEE floating point */ puts_uint32_be(rate); /* Sample rate */ puts_uint32_be(channels); /* Number of interleaved channels */ while(xm_get_loop_count(ctx) == 0) { xm_generate_samples(ctx, buffer, sizeof(buffer) / (channels * sizeof(float))); for(size_t k = 0; k < buffer_size; ++k) { union { float f; uint32_t i; } u; u.f = buffer[k]; puts_uint32_be(u.i); } } xm_free_context(ctx); return 0; }
int main(int argc, char** argv) { xm_context_t* ctx; FILE* out; uint32_t num_samples = 0; float buffer[buffer_size]; if(argc != 3) FATAL("Usage: %s <xm-file-input> <wav-file-out>\n", argv[0]); create_context_from_file(&ctx, rate, argv[1]); if(ctx == NULL) exit(1); xm_set_max_loop_count(ctx, 1); out = fopen(argv[2], "w"); if(out == NULL) FATAL_ERR("could not open output file for writing"); /* WAVE format info taken from * http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html */ /* Unlike AU, WAVE files cannot have an unknown length. This * is why we can't write directly to stdout (we need to rewind * because module length is hard to know. */ fputs("RIFF", out); puts_uint32_le(0, out); /* Chunk size. Will be filled later. */ fputs("WAVE", out); fputs("fmt ", out); /* Start format chunk */ puts_uint32_le(16, out); /* Format chunk size */ puts_uint16_le(3, out); /* IEEE float sample data */ puts_uint16_le(channels, out); /* Number of channels */ puts_uint32_le(rate, out); /* Frames/sec (sampling rate) */ puts_uint32_le(rate * channels * sizeof(float), out); /* nAvgBytesPerSec ? */ puts_uint16_le(channels * sizeof(float), out); /* nBlockAlign ? */ puts_uint16_le(8 * sizeof(float), out); /* wBitsPerSample ? */ fputs("data", out); /* Start data chunk */ puts_uint32_le(0, out); /* Data chunk size. Will be filled later. */ while(xm_get_loop_count(ctx) == 0) { xm_generate_samples(ctx, buffer, buffer_size / channels); num_samples += buffer_size; for(size_t k = 0; k < buffer_size; ++k) { union { float f; uint32_t i; } u; u.f = buffer[k]; puts_uint32_le(u.i, out); } } fseek(out, 4, SEEK_SET); puts_uint32_le(36 + num_samples * sizeof(float), out); fseek(out, 32, SEEK_SET); puts_uint32_le(num_samples * sizeof(float), out); fclose(out); xm_free_context(ctx); return 0; }
void setup(int argc, char** argv) { size_t filenameidx = 1; for(size_t i = 1; i < argc; ++i) { if(!strcmp(argv[i], "--")) { filenameidx = i+1; break; } if(!strcmp(argv[i], "--width")) { if(argc == i+1) FATAL("%s: expected argument after %s\n", argv[0], argv[i]); width = strtol(argv[i+1], NULL, 0); ++i; continue; } if(!strcmp(argv[i], "--height")) { if(argc == i+1) FATAL("%s: expected argument after %s\n", argv[0], argv[i]); height = strtol(argv[i+1], NULL, 0); ++i; continue; } if(!strcmp(argv[i], "--interval")) { if(argc == i+1) FATAL("%s: expected argument after %s\n", argv[0], argv[i]); interval = strtol(argv[i+1], NULL, 0); ++i; continue; } if(!strcmp(argv[i], "--fullscreen")) { fullscreen = true; continue; } if(!strcmp(argv[i], "--device") || !strcmp(argv[i], "--buffer-size") || !strcmp(argv[i], "--period-size") || !strcmp(argv[i], "--rate") || !strcmp(argv[i], "--format")) { ++i; continue; } filenameidx = i; break; } if(filenameidx+1 != argc) { usage(argv[0]); exit(1); } glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); window = glfwCreateWindow(width, height, argv[0], fullscreen ? glfwGetPrimaryMonitor() : NULL, NULL); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); glfwMakeContextCurrent(window); glfwSwapInterval(interval); printf("Using GL renderer: %s %s\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER)); glGenBuffers(1, &vertexn); glBindBuffer(GL_ARRAY_BUFFER, vertexn); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glGenBuffers(1, &elementn); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementn); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glGenVertexArrays(1, &varrayn); glBindVertexArray(varrayn); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); /* XXX: wtf? */ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementn); GLuint vsn, fsn; const char* src; GLint status; progn = glCreateProgram(); #include "vs.h" src = vs; vsn = glCreateShader(GL_VERTEX_SHADER); glAttachShader(progn, vsn); glShaderSource(vsn, 1, &src, NULL); glCompileShader(vsn); glGetShaderiv(vsn, GL_COMPILE_STATUS, &status); if(status != GL_TRUE) { char msg[1024]; glGetShaderInfoLog(vsn, 1024, NULL, msg); fprintf(stderr, "VS:%s", msg); exit(1); } #include "fs.h" src = fs; fsn = glCreateShader(GL_FRAGMENT_SHADER); glAttachShader(progn, fsn); glShaderSource(fsn, 1, &src, NULL); glCompileShader(fsn); glGetShaderiv(fsn, GL_COMPILE_STATUS, &status); if(status != GL_TRUE) { char msg[1024]; glGetShaderInfoLog(fsn, 1024, NULL, msg); fprintf(stderr, "FS:%s", msg); exit(1); } glLinkProgram(progn); glGetProgramiv(progn, GL_LINK_STATUS, &status); if(status != GL_TRUE) { char msg[1024]; glGetProgramInfoLog(progn, 1024, NULL, msg); fprintf(stderr, "PROG:%s", msg); exit(1); } xmdatau = glGetUniformLocation(progn, "xmdata"); glUseProgram(progn); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); init_alsa_device(argc, argv, 64, 2048, SND_PCM_NONBLOCK, &device, &period_size, &rate, &format); create_context_from_file(&xmctx, rate, argv[filenameidx]); if(xmctx == NULL) exit(1); xm_set_max_loop_count(xmctx, 1); channels = xm_get_number_of_channels(xmctx); instruments = xm_get_number_of_instruments(xmctx); CHECK_ALSA_CALL(snd_pcm_prepare(device)); }