/*
Copyright (c) 2007-2013, John Ryland
*/
#include <oslayer.h>
#include <corelayer.h>
#include <soundcard.h>
#include <sound.h>
const char *formatTable[] = {
"AFMT_MU_LAW",
"AFMT_A_LAW",
"AFMT_IMA_ADPCM",
"AFMT_U8", /* unsigned 8 */
"AFMT_S16_LE", /* Little endian signed 16*/
"AFMT_S16_BE", /* Big endian signed 16 */
"AFMT_S8", /* signed 8 */
"AFMT_U16_LE", /* Little endian U16 */
"AFMT_U16_BE", /* Big endian U16 */
"AFMT_MPEG", /* MPEG (2) audio */
"AFMT_AC3" /* Dolby Digital AC3 */
};
void printAudioFormatMask(int format, const char *sep)
{
int i = 0;
int first = 0;
while (format) {
if (format & 0x01) {
if (first)
strPrint(sep);
strPrint(formatTable[i]);
first = 1;
}
i++;
format >>= 1;
}
}
const char *levelNames[] = SOUND_DEVICE_LABELS;
#undef MIXER_WRITE
#define MIXER_WRITE(d) _IOW('M', d, int)
void setVolume(int arg)
{
int mixerFd = fsOpen("/dev/sound/mixer", O_RDWR);
int mute = 0;
int mask = 0;
int vol, i;
int buf[256];
mixer_vol_table tab;
mixer_info info;
_old_mixer_info old_info;
/*
if (sysIoctl(mixerFd, SOUND_MIXER_WRITE_MUTE, &mute))
strPrint("error in call mute\n");
if (sysIoctl(mixerFd, MIXER_READ(SOUND_MIXER_OUTMASK), &mask))
strPrint("error in call MIXER_READ(SOUND_MIXER_OUTMASK)\n");
strPrintf("got MIXER_READ(SOUND_MIXER_OUTMASK) = %x\n", mask);
if (sysIoctl(mixerFd, MIXER_WRITE(SOUND_MIXER_OUTSRC), &mask))
strPrint("error in call MIXER_WRITE(SOUND_MIXER_OUTSRC)\n");
*/
/*
success: _IOC(0, T, 33, 0)
success: _IOC(0, T, 80, 0)
success: _IOC(0, T, 81, 0)
success: _IOC(0, T, 82, 0)
success: _IOW(M, 9, 4) // SOUND_MIXER_WRITE_IMIX
success: _IOW(M, 11, 4) // SOUND_MIXER_WRITE_RECLEV
success: _IOW(M, 13, 4) // SOUND_MIXER_WRITE_OGAIN
success: _IOR(M, 6, 4) // SOUND_MIXER_READ_LINE
success: _IOR(M, 8, 4) // SOUND_MIXER_READ_CD
success: _IOR(M, 10, 4) // SOUND_MIXER_READ_ALTPCM
success: _IOR(M, 12, 4) // SOUND_MIXER_READ_IGAIN
success: _IOR(M, 14, 4) // SOUND_MIXER_READ_LINE1
success: _IOR(M, 101, 48) // SOUND_OLD_MIXER_INFO
success: _IOR(M, 101, 92) // SOUND_MIXER_INFO
success: _IOR(M, 118, 4) // OSS_GETVERSION
success: _IORW(M, 116, 164) // SOUND_MIXER_GETLEVELS
success: _IORW(M, 117, 164) // SOUND_MIXER_SETLEVELS
char id[16];
char name[32];
int modify_counter;
int fillers[10];
*/
/*
if (sysIoctl(mixerFd, SOUND_MIXER_GETLEVELS, &tab))
strPrint("error in call X\n");
strPrintf("audio: name: %s num: %i\n", tab.name, -tab.num);
for (i = 0; i < 32; i++) {
strPrintf("level[%i]: %x\n", i, tab.levels[i]);
tab.levels[i] = arg;
}
fsClose(mixerFd);
mixerFd = fsOpen("/dev/sound/mixer", O_RDWR);
if (sysIoctl(mixerFd, SOUND_MIXER_SETLEVELS, &tab))
strPrint("error in call Y\n");
// if (sysIoctl(mixerFd, _IO('T', 33), 0))
// strPrint("error in call 1\n");
if (sysIoctl(mixerFd, _IO('T', 80), 0))
strPrint("error in call 2\n");
if (sysIoctl(mixerFd, _IO('T', 81), 0))
strPrint("error in call 3\n");
// if (sysIoctl(mixerFd, _IO('T', 82), 0))
// strPrint("error in call 4\n");
*/
vol = arg;
if (sysIoctl(mixerFd, _IOW('M', 5, 4), &vol)) // SOUND_MIXER_SPEAKER
strPrint("error in call vA--\n");
vol = arg;
if (sysIoctl(mixerFd, _IOW('M', 7, 4), &vol)) // SOUND_MIXER_MIC
strPrint("error in call vA--\n");
vol = arg;//(90 << 8) | 90;
if (sysIoctl(mixerFd, SOUND_MIXER_WRITE_IMIX, &vol))
strPrint("error in call vB\n");
vol = arg;
if (sysIoctl(mixerFd, SOUND_MIXER_WRITE_RECLEV, &vol))
strPrint("error in call vA--\n");
vol = arg;//(90 << 8) | 90;
if (sysIoctl(mixerFd, SOUND_MIXER_WRITE_OGAIN, &vol))
strPrint("error in call vB\n");
vol = (90 << 8) | 90;
if (sysIoctl(mixerFd, SOUND_MIXER_READ_LINE, &vol))
strPrint("error in call vB\n");
strPrintf("line vol: %i\n", i);
vol = (90 << 8) | 90;
if (sysIoctl(mixerFd, SOUND_MIXER_READ_CD, &vol))
strPrint("error in call vB\n");
strPrintf("cd vol: %i\n", i);
vol = (90 << 8) | 90;
if (sysIoctl(mixerFd, SOUND_MIXER_READ_ALTPCM, &vol))
strPrint("error in call vB\n");
strPrintf("altpcm vol: %i\n", i);
vol = (90 << 8) | 90;
if (sysIoctl(mixerFd, SOUND_MIXER_READ_IGAIN, &vol))
strPrint("error in call vB\n");
strPrintf("igain vol: %i\n", i);
vol = (90 << 8) | 90;
if (sysIoctl(mixerFd, SOUND_MIXER_READ_LINE1, &vol))
strPrint("error in call vB\n");
strPrintf("line1 vol: %i\n", i);
fsClose(mixerFd);
}
int openSound()
{
#if defined(ARCH_ARM)
int audioFd = fsOpen("/dev/sound/dsp1", O_RDWR);
#else
int audioFd = fsOpen("/dev/dsp", O_RDWR);
#endif
int format = AFMT_S16_LE, stereo = 1, speed = 8000;//48000;//11025;
int frags = 0x0002000A, mask;
int ver = 1;
//setVolume(32);
// int pm = fsOpen("/dev/pm", O_RDWR);
// int lcdFd = fsOpen("/dev/fb0", O_RDWR);
// sysIoctl(pm, SNDCTL_DSP_SETFRAGMENT, 0);
// sysIoctl(lcdFd, 0x4d0d, 0);
// fsClose(lcdFd);
// lcdFd = fsOpen("/dev/fb0", O_RDWR);
// sysIoctl(lcdFd, 0x4d21, 0);
// fsClose(pm);
// fsClose(lcdFd);
if (sysIoctl(audioFd, OSS_GETVERSION, &ver))
strPrint("OSS_GETVERSION error in call\n");
if (sysIoctl(audioFd, SNDCTL_DSP_SETFRAGMENT, &frags))
strPrint("SNDCTL_DSP_SETFFRAGMENT error in call\n");
if (sysIoctl(audioFd, SNDCTL_DSP_SETFMT, &format) == -1)
strPrint("SNDCTL_DSP_SETFMT error in call\n");
if (format != AFMT_S16_LE)
strPrint("SNDCTL_DSP_SETFMT error, format not supported\n");
if (sysIoctl(audioFd, SNDCTL_DSP_GETFMTS, &mask) != -1) {
strPrint("Supported audio formats: ");
printAudioFormatMask(mask, ", ");
strPrint("\n");
}
if (sysIoctl(audioFd, SNDCTL_DSP_STEREO, &stereo) == -1)
strPrint("SNDCTL_DSP_STEREO error in call\n");
if (sysIoctl(audioFd, SNDCTL_DSP_SPEED, &speed) == -1)
strPrint("SNDCTL_DSP_SPEED error in call\n");
// strPrint("Sound parameters are: ");
// printAudioFormatMask(format, "|");
strPrintf("Sound parameters:\n OSS-Version: %x\n %s %iHz\n", ver, stereo ? "stereo" : "mono", speed);
return audioFd;
}
void closeSound(int audioFd)
{
fsClose(audioFd);
}
Sound openSoundFile(const char *mapableSound)
{
stat sbuf;
Sound sound;
sound.fd = fsOpen(mapableSound, O_RDONLY);
fsStat(mapableSound, &sbuf);
sound.data = (unsigned char *)fsMmap(0, sbuf.st_size, PROT_READ, MAP_PRIVATE, sound.fd, 0);
sound.size = sbuf.st_size;
return sound;
}
void closeSoundFile(Sound sound)
{
fsClose(sound.fd);
}
void playSound(int sd, Sound *sound)
{
unsigned char blank[1024];
int i;
fsWrite(sd, sound->data, sound->size);
for (i = 0; i < 1024; i++)
blank[i] = 0;
fsWrite(sd, blank, sound->size % 1024); // Close off a fragment
// sysIoctl(sd, SNDCTL_DSP_POST, 0);
// sysIoctl(sd, SNDCTL_DSP_SYNC, 0);
}
void playSoundFile(int sd, const char *mapableSound)
{
stat sbuf;
unsigned char *ch;
unsigned char blank[1024];
int i, fd = fsOpen(mapableSound, O_RDONLY);
fsStat(mapableSound, &sbuf);
ch = (unsigned char *)fsMmap(0, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
fsWrite(sd, ch, sbuf.st_size);
// sysIoctl(sd, SNDCTL_DSP_POST, 0);
// sysIoctl(sd, SNDCTL_DSP_SYNC, 0);
for (i = 0; i < 1024; i++)
blank[i] = 0;
fsWrite(sd, blank, sbuf.st_size % 1024); // Close off a fragment
fsClose(fd);
}