AudioBot/audio.c
2024-01-25 22:08:47 -05:00

125 lines
3.5 KiB
C

#include <stdio.h>
#include <rfb/rfbclient.h>
// The world if libvncclient let you easily connect to a server without using their own retarded argv shit
// (audio and name wouldn't even have to be 2 different binaries and password could easily be specified!!!)
#define VNC_PASSWORD "D0gg0!!!"
#define VNC_ENCODING_AUDIO 0XFFFFFEFD /* -259 */
#define VNC_MSG_CLIENT_QEMU 255
#define VNC_MSG_CLIENT_QEMU_AUDIO 1
#define VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE 0
#define VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE 1
#define VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT 2
#define VNC_MSG_SERVER_QEMU_AUDIO_END 0
#define VNC_MSG_SERVER_QEMU_AUDIO_BEGIN 1
#define VNC_MSG_SERVER_QEMU_AUDIO_DATA 2
#define AUDIO_FORMAT_U8 0
#define AUDIO_FORMAT_S8 1
#define AUDIO_FORMAT_U16 2
#define AUDIO_FORMAT_S16 3
#define AUDIO_FORMAT_U32 4
#define AUDIO_FORMAT_S32 5
#define VNC_QEMU_AUDIO_RATE 48000
#define VNC_QEMU_AUDIO_CHANNELS 2
#define VNC_QEMU_AUDIO_BPS 16
char * getpassword(rfbClient *client) {
return strdup(VNC_PASSWORD);
};
static rfbBool vnc_qemu_audio_encoding(rfbClient* client, rfbFramebufferUpdateRectHeader* rect) {
struct {
uint8_t type;
uint8_t msg_id;
uint16_t audio_id;
struct {
uint8_t format;
uint8_t channels;
char frequency[sizeof(uint32_t)];
} set_format;
} audio_format_msg = {
VNC_MSG_CLIENT_QEMU,
VNC_MSG_CLIENT_QEMU_AUDIO,
rfbClientSwap16IfLE(VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT),
AUDIO_FORMAT_S16,
VNC_QEMU_AUDIO_CHANNELS
};
*(uint32_t*) audio_format_msg.set_format.frequency = rfbClientSwap32IfLE(VNC_QEMU_AUDIO_RATE);
if (!WriteToRFBServer(client, (char*)& audio_format_msg, sizeof(audio_format_msg))) return FALSE;
struct {
uint8_t type;
uint8_t msg_id;
uint16_t audio_id;
} audio_enable_msg = {
VNC_MSG_CLIENT_QEMU,
VNC_MSG_CLIENT_QEMU_AUDIO,
rfbClientSwap16IfLE(VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE)
};
if (!WriteToRFBServer(client, (char*)& audio_enable_msg, sizeof(audio_enable_msg))) return FALSE;
return TRUE;
}
static rfbBool vnc_qemu_audio_msg(rfbClient* client, rfbServerToClientMsg* message) {
if (message->type != VNC_MSG_CLIENT_QEMU) return FALSE;
struct {
uint8_t msg_id;
char audio_id[sizeof(uint16_t)];
} msg;
if (!ReadFromRFBServer(client, (char*)&msg, sizeof(msg))) return TRUE;
if (msg.msg_id != VNC_MSG_CLIENT_QEMU_AUDIO) return TRUE;
switch (rfbClientSwap16IfLE(*(uint16_t*)msg.audio_id)) {
case VNC_MSG_SERVER_QEMU_AUDIO_BEGIN:
break;
case VNC_MSG_SERVER_QEMU_AUDIO_DATA: {
uint32_t size;
if (!ReadFromRFBServer(client, (char*) &size, sizeof(uint32_t))) return TRUE;
size = rfbClientSwap32IfLE(size);
char* data = malloc(size);
if (ReadFromRFBServer(client, data, size)) fwrite(data, sizeof(char), size, stdout);
free(data);
break;
};
case VNC_MSG_SERVER_QEMU_AUDIO_END:
break;
};
return TRUE;
}
static int QEMU_AUDIO_ENCODING[] = {VNC_ENCODING_AUDIO, 0};
static rfbClientProtocolExtension qemu_audio_extension = {
QEMU_AUDIO_ENCODING,
vnc_qemu_audio_encoding,
vnc_qemu_audio_msg,
NULL,
NULL,
NULL
};
int main(int argc, char **argv) {
rfbClient* client = rfbGetClient(8,3,4);
client->GetPassword = getpassword;
rfbClientRegisterExtension(&qemu_audio_extension);
if (!rfbInitClient(client,&argc,argv)) return 1;
while (1) {
if (WaitForMessage(client,50) < 0) break;
if (!HandleRFBServerMessage(client)) break;
};
rfbClientCleanup(client);
return 0;
}