annotate libao2/pl_volume.c @ 8534:922ce27eb683

This patch adds support for vertical subtitle alignment control. Possible values are top, center, and bottom, with bottom being the default. Alignment is relevant when it comes to positioning subtitles with one line (or fewer lines) of text relative to multi-line subtitles. It is implemented as a new command (sub_alignment) that without an argument cycles the alignment (between top, center, and bottom), or with an argument sets the alignment (0 for top, 1 for center, 2 for bottom). The key 'i' is bound to this command. patch by Oskar Liljeblad (oskar@osk.mine.nu)
author arpi
date Mon, 23 Dec 2002 01:37:43 +0000
parents be67d073f23b
children 46d21c0f36aa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4859
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
1 /* This audio output plugin changes the volume of the sound, and can
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
2 be used when the mixer doesn't support the PCM channel. The volume
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
3 is set in fixed steps between 0 - 2^8. */
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
4
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
5 #define PLUGIN
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
6
5063
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
7 // Some limits
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
8 #define MIN_S16 -32650
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
9 #define MAX_S16 32650
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
10 #define MIN_U8 0
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
11 #define MAX_U8 255
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
12 #define MIN_S8 -128
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
13 #define MAX_S8 127
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
14
4859
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
15 #include <stdio.h>
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
16 #include <stdlib.h>
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
17 #include <unistd.h>
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
18 #include <inttypes.h>
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
19
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
20 #include "audio_out.h"
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
21 #include "audio_plugin.h"
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
22 #include "audio_plugin_internal.h"
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
23 #include "afmt.h"
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
24
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
25 static ao_info_t info =
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
26 {
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
27 "Volume control audio plugin",
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
28 "volume",
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
29 "Anders",
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
30 ""
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
31 };
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
32
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
33 LIBAO_PLUGIN_EXTERN(volume)
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
34
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
35 // local data
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
36 typedef struct pl_volume_s
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
37 {
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
38 uint16_t volume; // output volume level
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
39 int inuse; // This plugin is in use TRUE, FALSE
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
40 int format; // sample fomat
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
41 } pl_volume_t;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
42
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
43 static pl_volume_t pl_volume={0,0,0};
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
44
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
45 // to set/get/query special features/parameters
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
46 static int control(int cmd,int arg){
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
47 switch(cmd){
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
48 case AOCONTROL_PLUGIN_SET_LEN:
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
49 return CONTROL_OK;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
50 case AOCONTROL_GET_VOLUME:{
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
51 if(pl_volume.inuse){
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
52 ((ao_control_vol_t *)arg)->right=((float)pl_volume.volume)/2.55;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
53 ((ao_control_vol_t *)arg)->left=((float)pl_volume.volume)/2.55;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
54 return CONTROL_OK;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
55 }
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
56 else
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
57 return CONTROL_ERROR;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
58 }
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
59 case AOCONTROL_SET_VOLUME:{
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
60 if(pl_volume.inuse){
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
61 // Calculate avarage between left and right
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
62 float vol =2.55*((((ao_control_vol_t *)arg)->right)+(((ao_control_vol_t *)arg)->left))/2;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
63 pl_volume.volume=(uint16_t)vol;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
64 // Volume must be between 0 and 255
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
65 if(vol > 255)
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
66 pl_volume.volume = 0xFF;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
67 if(vol < 0)
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
68 pl_volume.volume = 0;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
69 return CONTROL_OK;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
70 }
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
71 else
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
72 return CONTROL_ERROR;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
73 }
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
74 }
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
75 return CONTROL_UNKNOWN;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
76 }
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
77
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
78 // open & setup audio device
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
79 // return: 1=success 0=fail
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
80 static int init(){
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
81 // Sanity sheck this plugin supports AFMT_U8 and AFMT_S16_LE
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
82 switch(ao_plugin_data.format){
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
83 case(AFMT_U8):
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
84 case(AFMT_S16_LE):
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
85 break;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
86 default:
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
87 fprintf(stderr,"[pl_volume] Audio format not yet suported \n");
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
88 return 0;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
89 }
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
90 // Initialize volume to this value
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
91 pl_volume.volume=ao_plugin_cfg.pl_volume_volume;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
92 pl_volume.format=ao_plugin_data.format;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
93 /* The inuse flag is used in control to detremine if the return
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
94 value since that function always is called from ao_plugin regardless
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
95 of wether this plugin is in use or not. */
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
96 pl_volume.inuse=1;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
97 // Tell the world what we are up to
5063
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
98 printf("[pl_volume] Software volume control in use%s.\n",ao_plugin_cfg.pl_volume_softclip?", soft clipping enabled":"");
4859
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
99 return 1;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
100 }
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
101
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
102 // close plugin
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
103 static void uninit(){
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
104 pl_volume.inuse=0;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
105 }
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
106
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
107 // empty buffers
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
108 static void reset(){
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
109 }
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
110
5063
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
111 #define SIGN(x) (x>0?1:-1)
4859
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
112 // processes 'ao_plugin_data.len' bytes of 'data'
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
113 // called for every block of data
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
114 static int play(){
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
115 register int i=0;
5063
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
116 register int vol=pl_volume.volume; // Logarithmic control sounds more natural
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
117 vol=(vol*vol*vol)>>12;
4859
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
118 // Change the volume.
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
119 switch(pl_volume.format){
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
120 case(AFMT_U8):{
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
121 register uint8_t* data=(uint8_t*)ao_plugin_data.data;
5063
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
122 register int x;
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
123 for(i=0;i<ao_plugin_data.len;i++){
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
124 x=((data[i]-128) * vol) >> 8;
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
125 if(x>MAX_S8)
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
126 data[i]=MAX_U8;
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
127 else if(x<MIN_S8)
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
128 data[i]=MIN_U8;
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
129 else{
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
130 if(ao_plugin_cfg.pl_volume_softclip)
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
131 data[i] = ((3*x - ((x*x*x) >> 14)) >> 1) + 128;
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
132 else
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
133 data[i] = x + 128;
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
134 }
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
135 }
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
136 break;
4859
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
137 }
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
138 case(AFMT_S16_LE):{
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
139 register int len=ao_plugin_data.len>>1;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
140 register int16_t* data=(int16_t*)ao_plugin_data.data;
5063
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
141 register int x;
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
142 for(i=0;i<len;i++){
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
143 x=(data[i] * vol) >> 8;
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
144 if(x>MAX_S16)
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
145 data[i]=MAX_S16;
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
146 else if(x<MIN_S16)
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
147 data[i]=MIN_S16;
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
148 else{
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
149 if(ao_plugin_cfg.pl_volume_softclip){
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
150 int64_t t=x*x;
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
151 t=(t*x) >> 30;
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
152 data[i] = (3*x - (int)t) >> 1;
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
153 //data[i] = 2*x - SIGN(x)*((x*x)>>15);
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
154 }
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
155 else
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
156 data[i] = x;
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
157 }
be67d073f23b Added soft clipping for software volume control
anders
parents: 4859
diff changeset
158 }
4859
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
159 break;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
160 }
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
161 default:
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
162 return 0;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
163 }
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
164 return 1;
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
165
c72b386debb4 Adding SW volume control
anders
parents:
diff changeset
166 }