udp packets are now rightly placed in message buf, that is cleared at end of frame
parent
3fa2487596
commit
2680732685
4
ampler.c
4
ampler.c
|
@ -67,6 +67,10 @@ int ampler_main(SDL_Window *w, SDL_Renderer *r, Ampler_state **u_data) {
|
|||
state -> played_audio_last_frame = audio_frame(state);
|
||||
draw_frame(w, r, state);
|
||||
|
||||
// CLEAR UDP MESSAGES
|
||||
foreach_ptr(Udp_msg, msg, state -> messages)
|
||||
msg -> state = MSG_FREE;
|
||||
|
||||
SDL_Delay(1);
|
||||
|
||||
if !remove("reload-trigger") do {
|
||||
|
|
14
ampler.h
14
ampler.h
|
@ -28,6 +28,11 @@ typedef double f64;
|
|||
|
||||
#define arraylen(a) (sizeof (a) / sizeof ((a)[0]))
|
||||
|
||||
#define foreach_ptr(TYPE, N, ARRAY) \
|
||||
for int N##_i = 0; N##_i == 0; N##_i = 1 do \
|
||||
for TYPE *N = &((ARRAY)[N##_i]); N != NULL; N = NULL do \
|
||||
for ; N##_i < arraylen(ARRAY); N##_i += 1, N = &((ARRAY)[N##_i]) do
|
||||
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define CHANNELS (2)
|
||||
#define FRAME_SAMPLES (SAMPLE_RATE / 60)
|
||||
|
@ -38,7 +43,13 @@ struct Sound_src {
|
|||
s32 len; // in samples
|
||||
f32 pos; // position in samples
|
||||
f32 speed; // in samples, per sample, can be negative
|
||||
enum { FREE = 0, STOPPED, PLAYING, LOOPING } state;
|
||||
enum { SND_FREE = 0, SND_STOPPED, SND_PLAYING, SND_LOOPING, } state;
|
||||
};
|
||||
|
||||
typedef struct Udp_msg Udp_msg;
|
||||
struct Udp_msg {
|
||||
s8 text[32]; // includes null terminator
|
||||
enum { MSG_FREE = 0, MSG_TRIGGER, } state;
|
||||
};
|
||||
|
||||
typedef struct Ampler_state Ampler_state;
|
||||
|
@ -47,6 +58,7 @@ struct Ampler_state {
|
|||
SDL_AudioDeviceID playdev;
|
||||
Sound_src sounds[64];
|
||||
s32 played_audio_last_frame;
|
||||
Udp_msg messages[64];
|
||||
};
|
||||
|
||||
|
||||
|
|
27
audio.c
27
audio.c
|
@ -1,7 +1,10 @@
|
|||
// audio.c
|
||||
|
||||
// TODO: add something to make sure, we KNOW if we've dropped audio
|
||||
// eg. buffer has gone unfilled for a frame or more
|
||||
|
||||
void sound_src_frame(Sound_src *s, s8 *mix[]) {
|
||||
if s -> state == LOOPING do
|
||||
if s -> state == SND_LOOPING do
|
||||
for int i = 0; i < FRAME_SAMPLES; i += 1 do {
|
||||
for int c = 0; c < CHANNELS; c += 1 do
|
||||
mix[c][i] += s -> tracks[c][(int) s -> pos];
|
||||
|
@ -27,8 +30,8 @@ int audio_frame(Ampler_state *state) {
|
|||
SDL_memset(mix_r, 0, sizeof mix_r);
|
||||
|
||||
s8 *mix[] = { mix_l, mix_r };
|
||||
for int s = 0; s < arraylen(state -> sounds); s += 1 do
|
||||
sound_src_frame(&(state -> sounds[s]), mix);
|
||||
foreach_ptr(Sound_src, snd, state -> sounds) //for int s = 0; s < arraylen(state -> sounds); s += 1 do
|
||||
sound_src_frame(snd, mix); //sound_src_frame(&(state -> sounds[s]), mix);
|
||||
|
||||
const int vol = 100;
|
||||
static s16 frame[FRAME_SAMPLES * CHANNELS] = { 0 };
|
||||
|
@ -43,6 +46,17 @@ int audio_frame(Ampler_state *state) {
|
|||
}
|
||||
|
||||
void load_track(Ampler_state *state) {
|
||||
Sound_src *snd = NULL;
|
||||
foreach_ptr(Sound_src, s, state -> sounds)
|
||||
if s -> state == SND_FREE do {
|
||||
snd = s;
|
||||
break;
|
||||
}
|
||||
if snd == NULL do {
|
||||
puts("error: all sound sources in use");
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_AudioSpec spec;
|
||||
s16 *buffer = NULL;
|
||||
u32 bytes = 0;
|
||||
|
@ -57,18 +71,17 @@ void load_track(Ampler_state *state) {
|
|||
const int chans = spec.channels;
|
||||
const int length = (bytes / sizeof s16) / chans;
|
||||
|
||||
// TODO: Actually find free sound_src
|
||||
Sound_src *snd = &(state -> sounds[0]);
|
||||
snd -> len = length;
|
||||
snd -> speed = 1.0f;
|
||||
snd -> pos = 0.0f;
|
||||
snd -> state = LOOPING; // TOOD: Should be STOPPED
|
||||
// snd -> state = SND_LOOPING;
|
||||
snd -> state = SND_STOPPED;
|
||||
|
||||
for int i = 0; i < CHANNELS; i += 1 do
|
||||
snd -> tracks[i] = malloc(snd -> len);
|
||||
|
||||
for int i = 0; i < CHANNELS; i += 1 do
|
||||
if !snd -> tracks[i] do
|
||||
if !(snd -> tracks[i]) do
|
||||
puts("fffuuuck");
|
||||
|
||||
for int i = 0; i < snd -> len; i += 1 do
|
||||
|
|
21
draw.c
21
draw.c
|
@ -5,20 +5,23 @@ void draw_frame(SDL_Window *w, SDL_Renderer *r, Ampler_state *state) {
|
|||
//SDL_SetRenderDrawColor(r, 10, 10, 10, 100);
|
||||
SDL_RenderClear(r);
|
||||
|
||||
// TODO: ACTUALLY DRAW ALL SOUNDS, BUT SMOLER
|
||||
// TODO: DRAW SMOLER
|
||||
SDL_SetRenderDrawColor(r, 0xFF, 0x00, 0x4D, 255);
|
||||
const space = (44100 * 8) / 512;
|
||||
// TODO: DRAW L / R OVERLAPPED IN DIFF COLORS ?
|
||||
const int t = 0;
|
||||
for int x = 0; x < 512; x += 1 do {
|
||||
const int y = 128 + 256 * t;
|
||||
const int val = state -> sounds[0].tracks[t][x * space];
|
||||
SDL_RenderDrawLine(r, x, y + val / 8, x, y + val);
|
||||
//SDL_RenderDrawPoint(r, x, y + val);
|
||||
}
|
||||
foreach_ptr(Sound_src, snd, state -> sounds)
|
||||
if snd -> state != SND_FREE do
|
||||
for int x = 0; x < 512; x += 1 do {
|
||||
const int y = 128 + 256 * snd_i;
|
||||
const int val = snd -> tracks[t][x * space];
|
||||
SDL_RenderDrawLine(r, x, y + val / 8, x, y + val);
|
||||
//SDL_RenderDrawPoint(r, x, y + val);
|
||||
}
|
||||
|
||||
if state -> played_audio_last_frame do
|
||||
for int i = 0; i < arraylen(state -> sounds); i += 1 do {
|
||||
const int x = state -> sounds[i].pos / space;
|
||||
foreach_ptr(Sound_src, snd, state -> sounds) {
|
||||
const int x = snd -> pos / space;
|
||||
SDL_RenderDrawLine(r, x, 0, x, 512);
|
||||
}
|
||||
|
||||
|
|
79
udp.c
79
udp.c
|
@ -1,5 +1,13 @@
|
|||
// udp.c
|
||||
|
||||
/* TODO:
|
||||
* convert error codes to strings and print them, we could just make a table
|
||||
* option to change port, handle when we cant get gur port
|
||||
* be able to send packets when sounds / recording starts / ends ?
|
||||
|
||||
* store from ip + port in message ?
|
||||
*/
|
||||
|
||||
#include <winsock2.h>
|
||||
|
||||
#include "ampler.h"
|
||||
|
@ -46,6 +54,51 @@ void udp_init(Ampler_state *state) {
|
|||
printf("error: bind returned SOCKET_ERROR, WSAGetLastError() = %i\n" , WSAGetLastError());
|
||||
}
|
||||
|
||||
void udp_quit(Ampler_state *state) {
|
||||
closesocket(udp_sock);
|
||||
WSACleanup();
|
||||
}
|
||||
|
||||
void recv_packet(Ampler_state *state) {
|
||||
char discard_buf[32] = { 0 }; // for dropped packets
|
||||
char *buf = discard_buf;
|
||||
int buf_len = sizeof discard_buf;
|
||||
|
||||
for (int i = 0; i < arraylen(state -> messages); i += 1) {
|
||||
Udp_msg *msg = &(state -> messages[i]);
|
||||
if (msg -> state == MSG_FREE) {
|
||||
msg -> state = MSG_TRIGGER;
|
||||
buf = msg -> text;
|
||||
buf_len = sizeof msg -> text;
|
||||
SDL_memset(buf, 0, buf_len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (buf == discard_buf)
|
||||
puts("dropped udp packet.");
|
||||
|
||||
struct sockaddr_in from_addr;
|
||||
int from_addr_size = sizeof from_addr;
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recvfrom
|
||||
int recv_len = recvfrom(
|
||||
udp_sock, // socket to recive on
|
||||
buf, // buffer for recv'd data
|
||||
buf_len - 1, // size of buffer in bytes, '- 1' preserves null terminator
|
||||
0, // flags
|
||||
&from_addr, // address struct to recieve source of packet
|
||||
&from_addr_size // POINTER to size of address struct
|
||||
);
|
||||
if (recv_len == SOCKET_ERROR)
|
||||
if (WSAGetLastError() != WSAEMSGSIZE) // packet was truncated to fit buffer
|
||||
printf("error: recvfrom returned SOCKET_ERROR, WSAGetLastError() = %i\n" , WSAGetLastError());
|
||||
|
||||
// convert to ipv4 address string, stored in static buffer, next call overwrites
|
||||
const char *from_ip_str = inet_ntoa(from_addr.sin_addr);
|
||||
int from_port = ntohs(from_addr.sin_port); // convert network to host byte order for short
|
||||
if (0) // FOR DEBUGGING
|
||||
printf("%s:%d\t%s\n", from_ip_str, from_port, buf);
|
||||
}
|
||||
|
||||
void udp_frame(Ampler_state *state) {
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-select
|
||||
fd_set recv_fd_set;
|
||||
|
@ -77,34 +130,10 @@ void udp_frame(Ampler_state *state) {
|
|||
return;
|
||||
}
|
||||
|
||||
char buf[16] = { 0 };
|
||||
struct sockaddr_in from_addr;
|
||||
int from_addr_size = sizeof from_addr;
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recvfrom
|
||||
int recv_len = recvfrom(
|
||||
udp_sock, // socket to recive on
|
||||
buf, // buffer for recv'd data
|
||||
sizeof buf - 1, // size of buffer in bytes, '- 1' preserves null terminator
|
||||
0, // flags
|
||||
&from_addr, // address struct to recieve source of packet
|
||||
&from_addr_size // POINTER to size of address struct
|
||||
);
|
||||
if (recv_len == SOCKET_ERROR)
|
||||
if (WSAGetLastError() != WSAEMSGSIZE) // packet was truncated to fit buffer
|
||||
printf("error: recvfrom returned SOCKET_ERROR, WSAGetLastError() = %i\n" , WSAGetLastError());
|
||||
|
||||
// convert to ipv4 address string, stored in static buffer, next call overwrites
|
||||
const char *from_ip_str = inet_ntoa(from_addr.sin_addr);
|
||||
int from_port = ntohs(from_addr.sin_port); // convert network to host byte order for short
|
||||
printf("%s\t\t%s:%d\n", buf, from_ip_str, from_port);
|
||||
recv_packet(state);
|
||||
}
|
||||
}
|
||||
|
||||
void udp_quit(Ampler_state *state) {
|
||||
closesocket(udp_sock);
|
||||
WSACleanup();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue