8
8
9
9
#include <pthread.h>
10
10
#include <stdint.h>
11
+ #include <string.h>
12
+ #include <sys/time.h>
11
13
12
14
#include "gamepad.h"
13
15
#include "vanilla.h"
@@ -35,6 +37,96 @@ typedef struct {
35
37
uint32_t video_format ;
36
38
} AudioPacketVideoFormat ;
37
39
40
+ static unsigned char queued_audio [2048 ];
41
+ static size_t queued_audio_start = 0 ;
42
+ static size_t queued_audio_end = 0 ;
43
+ static pthread_mutex_t queued_audio_mutex ;
44
+
45
+ int send_audio_packet (const void * data , size_t len )
46
+ {
47
+ pthread_mutex_lock (& queued_audio_mutex );
48
+
49
+ for (size_t i = 0 ; i < len ; ) {
50
+ size_t phys = queued_audio_end % sizeof (queued_audio );
51
+ size_t max_write = MIN (sizeof (queued_audio ) - phys , len - i );
52
+ memcpy (queued_audio + phys , ((const unsigned char * ) data ) + i , max_write );
53
+ i += max_write ;
54
+ queued_audio_end += max_write ;
55
+ }
56
+
57
+ pthread_mutex_unlock (& queued_audio_mutex );
58
+
59
+ return VANILLA_SUCCESS ;
60
+ }
61
+
62
+ static void handle_queued_audio (gamepad_context_t * ctx , int seq_id )
63
+ {
64
+ AudioPacket ap ;
65
+
66
+ // Initialize payload size to zero
67
+ const size_t MIC_PAYLOAD_SIZE = 512 ;
68
+ ap .payload_size = 0 ;
69
+
70
+ // Lock mutex
71
+ pthread_mutex_lock (& queued_audio_mutex );
72
+
73
+ // If available, copy over to our packet
74
+ if (queued_audio_end >= (queued_audio_start + MIC_PAYLOAD_SIZE )) {
75
+ for (size_t i = 0 ; i < MIC_PAYLOAD_SIZE ; ) {
76
+ size_t phys = queued_audio_start % sizeof (queued_audio );
77
+ size_t max_write = MIN (sizeof (queued_audio ) - phys , MIC_PAYLOAD_SIZE - i );
78
+ memcpy (ap .payload + i , queued_audio + queued_audio_start , max_write );
79
+ i += max_write ;
80
+ queued_audio_start += max_write ;
81
+ }
82
+ ap .payload_size = MIC_PAYLOAD_SIZE ;
83
+ }
84
+
85
+ // Unlock
86
+ pthread_mutex_unlock (& queued_audio_mutex );
87
+
88
+ // If we didn't get audio, return here
89
+ if (!ap .payload_size ) {
90
+ return ;
91
+ }
92
+
93
+ // struct timeval tv;
94
+ // gettimeofday(&tv, 0);
95
+ // if ((tv.tv_sec % 2) == 1) {
96
+ // for (int i = 0; i < ap.payload_size; i++) {
97
+ // ap.payload[i] = (rand() % 0xFF);
98
+ // }
99
+ // vanilla_log("NOISE!");
100
+ // } else {
101
+ // memset(ap.payload, 0x00, ap.payload_size);
102
+ // vanilla_log("...quiet...");
103
+ // }
104
+
105
+ // Set up remaining default parameters
106
+ ap .format = 6 ;
107
+ ap .mono = 1 ;
108
+ ap .vibrate = 0 ;
109
+ ap .type = TYPE_AUDIO ; // Audio data
110
+ ap .seq_id = seq_id + 1 ;
111
+ ap .timestamp = 0 ;
112
+
113
+ // Reverse bits on params
114
+ ap .format = reverse_bits (ap .format , 3 );
115
+ ap .seq_id = reverse_bits (ap .seq_id , 10 );
116
+ ap .payload_size = reverse_bits (ap .payload_size , 16 );//ntohs(ap.payload_size);
117
+ // ap.timestamp = reverse_bits(ap.timestamp, 32); // Not necessary because timestamp is 0
118
+
119
+ // Further reverse bits
120
+ unsigned char * bytes = (unsigned char * ) & ap ;
121
+ const size_t header_sz = sizeof (AudioPacket ) - sizeof (ap .payload );
122
+ for (int i = 0 ; i < header_sz ; i ++ ) {
123
+ bytes [i ] = (unsigned char ) reverse_bits (bytes [i ], 8 );
124
+ }
125
+
126
+ // Send packet to console
127
+ send_to_console (ctx -> socket_aud , & ap , header_sz + ap .payload_size , PORT_AUD );
128
+ }
129
+
38
130
void handle_audio_packet (gamepad_context_t * ctx , unsigned char * data , size_t len )
39
131
{
40
132
//
@@ -43,16 +135,16 @@ void handle_audio_packet(gamepad_context_t *ctx, unsigned char *data, size_t len
43
135
// This for loop skips ap->format, ap->seq_id, and ap->timestamp to save processing.
44
136
// If you want those, you'll have to adjust this loop.
45
137
//
46
- for (int byte = 0 ; byte < 2 ; byte ++ ) {
138
+ for (int byte = 0 ; byte < 8 ; byte ++ ) {
47
139
data [byte ] = (unsigned char ) reverse_bits (data [byte ], 8 );
48
140
}
49
141
50
142
AudioPacket * ap = (AudioPacket * ) data ;
51
143
52
- // ap->format = reverse_bits(ap->format, 3);
53
- // ap->seq_id = reverse_bits(ap->seq_id, 10);
54
- ap -> payload_size = ntohs (ap -> payload_size );
55
- // ap->timestamp = reverse_bits(ap->timestamp, 32);
144
+ ap -> format = reverse_bits (ap -> format , 3 );
145
+ ap -> seq_id = reverse_bits (ap -> seq_id , 10 );
146
+ ap -> payload_size = reverse_bits ( ap -> payload_size , 16 ); // ntohs(ap->payload_size);
147
+ ap -> timestamp = reverse_bits (ap -> timestamp , 32 );
56
148
57
149
if (ap -> type == TYPE_VIDEO ) {
58
150
AudioPacketVideoFormat * avp = (AudioPacketVideoFormat * ) ap -> payload ;
@@ -69,19 +161,29 @@ void handle_audio_packet(gamepad_context_t *ctx, unsigned char *data, size_t len
69
161
70
162
uint8_t vibrate_val = ap -> vibrate ;
71
163
push_event (ctx -> event_loop , VANILLA_EVENT_VIBRATE , & vibrate_val , sizeof (vibrate_val ));
164
+
165
+ handle_queued_audio (ctx , ap -> seq_id );
72
166
}
73
167
74
168
void * listen_audio (void * x )
75
169
{
76
170
gamepad_context_t * info = (gamepad_context_t * ) x ;
77
171
unsigned char data [2048 ];
78
172
ssize_t size ;
173
+
174
+ queued_audio_start = 0 ;
175
+ queued_audio_end = 0 ;
176
+
177
+ pthread_mutex_init (& queued_audio_mutex , 0 );
178
+
79
179
do {
80
180
size = recv (info -> socket_aud , data , sizeof (data ), 0 );
81
181
if (size > 0 ) {
82
182
handle_audio_packet (info , data , size );
83
183
}
84
184
} while (!is_interrupted ());
185
+
186
+ pthread_mutex_destroy (& queued_audio_mutex );
85
187
86
188
pthread_exit (NULL );
87
189
0 commit comments