1 /*
2  *  Copyright (C) 2009-2014  Christian Heckendorf <heckendorfc@gmail.com>
3  *
4  *  This program is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "ossutil.h"
19 #include "sndutil.h"
20 
snd_init(struct playerHandles * ph)21 int snd_init(struct playerHandles *ph){
22 	if((ph->sndfd=open(ph->device?ph->device:"/dev/dsp",O_WRONLY,777))==-1)return 1;
23 	return 0;
24 }
25 
snd_param_init(struct playerHandles * ph,int * enc,int * channels,unsigned int * rate)26 int snd_param_init(struct playerHandles *ph, int *enc, int *channels, unsigned int *rate){
27 	int oss_enc=AFMT_S16_NE;
28 	if(ioctl(ph->sndfd,SNDCTL_DSP_RESET,NULL)<0){
29 		fprintf(stderr,"reset errno:%d\n",errno);
30 		errno=0;
31 	}
32 	if(ioctl(ph->sndfd,SNDCTL_DSP_SETFMT,&oss_enc)<0){
33 		fprintf(stderr,"fmt errno:%d\n",errno);
34 		errno=0;
35 	}
36 	if(ioctl(ph->sndfd,SNDCTL_DSP_CHANNELS,channels)<0){
37 		fprintf(stderr,"ch errno:%d\n",errno);
38 		errno=0;
39 	}
40 	if(ioctl(ph->sndfd,SNDCTL_DSP_SPEED,rate)<0){
41 		fprintf(stderr,"rate errno:%d\n",errno);
42 		errno=0;
43 	}
44 	fprintf(stderr,"param ok");
45 	return 0;
46 }
47 
changeVolume(struct playerHandles * ph,int mod)48 void changeVolume(struct playerHandles *ph, int mod){
49 #ifdef OSSV4_DEFS
50 	int current;
51 	int ffd=ph->sndfd;
52 	char tail[OUTPUT_TAIL_SIZE];
53 
54 	if(ph->pflag->mute)
55 		current=ph->pflag->mute;
56 	else
57 		if(ioctl(ffd,SNDCTL_DSP_GETPLAYVOL,&current)==-1){fprintf(stderr,"\nget vol errno:%d\n",errno);errno=0;close(ffd);return;}
58 
59 	current+=mod<<8;
60 	current+=mod;
61 	if((current&0xff)>150)current=0; // Unsigned integer overloaded through 0
62 	if((current&0xff)>100)current=100+(100<<8);
63 	if(ph->pflag->mute){
64 		if(!(ph->pflag->mute=current))
65 			ph->pflag->mutec=32;
66 	}
67 	else
68 		if(ioctl(ffd,SNDCTL_DSP_SETPLAYVOL,&current)==-1){fprintf(stderr,"\nset vol errno:%d\n",errno);errno=0;close(ffd);return;}
69 
70 	sprintf(tail,"Volume: %d%%",(0xff&current));
71 	addStatusTail(tail,ph->outdetail);
72 #endif
73 }
74 
toggleMute(struct playerHandles * ph,int * mute)75 void toggleMute(struct playerHandles *ph, int *mute){
76 #ifdef OSSV4_DEFS
77 	int current;
78 	int ffd=ph->sndfd;
79 
80 	if(*mute>0){ // Unmute and perform volume change
81 		char tail[OUTPUT_TAIL_SIZE];
82 		current=*mute;
83 		*mute=0;
84 		sprintf(tail,"Volume: %d%%",(0xff&current));
85 		addStatusTail(tail,ph->outdetail);
86 	}
87 	else{ // Mute
88 		if(ioctl(ffd,SNDCTL_DSP_GETPLAYVOL,&current)==-1){fprintf(stderr,"\nget vol errno:%d\n",errno);errno=0;close(ffd);return;}
89 		*mute=current;
90 		current=0;
91 		addStatusTail("Volume Muted",ph->outdetail);
92 	}
93 	fflush(stdout);
94 
95 	if(ioctl(ffd,SNDCTL_DSP_SETPLAYVOL,&current)==-1){fprintf(stderr,"\nset vol errno:%d\n",errno);errno=0;close(ffd);return;}
96 #endif
97 }
98 
snd_clear(struct playerHandles * ph)99 void snd_clear(struct playerHandles *ph){
100 #ifdef OSSV4_DEFS
101 	ioctl(ph->sndfd,SNDCTL_DSP_SKIP,NULL);
102 #endif
103 }
104 
writei_snd(struct playerHandles * ph,const char * out,const unsigned int size)105 int writei_snd(struct playerHandles *ph, const char *out, const unsigned int size){
106 	int write_size;
107 	if(ph->pflag->pause){
108 #ifdef OSSV4_DEFS
109 		ioctl(ph->sndfd,SNDCTL_DSP_SILENCE,NULL);
110 #endif
111 		do{
112 			usleep(100000);
113 		}
114 		while(ph->pflag->pause);
115 #ifdef OSSV4_DEFS
116 		ioctl(ph->sndfd,SNDCTL_DSP_SKIP,NULL);
117 #endif
118 	}
119 	if(size==0){
120 		return 0;
121 	}
122 	if((write_size=write(ph->sndfd,out,size))!=size)
123 		fprintf(stderr,"Write error %d %d\n",size,write_size);
124 	return write_size;
125 }
126 
snd_close(struct playerHandles * ph)127 void snd_close(struct playerHandles *ph){
128 	close(ph->sndfd);
129 }
130