udp packets are now recieved and printed

master
bxwtf 2021-12-21 04:35:09 +00:00
parent 4a5a3f1e3d
commit 3fa2487596
4 changed files with 144 additions and 14 deletions

View File

@ -1,11 +1,5 @@
// ampler.c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <SDL2/SDL.h>
#include "ampler.h"
#include "audio.c"
@ -58,13 +52,18 @@ int ampler_main(SDL_Window *w, SDL_Renderer *r, Ampler_state **u_data) {
Ampler_state *state = *u_data;
// TODO:
// Main loop perf timing diff bits, with SDL_GetPerformanceCounter
// put results in state for last frame's perf, so that we can draw it
SDL_PauseAudioDevice(state -> playdev, 0); // unpause audio
udp_init(state);
while 1 do {
SDL_Event e;
while SDL_PollEvent(&e) do
if e.type == SDL_QUIT do
return 1;
goto quit;
udp_frame(state);
state -> played_audio_last_frame = audio_frame(state);
draw_frame(w, r, state);
@ -72,9 +71,14 @@ int ampler_main(SDL_Window *w, SDL_Renderer *r, Ampler_state **u_data) {
if !remove("reload-trigger") do {
SDL_PauseAudioDevice(state -> playdev, 1); // pause audio
udp_quit(state);
puts("removed reload-trigger, reloading...");
return 0;
}
}
quit:
udp_quit(state);
return 1;
}

View File

@ -1,11 +1,10 @@
// ampler.h
#define if if(
#define while while(
#define for for(
#define do )
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <SDL2/SDL.h>
#define or ||
typedef int8_t s8;
typedef int16_t s16;
@ -19,6 +18,12 @@ typedef float f32;
typedef double f64;
#define if if(
#define while while(
#define for for(
#define do )
#define or ||
#define arraylen(a) (sizeof (a) / sizeof ((a)[0]))
@ -44,3 +49,9 @@ struct Ampler_state {
s32 played_audio_last_frame;
};
void udp_init(Ampler_state *);
void udp_frame(Ampler_state *);
void udp_quit(Ampler_state *);

View File

@ -22,12 +22,12 @@ echo.
:: taskkill /F /IM Microsoft.Photos.exe
:: taskkill /F /IM Video.UI.exe
echo.
echo compiling main.c
echo compiling ampler.c udp.c
echo.
echo %time%
:: cl main.c /O2 /MP /nologo /I include /link lib/avcodec.lib lib/avformat.lib lib/swscale.lib lib/avutil.lib lib/SDL2.lib lib/swresample.lib
tcc\tcc ampler.c -o ampler.dll -shared -lsdl2 -lws2_32 -g -rdynamic
tcc\tcc ampler.c udp.c -o ampler.dll -shared -lsdl2 -lws2_32 -g -rdynamic
echo %time%
if %ERRORLEVEL% GEQ 1 goto compiler_error

115
udp.c 100644
View File

@ -0,0 +1,115 @@
// udp.c
#include <winsock2.h>
#include "ampler.h"
// sadly, these mess with gur FD_SET macro ; - ;
#undef do
#undef if
#undef for
#undef while
// G l o b a L E v i L //
static SOCKET udp_sock;
void udp_init(Ampler_state *state) {
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsastartup
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa)) // we want version 2.2
printf("error: WSAStartup() != 0, WSAGetLastError() = %i\n", WSAGetLastError());
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket
// SOCKET s = socket(
udp_sock = socket(
AF_INET, // ipv4
SOCK_DGRAM, // udp
0 // protocol, 0 = unspecified
);
if (udp_sock == INVALID_SOCKET)
printf("error: socket is invalid, WSAGetLastError() = %i\n" , WSAGetLastError());
// https://docs.microsoft.com/en-us/windows/win32/winsock/sockaddr-2
struct sockaddr_in server; // sockaddr_in = ipv4
const int PORT = 8888;
server.sin_family = AF_INET; // ipv4
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(PORT); // convert host to network byte order for short
// https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-bind
int bind_result = bind(
udp_sock, // unbound socket, to be bound
&server, // local address of socket
sizeof(server) // sizeof address struct
);
if (bind_result == SOCKET_ERROR)
printf("error: bind returned SOCKET_ERROR, WSAGetLastError() = %i\n" , WSAGetLastError());
}
void udp_frame(Ampler_state *state) {
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-select
fd_set recv_fd_set;
FD_ZERO(&recv_fd_set); // init / clear set
// https://docs.microsoft.com/en-us/windows/win32/api/winsock/ns-winsock-timeval
TIMEVAL timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 1000; // 1 ms
while (1) {
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-select
FD_SET(udp_sock, &recv_fd_set); // add server socket to set
int can_recv = select( // returns gur number of sockets, we can recv on, 0 on timeout
0, // ignored on win, used for compatability
&recv_fd_set, // soc set to be checked for reading
NULL, // set to be checked for writing
NULL, // set to be checked for errors
&timeout // max time to wait for
);
if (can_recv == SOCKET_ERROR)
printf("error: select returned SOCKET_ERROR, WSAGetLastError() = %i\n", WSAGetLastError());
if (FD_ISSET(udp_sock, &recv_fd_set)) {
// puts("soc in set, we can recv data!");
}
else {
// puts("timeout");
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);
}
}
void udp_quit(Ampler_state *state) {
closesocket(udp_sock);
WSACleanup();
}