digitalmars.D.learn - ioctl to set mixer volume
- Alain De Vos (13/13) Apr 16 2021 The following very simple low level C-function simply sets the
- Adam D. Ruppe (14/16) Apr 16 2021 ```
- Dennis (28/42) Apr 16 2021 You could change `sizeof(int)` to `int.sizeof` and `(unsigned
- Alain De Vos (26/26) Apr 16 2021 I had to copy over a downloaded ioctl.d to the directory
- Alain De Vos (19/19) Apr 16 2021 I tried :
- Alain De Vos (20/20) Apr 16 2021 After some fiddling i finally got it.
- Boris Carvajal (4/24) Apr 16 2021 Here you could avoid C stdio and just use posix functions like
- Alain De Vos (19/19) Apr 16 2021 Correct, then i have :
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
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
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
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
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
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
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
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









Adam D. Ruppe <destructionator gmail.com> 