www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - ioctl to set mixer volume

reply Alain De Vos <devosalain ymail.com> writes:
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);
}
```
Apr 16 2021
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
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
Apr 16 2021
prev sibling parent reply Dennis <dkorpel gmail.com> writes:
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: ```C 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: ```D 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); } ```
Apr 16 2021
parent reply Alain De Vos <devosalain ymail.com> writes:
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);
}
```
Apr 16 2021
parent reply Alain De Vos <devosalain ymail.com> writes:
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 ....
Apr 16 2021
parent reply Alain De Vos <devosalain ymail.com> writes:
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".
Apr 16 2021
parent reply Boris Carvajal <boris2.9 gmail.com> writes:
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.
Apr 16 2021
parent Alain De Vos <devosalain ymail.com> writes:
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);
}

```
Apr 16 2021