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,¤t)==-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,¤t)==-1){fprintf(stderr,"\nset vol errno:%d\n",errno);errno=0;close(ffd);return;}
69
70 sprintf(tail,"Volume: %d%%",(0xff¤t));
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¤t));
85 addStatusTail(tail,ph->outdetail);
86 }
87 else{ // Mute
88 if(ioctl(ffd,SNDCTL_DSP_GETPLAYVOL,¤t)==-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,¤t)==-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