Credit Andrew - improve in-tree documentation
[goodguy/cinelerra.git] / cinelerra / channel.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "channel.h"
23 #include "bchash.h"
24 #include "filexml.h"
25 #include <string.h>
26
27 // Channel table entry for the TV tuner
28
29 Channel::Channel()
30 {
31         reset();
32 }
33
34 Channel::Channel(Channel *channel)
35 {
36         copy_settings(channel);
37         copy_usage(channel);
38 }
39
40 Channel::~Channel()
41 {
42 }
43
44
45 void Channel::reset()
46 {
47 // GUI options
48         use_frequency = 0;
49         use_fine = 0;
50         use_norm = 0;
51         use_input = 0;
52
53         title[0] = 0;
54         device_name[0] = 0;
55         entry = 0;
56         element = 0;
57         freqtable = 0;
58         fine_tune = 0;
59         input = 0;
60         norm = 0;
61         device_index = 0;
62         tuner = 0;
63         has_scanning = 0;
64         has_subchan = 0;
65
66         audio_stream = 0;
67         video_stream = 0;
68         audio_pid = 0x14;
69         video_pid = 0x11;
70 }
71
72 void Channel::dump()
73 {
74         printf("Channel::dump title=%s\n"
75                 "device_name=%s\n"
76                 "use_freq=%d\n"
77                 "use_fine=%d\n"
78                 "use_norm=%d\n"
79                 "use_input=%d\n"
80                 "has_scanning=%d\n"
81                 "has_subchan=%d\n",
82                 title,
83                 device_name,
84                 use_frequency,
85                 use_fine,
86                 use_norm,
87                 use_input,
88                 has_scanning,
89                 has_subchan);
90 }
91
92 Channel& Channel::operator=(Channel &channel)
93 {
94         printf("Channel::operator= is not supported.\n");
95         return *this;
96 }
97
98 bool Channel::operator==(Channel &channel)
99 {
100         if( this == &channel ) return true;
101         return  this->entry != channel.entry ||
102                 this->element != channel.element ||
103                 this->freqtable != channel.freqtable ||
104                 this->fine_tune != channel.fine_tune ||
105                 this->input != channel.input ||
106                 this->norm != channel.norm ||
107                 this->device_index != channel.device_index ||
108                 this->tuner != channel.tuner ||
109                 this->audio_stream != channel.audio_stream ||
110                 this->video_stream != channel.video_stream ||
111                 this->audio_pid != channel.audio_pid ||
112                 this->video_pid != channel.video_pid ? false : true;
113 }
114
115 bool Channel::operator!=(Channel &channel)
116 {
117         return *this == channel ? false : true;
118 }
119
120 void Channel::copy_settings(Channel *channel)
121 {
122         strcpy(this->title, channel->title);
123         this->entry = channel->entry;
124         this->element = channel->element;
125         this->freqtable = channel->freqtable;
126         this->fine_tune = channel->fine_tune;
127         this->input = channel->input;
128         this->norm = channel->norm;
129         this->device_index = channel->device_index;
130         this->tuner = channel->tuner;
131         this->audio_stream = channel->audio_stream;
132         this->video_stream = channel->video_stream;
133         this->audio_pid = channel->audio_pid;
134         this->video_pid = channel->video_pid;
135 }
136
137 void Channel::copy_usage(Channel *channel)
138 {
139         this->use_frequency = channel->use_frequency;
140         this->use_fine = channel->use_fine;
141         this->use_norm = channel->use_norm;
142         this->use_input = channel->use_input;
143         this->has_scanning = channel->has_scanning;
144         this->has_subchan = channel->has_subchan;
145 }
146
147 int Channel::load(FileXML *file)
148 {
149         int done = 0;
150         char *text;
151
152
153         while(!done)
154         {
155                 done = file->read_tag();
156                 if(!done)
157                 {
158                         if(file->tag.title_is("CHANNEL"))
159                         {
160                                 entry = file->tag.get_property("ENTRY", entry);
161                                 element = file->tag.get_property("ELEMENT", element);
162                                 freqtable = file->tag.get_property("FREQTABLE", freqtable);
163                                 fine_tune = file->tag.get_property("FINE_TUNE", fine_tune);
164                                 input = file->tag.get_property("INPUT", input);
165                                 norm = file->tag.get_property("NORM", norm);
166                                 device_index = file->tag.get_property("DEVICE_INDEX", device_index);
167                                 tuner = file->tag.get_property("TUNER", tuner);
168                                 audio_stream = file->tag.get_property("AUDIO_STREAM", audio_pid);
169                                 video_stream = file->tag.get_property("VIDEO_STREAM", video_pid);
170                                 audio_pid = file->tag.get_property("AUDIO_PID", audio_pid);
171                                 video_pid = file->tag.get_property("VIDEO_PID", video_pid);
172                                 text = file->read_text();
173                                 strcpy(title, text);
174                         }
175                         else
176                         if(file->tag.title_is("/CHANNEL"))
177                                 return 0;
178                 }
179         }
180         return done;
181 }
182
183 void Channel::save(FileXML *file)
184 {
185         file->tag.set_title("CHANNEL");
186         file->tag.set_property("ENTRY", entry);
187         file->tag.set_property("ELEMENT", element);
188         file->tag.set_property("FREQTABLE", freqtable);
189         file->tag.set_property("FINE_TUNE", fine_tune);
190         file->tag.set_property("INPUT", input);
191         file->tag.set_property("NORM", norm);
192         file->tag.set_property("DEVICE_INDEX", device_index);
193         file->tag.set_property("TUNER", tuner);
194         file->tag.set_property("AUDIO_STREAM", audio_stream);
195         file->tag.set_property("VIDEO_STREAM", video_stream);
196         file->tag.set_property("AUDIO_PID", audio_pid);
197         file->tag.set_property("VIDEO_PID", video_pid);
198         file->append_tag();
199         file->append_text(title);
200         file->tag.set_title("/CHANNEL");
201         file->append_tag();
202         file->append_newline();
203 }
204
205
206
207 void Channel::load_defaults(BC_Hash *defaults)
208 {
209         freqtable = defaults->get("SCAN_FREQTABLE", freqtable);
210         input = defaults->get("SCAN_INPUT", input);
211         norm = defaults->get("SCAN_NORM", norm);
212 }
213
214 void Channel::save_defaults(BC_Hash *defaults)
215 {
216         defaults->update("SCAN_FREQTABLE", freqtable);
217         defaults->update("SCAN_INPUT", input);
218         defaults->update("SCAN_NORM", norm);
219 }
220
221 static inline bool is_numeric(char c) { return (c>='0' && c<='9'); }
222 static inline bool is_separator(char c) { return (c=='.' || c=='-'); }
223
224 static inline void get_chan(const char *p, int &ch, int &sub)
225 {
226         while( *p == ' ' ) ++p;
227         for( ch=0,sub=1; is_numeric(*p); ++p ) ch = ch*10 + *p-'0';
228         if( !*p || !is_separator(*p) || !is_numeric(*++p) ) return;
229         for( sub=*p-'0'; is_numeric(*++p); ) sub = sub*10 + *p-'0';
230 }
231
232 int Channel::cstrcmp(const char *name)
233 {
234         if( !strcmp(name, title) ) return 0;
235         int ch1, sub1;  get_chan(name, ch1, sub1);
236         int ch2, sub2;  get_chan(title, ch2, sub2);
237         int ret = ch1 - ch2;
238         if( !ret ) ret = sub1 - sub2;
239         return ret;
240 }
241