Mercurial > mplayer.hg
comparison libmpdemux/cdda.c @ 6384:f0b933918a22
Support for playing audio cds using cdparanoia. Include a raw audio
demuxer wich can be used for other purpose.
author | albeu |
---|---|
date | Tue, 11 Jun 2002 14:29:51 +0000 |
parents | |
children | 030e3fa9cf4a |
comparison
equal
deleted
inserted
replaced
6383:49f9e6b07687 | 6384:f0b933918a22 |
---|---|
1 #include "config.h" | |
2 | |
3 #ifdef HAVE_CDDA | |
4 | |
5 #include "stream.h" | |
6 #include "../cfgparser.h" | |
7 | |
8 #include <cdda_interface.h> | |
9 #include <cdda_paranoia.h> | |
10 | |
11 #include <stdio.h> | |
12 #include <stdlib.h> | |
13 | |
14 | |
15 static int speed = -1; | |
16 static int paranoia_mode = 1; | |
17 static char* generic_dev = NULL; | |
18 static int sector_size = 0; | |
19 static int search_overlap = -1; | |
20 static int toc_bias = 0; | |
21 static int toc_offset = 0; | |
22 static int no_skip = 0; | |
23 | |
24 static config_t cdda_opts[] = { | |
25 { "speed", &speed, CONF_TYPE_INT, CONF_RANGE,1,100, NULL }, | |
26 { "paranoia", ¶noia_mode, CONF_TYPE_INT,CONF_RANGE, 0, 2, NULL }, | |
27 { "generic-dev", &generic_dev, CONF_TYPE_STRING, 0, 0, 0, NULL }, | |
28 { "sector-size", §or_size, CONF_TYPE_INT, CONF_RANGE,1,100, NULL }, | |
29 { "overlap", &search_overlap, CONF_TYPE_INT, CONF_RANGE,0,75, NULL }, | |
30 { "toc-bias", &toc_bias, CONF_TYPE_INT, 0, 0, 0, NULL }, | |
31 { "toc-offset", &toc_offset, CONF_TYPE_INT, 0, 0, 0, NULL }, | |
32 { "noskip", &no_skip, CONF_TYPE_FLAG, 0 , 0, 1, NULL }, | |
33 { "skip", &no_skip, CONF_TYPE_FLAG, 0 , 1, 0, NULL }, | |
34 {NULL, NULL, 0, 0, 0, 0, NULL} | |
35 }; | |
36 | |
37 static config_t cdda_conf[] = { | |
38 { "cdda", &cdda_opts, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, | |
39 { NULL,NULL, 0, 0, 0, 0, NULL} | |
40 }; | |
41 | |
42 void cdda_register_options(m_config_t* cfg) { | |
43 m_config_register_options(cfg,cdda_conf); | |
44 } | |
45 | |
46 typedef struct { | |
47 cdrom_drive* cd; | |
48 cdrom_paranoia* cdp; | |
49 int sector; | |
50 int start_sector; | |
51 int end_sector; | |
52 } cdda_priv; | |
53 | |
54 stream_t* open_cdda(char* dev,char* track) { | |
55 stream_t* st; | |
56 int start_track = 0; | |
57 int end_track = 0; | |
58 int mode = paranoia_mode; | |
59 int offset = toc_offset; | |
60 cdrom_drive* cdd = NULL; | |
61 cdda_priv* priv; | |
62 char* end = strchr(track,'-'); | |
63 | |
64 if(!end) | |
65 start_track = end_track = atoi(track); | |
66 else { | |
67 int st_len = end - track; | |
68 int ed_len = strlen(track) - 1 - st_len; | |
69 | |
70 if(st_len) { | |
71 char st[st_len + 1]; | |
72 strncpy(st,track,st_len); | |
73 st[st_len] = '\0'; | |
74 start_track = atoi(st); | |
75 } | |
76 if(ed_len) { | |
77 char ed[ed_len + 1]; | |
78 strncpy(ed,end+1,ed_len); | |
79 ed[ed_len] = '\0'; | |
80 end_track = atoi(ed); | |
81 } | |
82 } | |
83 | |
84 if(generic_dev) | |
85 cdd = cdda_identify_scsi(generic_dev,dev,0,NULL); | |
86 else | |
87 cdd = cdda_identify(dev,0,NULL); | |
88 | |
89 if(!cdd) { | |
90 mp_msg(MSGT_OPEN,MSGL_ERR,"Can't open cdda device\n"); | |
91 return NULL; | |
92 } | |
93 | |
94 cdda_verbose_set(cdd, CDDA_MESSAGE_FORGETIT, CDDA_MESSAGE_FORGETIT); | |
95 | |
96 | |
97 if(sector_size) { | |
98 cdd->nsectors = sector_size; | |
99 cdd->bigbuff = sector_size * CD_FRAMESIZE_RAW; | |
100 } | |
101 | |
102 if(cdda_open(cdd) != 0) { | |
103 mp_msg(MSGT_OPEN,MSGL_ERR,"Can't open disc\n"); | |
104 cdda_close(cdd); | |
105 return NULL; | |
106 } | |
107 | |
108 priv = (cdda_priv*)malloc(sizeof(cdda_priv)); | |
109 priv->cd = cdd; | |
110 | |
111 if(toc_bias) | |
112 offset -= cdda_track_firstsector(cdd,1); | |
113 | |
114 if(offset) { | |
115 int i; | |
116 for(i = 0 ; i < cdd->tracks + 1 ; i++) | |
117 cdd->disc_toc[i].dwStartSector += offset; | |
118 } | |
119 | |
120 if(speed) | |
121 cdda_speed_set(cdd,speed); | |
122 | |
123 if(start_track) | |
124 priv->start_sector = cdda_track_firstsector(cdd,start_track); | |
125 else | |
126 priv->start_sector = cdda_disc_firstsector(cdd); | |
127 | |
128 if(end_track) { | |
129 int last = cdda_tracks(cdd); | |
130 if(end_track > last) end_track = last; | |
131 priv->end_sector = cdda_track_lastsector(cdd,end_track); | |
132 } else | |
133 priv->end_sector = cdda_disc_lastsector(cdd); | |
134 | |
135 priv->cdp = paranoia_init(cdd); | |
136 if(priv->cdp == NULL) { | |
137 cdda_close(cdd); | |
138 free(priv); | |
139 return NULL; | |
140 } | |
141 | |
142 if(mode == 0) | |
143 mode = PARANOIA_MODE_DISABLE; | |
144 else if(mode == 1) | |
145 mode = PARANOIA_MODE_OVERLAP; | |
146 else | |
147 mode = PARANOIA_MODE_FULL; | |
148 | |
149 if(no_skip) | |
150 mode |= PARANOIA_MODE_NEVERSKIP; | |
151 | |
152 if(search_overlap >= 0) | |
153 paranoia_overlapset(cdd,search_overlap); | |
154 | |
155 paranoia_seek(priv->cdp,priv->start_sector,SEEK_SET); | |
156 priv->sector = priv->start_sector; | |
157 | |
158 st = new_stream(-1,STREAMTYPE_CDDA); | |
159 st->priv = priv; | |
160 st->start_pos = priv->start_sector*CD_FRAMESIZE_RAW; | |
161 st->end_pos = priv->end_sector*CD_FRAMESIZE_RAW; | |
162 | |
163 return st; | |
164 } | |
165 | |
166 static void cdparanoia_callback(long inpos, int function) { | |
167 } | |
168 | |
169 int read_cdda(stream_t* s) { | |
170 cdda_priv* p = (cdda_priv*)s->priv; | |
171 int16_t * buf; | |
172 | |
173 buf = paranoia_read(p->cdp,cdparanoia_callback); | |
174 | |
175 p->sector++; | |
176 s->pos = p->sector*CD_FRAMESIZE_RAW; | |
177 memcpy(s->buffer,buf,CD_FRAMESIZE_RAW); | |
178 | |
179 if(p->sector == p->end_sector) | |
180 s->eof = 1; | |
181 | |
182 return CD_FRAMESIZE_RAW; | |
183 } | |
184 | |
185 void seek_cdda(stream_t* s) { | |
186 cdda_priv* p = (cdda_priv*)s->priv; | |
187 int sec = s->pos/CD_FRAMESIZE_RAW; | |
188 | |
189 if(sec < p->start_sector) | |
190 sec = p->start_sector; | |
191 else if(sec > p->end_sector) | |
192 sec = p->end_sector; | |
193 | |
194 p->sector = sec; | |
195 s->pos = sec*CD_FRAMESIZE_RAW; | |
196 | |
197 paranoia_seek(p->cdp,sec,SEEK_SET); | |
198 | |
199 } | |
200 | |
201 void close_cdda(stream_t* s) { | |
202 cdda_priv* p = (cdda_priv*)s->priv; | |
203 paranoia_free(p->cdp); | |
204 cdda_close(p->cd); | |
205 } | |
206 | |
207 #endif |