OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef MEDIA_MIDI_MIDI_MANAGER_ALSA_H_ | 5 #ifndef MEDIA_MIDI_MIDI_MANAGER_ALSA_H_ |
6 #define MEDIA_MIDI_MIDI_MANAGER_ALSA_H_ | 6 #define MEDIA_MIDI_MIDI_MANAGER_ALSA_H_ |
7 | 7 |
8 #include <alsa/asoundlib.h> | 8 #include <alsa/asoundlib.h> |
9 #include <map> | 9 #include <map> |
10 #include <vector> | 10 #include <vector> |
(...skipping 23 matching lines...) Expand all Loading... |
34 void DispatchSendMidiData(MidiManagerClient* client, | 34 void DispatchSendMidiData(MidiManagerClient* client, |
35 uint32 port_index, | 35 uint32 port_index, |
36 const std::vector<uint8>& data, | 36 const std::vector<uint8>& data, |
37 double timestamp) override; | 37 double timestamp) override; |
38 | 38 |
39 private: | 39 private: |
40 friend class MidiManagerAlsaTest; | 40 friend class MidiManagerAlsaTest; |
41 FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, ExtractManufacturer); | 41 FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, ExtractManufacturer); |
42 FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, ToMidiPortState); | 42 FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, ToMidiPortState); |
43 | 43 |
| 44 class AlsaCard; |
| 45 typedef std::map<int, AlsaCard*> AlsaCardMap; |
| 46 |
44 class MidiPort { | 47 class MidiPort { |
45 public: | 48 public: |
46 enum class Type { kInput, kOutput }; | 49 enum class Type { kInput, kOutput }; |
47 | 50 |
48 MidiPort(const std::string& path, | 51 MidiPort(const std::string& path, |
49 const std::string& id, | 52 const std::string& id, |
50 int client_id, | 53 int client_id, |
51 int port_id, | 54 int port_id, |
52 int midi_device, | 55 int midi_device, |
53 const std::string& client_name, | 56 const std::string& client_name, |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 snd_seq_client_type_t type); | 206 snd_seq_client_type_t type); |
204 bool ClientStarted(int client_id); | 207 bool ClientStarted(int client_id); |
205 void ClientExit(int client_id); | 208 void ClientExit(int client_id); |
206 void PortStart(int client_id, | 209 void PortStart(int client_id, |
207 int port_id, | 210 int port_id, |
208 const std::string& port_name, | 211 const std::string& port_name, |
209 PortDirection direction, | 212 PortDirection direction, |
210 bool midi); | 213 bool midi); |
211 void PortExit(int client_id, int port_id); | 214 void PortExit(int client_id, int port_id); |
212 snd_seq_client_type_t ClientType(int client_id) const; | 215 snd_seq_client_type_t ClientType(int client_id) const; |
213 scoped_ptr<TemporaryMidiPortState> ToMidiPortState(); | 216 scoped_ptr<TemporaryMidiPortState> ToMidiPortState( |
| 217 const AlsaCardMap& alsa_cards); |
| 218 |
| 219 int kernel_client_count() { return kernel_client_count_; } |
214 | 220 |
215 private: | 221 private: |
216 class Port { | 222 class Port { |
217 public: | 223 public: |
218 Port(const std::string& name, PortDirection direction, bool midi); | 224 Port(const std::string& name, PortDirection direction, bool midi); |
219 ~Port(); | 225 ~Port(); |
220 | 226 |
221 std::string name() const; | 227 std::string name() const; |
222 PortDirection direction() const; | 228 PortDirection direction() const; |
223 // True if this port is a MIDI port, instead of another kind of ALSA port. | 229 // True if this port is a MIDI port, instead of another kind of ALSA port. |
(...skipping 28 matching lines...) Expand all Loading... |
252 STLValueDeleter<PortMap> ports_deleter_; | 258 STLValueDeleter<PortMap> ports_deleter_; |
253 | 259 |
254 DISALLOW_COPY_AND_ASSIGN(Client); | 260 DISALLOW_COPY_AND_ASSIGN(Client); |
255 }; | 261 }; |
256 | 262 |
257 typedef std::map<int, Client*> ClientMap; | 263 typedef std::map<int, Client*> ClientMap; |
258 | 264 |
259 ClientMap clients_; | 265 ClientMap clients_; |
260 STLValueDeleter<ClientMap> clients_deleter_; | 266 STLValueDeleter<ClientMap> clients_deleter_; |
261 | 267 |
| 268 int kernel_client_count_; |
| 269 |
262 DISALLOW_COPY_AND_ASSIGN(AlsaSeqState); | 270 DISALLOW_COPY_AND_ASSIGN(AlsaSeqState); |
263 }; | 271 }; |
264 | 272 |
| 273 class AlsaCard { |
| 274 public: |
| 275 AlsaCard(udev_device* dev, |
| 276 const std::string& alsa_name, |
| 277 const std::string& alsa_longname, |
| 278 const std::string& alsa_driver, |
| 279 int midi_device_count); |
| 280 ~AlsaCard(); |
| 281 const std::string alsa_name() const { return alsa_name_; } |
| 282 const std::string alsa_longname() const { return alsa_longname_; } |
| 283 const std::string manufacturer() const { return manufacturer_; } |
| 284 const std::string alsa_driver() const { return alsa_driver_; } |
| 285 int midi_device_count() const { return midi_device_count_; } |
| 286 // Returns hardware path. |
| 287 const std::string path() const; |
| 288 // Returns the id we can use to try to match hardware across different |
| 289 // paths. |
| 290 const std::string id() const; |
| 291 |
| 292 private: |
| 293 FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, ExtractManufacturer); |
| 294 |
| 295 // Extracts the manufacturer using heuristics and a variety of sources. |
| 296 static std::string ExtractManufacturerString( |
| 297 const std::string& udev_id_vendor, |
| 298 const std::string& udev_id_vendor_id, |
| 299 const std::string& udev_id_vendor_from_database, |
| 300 const std::string& alsa_name, |
| 301 const std::string& alsa_longname); |
| 302 |
| 303 std::string alsa_name_; |
| 304 std::string alsa_longname_; |
| 305 std::string manufacturer_; |
| 306 std::string alsa_driver_; |
| 307 std::string path_; |
| 308 std::string bus_; |
| 309 std::string serial_; |
| 310 std::string vendor_id_; |
| 311 std::string model_id_; |
| 312 std::string usb_interface_num_; |
| 313 int midi_device_count_; |
| 314 |
| 315 DISALLOW_COPY_AND_ASSIGN(AlsaCard); |
| 316 }; |
| 317 |
265 typedef base::hash_map<int, uint32> SourceMap; | 318 typedef base::hash_map<int, uint32> SourceMap; |
266 typedef base::hash_map<uint32, int> OutPortMap; | 319 typedef base::hash_map<uint32, int> OutPortMap; |
267 | 320 |
268 // Extracts the manufacturer using heuristics and a variety of sources. | |
269 static std::string ExtractManufacturerString( | |
270 const std::string& udev_id_vendor, | |
271 const std::string& udev_id_vendor_id, | |
272 const std::string& udev_id_vendor_from_database, | |
273 const std::string& alsa_name, | |
274 const std::string& alsa_longname); | |
275 | |
276 // An internal callback that runs on MidiSendThread. | 321 // An internal callback that runs on MidiSendThread. |
277 void SendMidiData(uint32 port_index, const std::vector<uint8>& data); | 322 void SendMidiData(uint32 port_index, const std::vector<uint8>& data); |
278 | 323 |
279 void ScheduleEventLoop(); | 324 void ScheduleEventLoop(); |
280 void EventLoop(); | 325 void EventLoop(); |
281 void ProcessSingleEvent(snd_seq_event_t* event, double timestamp); | 326 void ProcessSingleEvent(snd_seq_event_t* event, double timestamp); |
282 void ProcessClientStartEvent(int client_id); | 327 void ProcessClientStartEvent(int client_id); |
283 void ProcessPortStartEvent(const snd_seq_addr_t& addr); | 328 void ProcessPortStartEvent(const snd_seq_addr_t& addr); |
284 void ProcessClientExitEvent(const snd_seq_addr_t& addr); | 329 void ProcessClientExitEvent(const snd_seq_addr_t& addr); |
285 void ProcessPortExitEvent(const snd_seq_addr_t& addr); | 330 void ProcessPortExitEvent(const snd_seq_addr_t& addr); |
286 void ProcessUdevEvent(udev_device* dev); | 331 void ProcessUdevEvent(udev_device* dev); |
| 332 void AddCard(udev_device* dev); |
| 333 void RemoveCard(int number); |
287 | 334 |
288 // Updates port_state_ and Web MIDI state from alsa_seq_state_. | 335 // Updates port_state_ and Web MIDI state from alsa_seq_state_. |
289 void UpdatePortStateAndGenerateEvents(); | 336 void UpdatePortStateAndGenerateEvents(); |
290 | 337 |
291 // Enumerates ports. Call once after subscribing to the announce port. | 338 // Enumerates ports. Call once after subscribing to the announce port. |
292 void EnumerateAlsaPorts(); | 339 void EnumerateAlsaPorts(); |
293 // Enumerates udev cards. Call once after initializing the udev monitor. | 340 // Enumerates udev cards. Call once after initializing the udev monitor. |
294 bool EnumerateUdevCards(); | 341 bool EnumerateUdevCards(); |
295 // Returns true if successful. | 342 // Returns true if successful. |
296 bool CreateAlsaOutputPort(uint32 port_index, int client_id, int port_id); | 343 bool CreateAlsaOutputPort(uint32 port_index, int client_id, int port_id); |
(...skipping 11 matching lines...) Expand all Loading... |
308 int out_client_id_; | 355 int out_client_id_; |
309 | 356 |
310 // One input port, many output ports. | 357 // One input port, many output ports. |
311 int in_port_id_; | 358 int in_port_id_; |
312 OutPortMap out_ports_; // guarded by out_ports_lock_ | 359 OutPortMap out_ports_; // guarded by out_ports_lock_ |
313 base::Lock out_ports_lock_; // guards out_ports_ | 360 base::Lock out_ports_lock_; // guards out_ports_ |
314 | 361 |
315 // Mapping from ALSA client:port to our index. | 362 // Mapping from ALSA client:port to our index. |
316 SourceMap source_map_; | 363 SourceMap source_map_; |
317 | 364 |
| 365 // Mapping from card to devices. |
| 366 AlsaCardMap alsa_cards_; |
| 367 STLValueDeleter<AlsaCardMap> alsa_cards_deleter_; |
| 368 int alsa_card_midi_count_; |
| 369 |
318 // ALSA event -> MIDI coder. | 370 // ALSA event -> MIDI coder. |
319 snd_midi_event_t* decoder_; | 371 snd_midi_event_t* decoder_; |
320 | 372 |
321 // udev, for querying hardware devices. | 373 // udev, for querying hardware devices. |
322 device::ScopedUdevPtr udev_; | 374 device::ScopedUdevPtr udev_; |
323 device::ScopedUdevMonitorPtr udev_monitor_; | 375 device::ScopedUdevMonitorPtr udev_monitor_; |
324 | 376 |
325 base::Thread send_thread_; | 377 base::Thread send_thread_; |
326 base::Thread event_thread_; | 378 base::Thread event_thread_; |
327 | 379 |
328 bool event_thread_shutdown_; // guarded by shutdown_lock_ | 380 bool event_thread_shutdown_; // guarded by shutdown_lock_ |
329 base::Lock shutdown_lock_; // guards event_thread_shutdown_ | 381 base::Lock shutdown_lock_; // guards event_thread_shutdown_ |
330 | 382 |
331 DISALLOW_COPY_AND_ASSIGN(MidiManagerAlsa); | 383 DISALLOW_COPY_AND_ASSIGN(MidiManagerAlsa); |
332 }; | 384 }; |
333 | 385 |
334 } // namespace midi | 386 } // namespace midi |
335 } // namespace media | 387 } // namespace media |
336 | 388 |
337 #endif // MEDIA_MIDI_MIDI_MANAGER_ALSA_H_ | 389 #endif // MEDIA_MIDI_MIDI_MANAGER_ALSA_H_ |
OLD | NEW |