FreeRDP
Loading...
Searching...
No Matches
wf_rdpsnd.c
1
21#include <freerdp/config.h>
22
23#include <stdio.h>
24#include <stdlib.h>
25
26#include <winpr/windows.h>
27#include <freerdp/server/server-common.h>
28
29#include "wf_rdpsnd.h"
30#include "wf_info.h"
31
32#ifdef WITH_RDPSND_DSOUND
33
34#include "wf_directsound.h"
35
36#else
37
38#include "wf_wasapi.h"
39
40#endif
41
42#include <freerdp/log.h>
43#define TAG SERVER_TAG("windows")
44
45static void wf_peer_rdpsnd_activated(RdpsndServerContext* context)
46{
47 wfInfo* wfi;
48 wfi = wf_info_get_instance();
49 wfi->agreed_format = NULL;
50 WLog_DBG(TAG, "Client supports the following %d formats:", context->num_client_formats);
51
52 size_t i = 0;
53 for (; i < context->num_client_formats; i++)
54 {
55 // TODO: improve the way we agree on a format
56 for (size_t j = 0; j < context->num_server_formats; j++)
57 {
58 if ((context->client_formats[i].wFormatTag == context->server_formats[j].wFormatTag) &&
59 (context->client_formats[i].nChannels == context->server_formats[j].nChannels) &&
60 (context->client_formats[i].nSamplesPerSec ==
61 context->server_formats[j].nSamplesPerSec))
62 {
63 WLog_DBG(TAG, "agreed on format!");
64 wfi->agreed_format = (AUDIO_FORMAT*)&context->server_formats[j];
65 break;
66 }
67 }
68
69 if (wfi->agreed_format != NULL)
70 break;
71 }
72
73 if (wfi->agreed_format == NULL)
74 {
75 WLog_ERR(TAG, "Could not agree on a audio format with the server");
76 return;
77 }
78
79 context->SelectFormat(context, i);
80 context->SetVolume(context, 0x7FFF, 0x7FFF);
81#ifdef WITH_RDPSND_DSOUND
82 wf_directsound_activate(context);
83#else
84 wf_wasapi_activate(context);
85#endif
86}
87
88int wf_rdpsnd_lock()
89{
90 DWORD dRes;
91 wfInfo* wfi;
92 wfi = wf_info_get_instance();
93 dRes = WaitForSingleObject(wfi->snd_mutex, INFINITE);
94
95 switch (dRes)
96 {
97 case WAIT_ABANDONED:
98 case WAIT_OBJECT_0:
99 return TRUE;
100 break;
101
102 case WAIT_TIMEOUT:
103 return FALSE;
104 break;
105
106 case WAIT_FAILED:
107 WLog_ERR(TAG, "wf_rdpsnd_lock failed with 0x%08lX", GetLastError());
108 return -1;
109 break;
110 }
111
112 return -1;
113}
114
115int wf_rdpsnd_unlock()
116{
117 wfInfo* wfi;
118 wfi = wf_info_get_instance();
119
120 if (ReleaseMutex(wfi->snd_mutex) == 0)
121 {
122 WLog_DBG(TAG, "wf_rdpsnd_unlock failed with 0x%08lX", GetLastError());
123 return -1;
124 }
125
126 return TRUE;
127}
128
129BOOL wf_peer_rdpsnd_init(wfPeerContext* context)
130{
131 wfInfo* wfi = wf_info_get_instance();
132
133 if (!wfi)
134 return FALSE;
135
136 if (!(wfi->snd_mutex = CreateMutex(NULL, FALSE, NULL)))
137 return FALSE;
138
139 context->rdpsnd = rdpsnd_server_context_new(context->vcm);
140 context->rdpsnd->rdpcontext = &context->_p;
141 context->rdpsnd->data = context;
142 context->rdpsnd->num_server_formats =
143 server_rdpsnd_get_formats(&context->rdpsnd->server_formats);
144
145 if (context->rdpsnd->num_server_formats > 0)
146 context->rdpsnd->src_format = &context->rdpsnd->server_formats[0];
147
148 context->rdpsnd->Activated = wf_peer_rdpsnd_activated;
149 context->rdpsnd->Initialize(context->rdpsnd, TRUE);
150 wf_rdpsnd_set_latest_peer(context);
151 wfi->snd_stop = FALSE;
152 return TRUE;
153}