-
Notifications
You must be signed in to change notification settings - Fork 0
/
broadcaster.cpp
172 lines (130 loc) · 4.76 KB
/
broadcaster.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/*
Name: Broadcaster.cpp
Description: UDP Broadcaster for encoded Opus audio packets
SRI International
InSys Intern: Amy Huang
Date: 11/30/2022
*/
#include "winsock2.h"
#include <iostream>
#include <conio.h>
#include <fstream>
#include "audio.cpp"
using namespace std;
#define MYPORT 9009 // the port users will be connecting to
#define WRITE_FILE 0 // Change to 1 if you want to write the opus file (read and write can't be on the same time)
#define READ_FILE 0 // Change to 1 if you want to read from opus file
#pragma comment(lib, "Ws2_32.lib")
struct Packet
{
uint8_t datasize;
uint8_t data[20]; //AUDIO packet payload
};
int main()
{
/* SOCKET SECTION */
WSADATA wsaData;
WSAStartup( MAKEWORD( 2, 2 ), &wsaData );
SOCKET sock;
sock = socket( AF_INET, SOCK_DGRAM, 0 );
char broadcast = '1';
if ( setsockopt( sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast) ) < 0 )
{
cout<<"Error in setting Broadcast option";
closesocket(sock);
return 0;
}
struct sockaddr_in Recv_addr;
// struct sockaddr_in Sender_addr;
int len = sizeof( struct sockaddr_in );
Recv_addr.sin_family = AF_INET;
Recv_addr.sin_port = htons( MYPORT );
Recv_addr.sin_addr.s_addr = INADDR_BROADCAST;
/* END OF SOCKET SECTION */
// Init portaudio
PaError paErr = Pa_Initialize();
if (paErr)
throw std::runtime_error(string("Could not start audio. Pa_Initialize error: ") + Pa_GetErrorText(paErr));
// Init opus encoder
int opusErr;
encoder = opus_encoder_create(SAMPLE_RATE, CHANNELS, OPUS_APPLICATION_VOIP, &opusErr);
if (opusErr != OPUS_OK)
throw std::runtime_error(string("opus_encoder_create error: ") + opus_strerror(opusErr));
opusErr = opus_encoder_ctl(encoder, OPUS_SET_BITRATE(8000));
if (opusErr != OPUS_OK) {
throw std::runtime_error(string("opus set bitrate error: ") + opus_strerror(opusErr));
}
opusErr = opus_encoder_ctl(encoder, OPUS_SET_COMPLEXITY(0));
if (opusErr != OPUS_OK) {
throw std::runtime_error(string("opus set complexity error: ") + opus_strerror(opusErr));
}
opusErr = opus_encoder_ctl(encoder, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));
if (opusErr != OPUS_OK) {
throw std::runtime_error(string("opus set max bandwidth error: ") + opus_strerror(opusErr));
}
opusErr = opus_encoder_ctl(encoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
if (opusErr != OPUS_OK) {
throw std::runtime_error(string("opus set signal error: ") + opus_strerror(opusErr));
}
beginAudioStream(true, false);
cout << "Sound in : " << Pa_GetDeviceInfo( Pa_GetDefaultInputDevice() )->name << endl;
#if WRITE_FILE
char output[50];
cout << "File name to write to: " << endl;
cin >> output;
ofstream rec_file;
#endif
#if READ_FILE
char input[50];
cout << "File name to read from: " << endl;
cin >> input;
ifstream audio_file;
audio_file.open(input, ios::binary);
uint8_t sendMSG[25];
while(audio_file)
{
Packet pack;
audio_file.read((char*)&pack.datasize, 1);
audio_file.read((char*)pack.data, pack.datasize);
cout << "size: " << int(pack.datasize) << " Packet: ";
for(int i = 0; i < pack.datasize ; i++)
{
cout << (int)pack.data[i] << " ";
}
cout << endl;
sendto( sock, (char*)&pack, int(pack.datasize + 1) , 0,(sockaddr*) &Recv_addr, sizeof( Recv_addr ) );
}
#else
while(1)
{
if(Pa_GetStreamReadAvailable(stream) >= PACKET_SAMPLES)
{
opus_int16 microphone[PACKET_SAMPLES];
PaError paErr = Pa_ReadStream(stream, microphone, PACKET_SAMPLES);
if (paErr && paErr != paInputOverflowed)
throw std::runtime_error(string("Pa_ReadStream error: ") + Pa_GetErrorText(paErr));
Packet pack;
opus_int32 enc = opus_encode(encoder, microphone, PACKET_SAMPLES, pack.data, sizeof(pack.data));
if (enc < 0)
throw std::runtime_error(string("opus_encode error: ") + opus_strerror(enc));
pack.datasize = enc;
cout << "size: " << int(pack.datasize) << " Packet: ";
for(int i = 0; i < pack.datasize ; i++)
{
cout << (int)pack.data[i] << " ";
}
cout << endl;
#if WRITE_FILE
rec_file.open(output, ios::app | ios::binary);
rec_file.write((char*)&pack.datasize, sizeof(pack.datasize));
rec_file.write((char*)pack.data, enc);
rec_file.close();
#endif
sendto( sock, (char*)&pack, int(pack.datasize + 1) , 0,(sockaddr*) &Recv_addr, sizeof( Recv_addr ) );
}
}
#endif
endAudioStream();
closesocket( sock );
WSACleanup();
}