Hi
It seems that the interface to /dev/audio has changed, putting sample code like pcmplay.c out of date.

I have been trying to compile a new version of pcmplay, based on references found in posts by Tony and Kim, however I haven't quite got it right.

I have commented out the references to ioctl(fd, SNDCTL_DSP_SETFMT etc as these cause run time errors. I understand they are no longer required.

I ahve also included commands to turn off the soft audio mute and set the source to PCM.

I have created a PCM file, and am trying to play it using ./pcmplay < file.pcm

It seems to be doing something, as it is several seconds before the cursor comes back, however I get no sound

I have compiled beep.c (makes a beep using the DSP) and this works correctly, so I am cautiously confident with my new dev environment.

printf debugging shows that all the appropriate parts of the code are being reached, I'm simply getting no sound.

I'm alternating between hijack 200 and hijack 200 with the Kims sound overlay patch.


My source is below. If anyone can comment on what I am doing wrong I would really appreciate it.

When this is resolved, I'll send the source to Tony, so he can update the FAQ.

Cheers
Peter Kerr

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

#include <sys/ioctl.h>
#include <sys/soundcard.h>

#include <stdlib.h>


# define AUDIO_DEVICE "/dev/audio"
# define AUDIO_FILLSZ 4608

int iAudio;
int iMixer;
int iSource = SOUND_MASK_PCM;
int iFlags = 0; // source not muted
int iSAM = 0; // SAM is off
int iVolume = 100|(100 << 8);

static
int output(int fd, void const *buf, unsigned int len)
{
char const *ptr = buf;
int wrote;

while (len) {
wrote = write(fd, ptr, len);
if (wrote == -1) {
if (errno == EINTR)
continue;
else
return -1;
}

ptr += wrote;
len -= wrote;
}

return 0;
}

static
int audio_buffer(int fd, void const *buf, unsigned int len)
{
char const *ptr = buf;
static char hold[AUDIO_FILLSZ];
static unsigned int held;
unsigned int left, grab;

if (len == 0) {
if (held) {
memset(&hold[held], 0, &hold[AUDIO_FILLSZ] - &hold[held]);
held = 0;
return output(fd, hold, AUDIO_FILLSZ);
}

return 0;
}

if (held == 0 && len == AUDIO_FILLSZ)
return output(fd, ptr, len);

left = AUDIO_FILLSZ - held;

while (len) {
grab = len < left ? len : left;

memcpy(&hold[held], ptr, grab);
held += grab;
left -= grab;

ptr += grab;
len -= grab;

if (left == 0) {
if (output(fd, hold, AUDIO_FILLSZ) == -1)
return -1;

held = 0;
left = AUDIO_FILLSZ;
}
}

return 0;
}

# define audio_flush(fd) audio_buffer((fd), 0, 0)

static
int audio_init(int fd)
{
int format, stereo, speed;
//
// format = AFMT_S16_LE;
// if (ioctl(fd, SNDCTL_DSP_SETFMT, &format) == -1) {
// perror("ioctl(SNDCTL_DSP_SETFMT)");
// return -1;
// }
// if (format != AFMT_S16_LE) {
// fprintf(stderr, "AFMT_S16_LE not available
//");
// return -1;
// }

// stereo = 1;
// if (ioctl(fd, SNDCTL_DSP_STEREO, &stereo) == -1) {
// perror("ioctl(SNDCTL_DSP_STEREO)");
// return -1;
// }
// if (!stereo) {
// fprintf(stderr, "stereo selection failed");
// return -1;
// }

// speed = 44100;
// if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) == -1) {
// perror("ioctl(SNDCTL_DSP_SPEED)");
// return -1;
// }
// if (speed != 44100) {
// fprintf(stderr, "sample speed 44100 not available (closest %u)
//", speed);
// return -1;
// }

return 0;
}

int main(int argc, char *argv[])
{
static char buffer[AUDIO_FILLSZ];
int fd;
unsigned int len;

fd = open(AUDIO_DEVICE, O_WRONLY);
if (fd == -1) {
perror(AUDIO_DEVICE);
return 1;
}

if (audio_init(fd) == -1) {
close(fd);
return 2;
}
iMixer = open("/dev/mixer",O_RDONLY);
ioctl(iMixer,_IOW('m',0,int),&iSource); // set source
ioctl(iMixer,_IOW('m',1,int),&iFlags); // set Flags
ioctl(iMixer,_IOW('m',15,int),iSAM); // set Soft Audio Mute
ioctl(iMixer,MIXER_WRITE(SOUND_MIXER_VOLUME), &iVolume);

while ((len = fread(buffer, 4, AUDIO_FILLSZ / 4, stdin))) {
if (audio_buffer(fd, buffer, 4 * len) == -1) {
perror("write");
return 3;
}
}

if (ferror(stdin)) {
perror("read");
return 4;
}

if (audio_flush(fd) == -1) {
perror("write");
return 3;
}

if (close(fd) == -1) {
perror("close");
return 5;
}
close(iMixer);
printf("Done\n");
return 0;
}