This is a read-only archive of the Mumble forums.

This website archives and makes accessible historical state. It receives no updates or corrections. It is provided only to keep the information accessible as-is, under their old address.

For up-to-date information please refer to the Mumble website and its linked documentation and other resources. For support please refer to one of our other community/support channels.

Jump to content

Positional sound (Linux)


art24
 Share

Recommended Posts

Hi,


I just want to apologize first because I have tried to search the forum to find the answers to my questions but I have not been able to do it, too common words to search...


I have been trying to use the Link plugin (http://wiki.mumble.info/wiki/Link) in my own application, and I managed to make it work in Windows without problems. However, it is not working in Linux. Apparently, everything should work (I am not getting any error during the initialization), the shared memory seems to work fine because if the mumble client is not working I get an error message (the LinkedMemory struct is not initialized).


I do not really know what to do because it is really hard to find information about this on the internet... Have any of you tried to do it? Besides, I tried to compile the "mumble-pahelper" (https://github.com/mumble-voip/mumble-pahelper) but again, no luck compiling it in Linux. Is there any other way to test that the link plugin is working?


Thanks in advance.


Regards.


PS: I have not been able to make the overlay work on linux either, I do not know if this could have any relation to my problems with the link plugin

Link to comment
Share on other sites

  • Administrators

Should just work out of the box on Linux. I haven't checked recently but the last time I personally used it on Linux was when TF2 et. al. hit Linux (2013ish?) specifically to check their Link implementation worked with the Linux client. Is your project public? I doubt the integration is the problem but checking doesn't hurt.


Not sure if anyone ever compiled pahelper for Linux. Wrote it to debug non-link plugins on Windows and under the assumption that it could be made to work easily on Linux if ever needed so I didn't bother porting it right away.


A few questions:

  1. What version of Mumble are you using?
  2. What distro?
  3. What architecture?
  4. Is your application 32 or 64bit?

Link to comment
Share on other sites

Thank you hacst for you quick response.


Unfortunately, my project is not public yet :( it may be at some point, but not now. However, I could share the class I use to link with Mumble. As you can imagine, the most important part of this class is the code taken from (http://wiki.mumble.info/wiki/Link), and the same project is working fine on Windows, so I do not know where the problem can be...


Regarding pahelper, the problem when I try to compile it is in mumble/plugins/mumble_plugin.h, in parts like this one: void (__cdecl *config)(HWND); where __cdecl and HWND are not linux friendly (taking into account that I have never been very "linux friendly"... so I do not have much experience dealing with this problems).


To answer your questions:

1. What version of Mumble are you using?

I am using 1.2.8 in Windows and 1.2.4-0.2ubuntu1.1 in Linux, installed both last week. The mumble code used to compile pahelper is the master branch in github.

2. What distro?

I have tried Ubuntu 14.04.1 LTS and Linux Mint 17 Qiana

3. What architecture?

I have used Ubuntu in a virtual machine (virtual box) in an intel i7, and Mint in an old Atom netbook.

4. Is your application 32 or 64bit?

32 bit, but will be 64 in the future.


Here is the code, in case it can help to spot some unnoticed mistake. One more thing is that when I run my project, the Mumble client shows the text "TestProject linked" in both systems, and I do not get any error with the LinkedMem struct not initialized. Of course, the positional audio is activated in the mumble client both in the plugins and audio output sections (in both systems).


Header file:

#ifndef CDMumbleLinkWrapper_H
#define	CDMumbleLinkWrapper_H
#ifdef WIN32
#include <windows.h>
#include <AtlBase.h>	
#else
#include <unistd.h>	
#include <sys/mman.h>	
#include <fcntl.h>		
#include <cstring>	
#endif
#include "string"

class CDMumbleLinkWrapper
{
	public:
	struct LinkedMem {
	#ifdef WIN32
		UINT32	uiVersion;
		DWORD	uiTick;
	#else
		uint32_t uiVersion;
		uint32_t uiTick;
	#endif
		float	fAvatarPosition[3];
		float	fAvatarFront[3];
		float	fAvatarTop[3];
		wchar_t	name[256];
		float	fCameraPosition[3];
		float	fCameraFront[3];
		float	fCameraTop[3];
		wchar_t	identity[256];
	#ifdef WIN32
		UINT32	context_len;
	#else
		uint32_t context_len;
	#endif
		unsigned char context[256];
		wchar_t description[2048];
	};
	CDMumbleLinkWrapper(std::string userID);
	~CDMumbleLinkWrapper(void);
	bool init();
	void update(float x, float y, float z);
	bool isLinked();
private:
	LinkedMem	*_lm;
	std::string	_userID;
};
#endif // CDMumbleLinkWrapper_H

CPP file:

 

#include "CDMumbleLinkWrapper.h"
//#include <AtlBase.h>

CDMumbleLinkWrapper::CDMumbleLinkWrapper(std::string userID)
{
_lm = NULL;
_userID = userID;
}

CDMumbleLinkWrapper::~CDMumbleLinkWrapper(void)
{
}

bool CDMumbleLinkWrapper::init()
{
#ifdef WIN32
HANDLE hMapObject = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, L"MumbleLink");
if (hMapObject == NULL)
	return false;

_lm = (LinkedMem *) MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(LinkedMem));
if (_lm == NULL) {
	CloseHandle(hMapObject);
	hMapObject = NULL;
	return false;
}
#else
char memname[256];
snprintf(memname, 256, "/MumbleLink.%d", getuid());

int shmfd = shm_open(memname, O_RDWR, S_IRUSR | S_IWUSR);

if (shmfd < 0) {
	printf("Mumble not initialized!!\n");
	return false;
}

_lm = (LinkedMem *)(mmap(NULL, sizeof(LinkedMem), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd,0));

if (_lm == (void *)(-1)) {
	_lm = NULL;
	return false;
}
#endif
return true;
}

bool CDMumbleLinkWrapper::isLinked()
{
      return _lm != NULL;
}

void CDMumbleLinkWrapper::update(float x, float y, float z)
{
if (! _lm)
	return;

if(_lm->uiVersion != 2) {
	wcsncpy(_lm->name, L"TestProject", 256);
	wcsncpy(_lm->description, L"TestLink is a test of the Link plugin.", 2048);
	_lm->uiVersion = 2;
}
_lm->uiTick++;

// Left handed coordinate system.
// X positive towards "right".
// Y positive towards "up".
// Z positive towards "front".
//
// 1 unit = 1 meter

// Unit vector pointing out of the avatars eyes (here Front looks into scene).
_lm->fAvatarFront[0] = 0.0f;
_lm->fAvatarFront[1] = 0.0f;
_lm->fAvatarFront[2] = 1.0f;

// Unit vector pointing out of the top of the avatars head (here Top looks straight up).
_lm->fAvatarTop[0] = 0.0f;
_lm->fAvatarTop[1] = 1.0f;
_lm->fAvatarTop[2] = 0.0f;

// Position of the avatar (here standing slightly off the origin)
_lm->fAvatarPosition[0] = x;
_lm->fAvatarPosition[1] = z;
_lm->fAvatarPosition[2] = y;

// Same as avatar but for the camera.
_lm->fCameraPosition[0] = x;
_lm->fCameraPosition[1] = z;
_lm->fCameraPosition[2] = y;

_lm->fCameraFront[0] = 0.0f;
_lm->fCameraFront[1] = 0.0f;
_lm->fCameraFront[2] = 1.0f;

_lm->fCameraTop[0] = 0.0f;
_lm->fCameraTop[1] = 1.0f;
_lm->fCameraTop[2] = 0.0f;

// Identifier which uniquely identifies a certain player in a context (userID).
std::wstring w = std::wstring(_userID.begin(), _userID.end());
wcsncpy(_lm->identity, w.c_str(), 256);

// Context should be equal for players which should be able to hear each other positional and
// differ for those who shouldn't (group members?)
memcpy(_lm->context, "ALL", 16);
_lm->context_len = 16;
}

 

Again, thank you so much for your time.


Regards,

Arturo


PS: during my first tests I am using only 2D positions on screen, so that is why the code does not care about avatar/camera top/front.

Link to comment
Share on other sites

I have donwloaded and compiled mumble 1.2.8 in Linux just because I realized I was using different versions on windows and linux, but with the same result, no positional audio at all...


UPDATE: New advances, the positional audio is working ONLY if I use the manual placement plugin. I think that this discards having a problem with the mumble client itself, it should be in the link plugin or (more likely) in my code...


UPDATE2: Using three users (four computers), 2 windows and 1 linux (+ 1 linux murmur), the two windows have PA working, but the linux not...

Link to comment
Share on other sites

  • Administrators

This might already be the reason:

   memcpy(_lm->context, "ALL", 16);
  _lm->context_len = 16;

Your context is only 4 (ALL + zero termination) characters long yet you tell it to copy 16 and then to use all of those 16 bytes. Seems like you C&P that from our sample code which had a longer context sample string without adjusting it.


This out of bound read might cause arbitrary memory contents to become part of the context which would explain why the plugin links but no PA interaction is possible (context must match exactly).


The reason why you have to use memcpy and manually specify the length instead of more usual string operations is that we allow things like zero termination characters in that string so we cannot handle it like a normal C-String.

Link to comment
Share on other sites

:oops: of course, that solved the problem!!


Thank you so much for your help. What was confusing me was that it worked in windows, but of course it was the same binaries build in the same computer, so the "extra" content of the mumble context was always the same, and as a result they matched and it worked fine.


I will be more careful with the copy and paste in the future ;).


Regards!

Link to comment
Share on other sites

 Share

×
×
  • Create New...