Thread overview
ioctl to set mixer volume
Apr 16, 2021
Alain De Vos
Apr 16, 2021
Adam D. Ruppe
Apr 16, 2021
Dennis
Apr 16, 2021
Alain De Vos
Apr 16, 2021
Alain De Vos
Apr 17, 2021
Alain De Vos
Apr 17, 2021
Boris Carvajal
Apr 17, 2021
Alain De Vos
April 16, 2021

The following very simple low level C-function simply sets the mixer volume. How to convert this simple function to dlang ?

void mixer_setlevel_stereo(int mixfd,int dev,int left,int right)
{
left+=256*right;
#int_ioctl(int fd, unsigned long request, ...);
ioctl(mixfd,
((unsigned long) (((0x80000000UL|0x40000000UL)) | (((sizeof(int)) & ((1 << 13) - 1)) << 16) | ((('M')) << 8) | ((dev)))),
&left);
}
April 16, 2021

On Friday, 16 April 2021 at 17:50:13 UTC, Alain De Vos wrote:

>

The following very simple low level C-function simply sets the mixer volume. How to convert this simple function to dlang ?

import core.stdc.config;
import core.sys.posix.sys.ioctl;
void mixer_setlevel_stereo(int mixfd,int dev,int left,int right)
{
left+=256*right;
ioctl(mixfd,
(cast(c_ulong) (((0x80000000UL|0x40000000UL)) | (((int.sizeof) & ((1 << 13) - 1)) << 16) | ((('M')) << 8) | ((dev)))),
&left);
}

something like that it is almost identical

April 16, 2021

On Friday, 16 April 2021 at 17:50:13 UTC, Alain De Vos wrote:

>

The following very simple low level C-function simply sets the mixer volume. How to convert this simple function to dlang ?

void mixer_setlevel_stereo(int mixfd,int dev,int left,int right)
{
left+=256*right;
#int_ioctl(int fd, unsigned long request, ...);
ioctl(mixfd,
((unsigned long) (((0x80000000UL|0x40000000UL)) | (((sizeof(int)) & ((1 << 13) - 1)) << 16) | ((('M')) << 8) | ((dev)))),
&left);
}

You could change sizeof(int) to int.sizeof and (unsigned long) to cast(uint) in this case, but it seems you expanded the IOWR macro resulting in the ugly mess of bitwise operations.

I did a search for your function name and found what I think is the original C code:

void mixer_setlevel_stereo(int mixfd,int dev,int left,int right)
{
  left+=256*right;
  ioctl(mixfd,MIXER_WRITE(dev),&left);
}

Looking at my /usr/include/linux/soundcard.h:

#define MIXER_WRITE(dev)		_SIOWR('M', dev, int)

And _SIOWR looks identical to IOWR, so I think this is a correct translation:

import core.sys.posix.sys.ioctl: ioctl, _IOWR;

void mixer_setlevel_stereo(int mixfd, int dev, int left, int right)
{
	left += 256 * right;
	ioctl(mixfd, _IOWR!int('M', dev), &left);
}
April 16, 2021

I had to copy over a downloaded ioctl.d to the directory ./core/sys/posix/
I don't know why. But with this dub seems to work. Weird ???

I had forgotten I needed also an integer file handle to provide to ioctrl; cfr this code which puts the volume on maximum on my PC.
So I need if fact this to dlang ... somehow ...

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
char *mixerdev="/dev/mixer";
int main(int argc,char *argv[])
{
int mixfd=open(mixerdev,O_RDWR);
int left=255*255+255;
unsigned int x=3221507328U;
ioctl(mixfd,x,&left);
close(mixfd);
exit(0);
}
April 16, 2021

I tried :

import std.stdio;
import core.sys.posix.ioctl;
import core.stdc.config;
import core.stdc.stdio;

void main() {
	writeln("Set vol to min");
	char *mixerdev=cast(char *)"/dev/mixer";
	char *mode=cast(char *)"rw";
	int mixfd=cast(int)fopen(mixerdev,mode);
	writeln(mixfd);
	c_ulong x=3221507328;
	int left=0;
	ioctl(mixfd,x, &left);
}

But I think I did here a mysterious cast of a FILE* handle to int , which is probably rubbish ....

April 17, 2021

After some fiddling i finally got it.
A d-lang program which sets my volume to zero.

import std.stdio;
import core.sys.posix.ioctl;
import core.stdc.config;
import core.stdc.stdio;
void main() {
writeln("Set vol to min");
char *mixerdev=cast(char *)"/dev/mixer";
char *mode=cast(char *)"rw";
int mixfd=(fopen(mixerdev,mode)).fileno;
writeln(mixfd);
c_ulong x=3221507328;
int left=0;
ioctl(mixfd,x, &left);
}

The function .fileno returns the "underlying handle" of the FILE "object".

April 17, 2021

On Saturday, 17 April 2021 at 00:05:41 UTC, Alain De Vos wrote:

>

After some fiddling i finally got it.
A d-lang program which sets my volume to zero.

import std.stdio;
import core.sys.posix.ioctl;
import core.stdc.config;
import core.stdc.stdio;
void main() {
writeln("Set vol to min");
char *mixerdev=cast(char *)"/dev/mixer";
char *mode=cast(char *)"rw";
int mixfd=(fopen(mixerdev,mode)).fileno;
writeln(mixfd);
c_ulong x=3221507328;
int left=0;
ioctl(mixfd,x, &left);
}

The function .fileno returns the "underlying handle" of the FILE "object".

Here you could avoid C stdio and just use posix functions like core.sys.posix.fcntl : open that returns a file descriptor directly.

April 17, 2021

Correct, then i have :

import std.stdio: writeln;
import core.sys.posix.fcntl: open,O_RDWR;
import core.sys.posix.unistd : close;
import core.sys.posix.ioctl: ioctl;
import core.stdc.config: c_ulong;

void main() {
	writeln("Set vol to max");
	char *mixerdev=cast(char *)"/dev/mixer";
	int mode=O_RDWR;
	int mixfd=open(mixerdev,mode);
	writeln(mixfd);
	c_ulong fun=3221507328;
	int vol=255*255+255;
	ioctl(mixfd,fun, &vol);
	close(mixfd);
}