blob: d06ff760c0483cf0bd4b6e075ed346cd5deba350 [file] [log] [blame]
toyoshim@chromium.orga97eebf2014-01-03 07:52:39 +00001// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
dnicoara@chromium.org9f2a6f02014-01-03 21:25:00 +00005#ifndef MEDIA_MIDI_MIDI_MANAGER_ALSA_H_
6#define MEDIA_MIDI_MIDI_MANAGER_ALSA_H_
toyoshim@chromium.orga97eebf2014-01-03 07:52:39 +00007
agoode@chromium.org25227512014-06-08 05:12:05 +00008#include <alsa/asoundlib.h>
9#include <map>
toyoshim@chromium.orga97eebf2014-01-03 07:52:39 +000010#include <vector>
11
12#include "base/basictypes.h"
agoode55a8b522015-03-08 12:40:17 -070013#include "base/gtest_prod_util.h"
toyoshim@chromium.orga97eebf2014-01-03 07:52:39 +000014#include "base/memory/scoped_ptr.h"
agoode@chromium.org25227512014-06-08 05:12:05 +000015#include "base/synchronization/lock.h"
toyoshim@chromium.orga97eebf2014-01-03 07:52:39 +000016#include "base/threading/thread.h"
17#include "media/midi/midi_manager.h"
18
agoode55a8b522015-03-08 12:40:17 -070019#if defined(USE_UDEV)
20#include "device/udev_linux/scoped_udev.h"
21#endif // defined(USE_UDEV)
22
toyoshim@chromium.orga97eebf2014-01-03 07:52:39 +000023namespace media {
24
agoode55a8b522015-03-08 12:40:17 -070025class MEDIA_EXPORT MidiManagerAlsa : public MidiManager {
toyoshim@chromium.orga97eebf2014-01-03 07:52:39 +000026 public:
toyoshim@chromium.orgc82e66e2014-02-04 07:05:47 +000027 MidiManagerAlsa();
dcheng9e8524d2014-10-27 15:18:50 -070028 ~MidiManagerAlsa() override;
toyoshim@chromium.orga97eebf2014-01-03 07:52:39 +000029
toyoshim@chromium.orgc82e66e2014-02-04 07:05:47 +000030 // MidiManager implementation.
dcheng9e8524d2014-10-27 15:18:50 -070031 void StartInitialization() override;
32 void DispatchSendMidiData(MidiManagerClient* client,
33 uint32 port_index,
34 const std::vector<uint8>& data,
35 double timestamp) override;
toyoshim@chromium.orga97eebf2014-01-03 07:52:39 +000036
37 private:
agoode55a8b522015-03-08 12:40:17 -070038 FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, ExtractManufacturer);
39 FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, UdevEscape);
40
41 class CardInfo {
42 public:
43 CardInfo(const MidiManagerAlsa* outer,
44 const std::string& alsa_name, const std::string& alsa_longname,
45 const std::string& alsa_driver, int card_index);
46 ~CardInfo();
47
48 const std::string alsa_name() const;
49 const std::string manufacturer() const;
50 const std::string alsa_driver() const;
51 const std::string udev_id_path() const;
52 const std::string udev_id_id() const;
53
54 private:
55 FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, ExtractManufacturer);
56 FRIEND_TEST_ALL_PREFIXES(MidiManagerAlsaTest, UdevEscape);
57
58 // Extracts the manufacturer using heuristics and a variety of sources.
59 static std::string ExtractManufacturerString(
60 const std::string& udev_id_vendor_enc,
61 const std::string& udev_id_vendor_id,
62 const std::string& udev_id_vendor_from_database,
63 const std::string& alsa_name,
64 const std::string& alsa_longname);
65
66 // TODO(agoode): Move this into a common place. Maybe device/udev_linux?
67 // Decodes just \xXX in strings.
68 static std::string UnescapeUdev(const std::string& s);
69
70 std::string alsa_name_;
71 std::string manufacturer_;
72 std::string alsa_driver_;
73 std::string udev_id_path_;
74 std::string udev_id_id_;
75 };
76
agoode@chromium.org25227512014-06-08 05:12:05 +000077 // An internal callback that runs on MidiSendThread.
78 void SendMidiData(uint32 port_index,
79 const std::vector<uint8>& data);
80
toyoshim@chromium.org4a8657c2014-02-06 11:23:09 +000081 void EventReset();
82 void EventLoop();
83
agoode@chromium.org25227512014-06-08 05:12:05 +000084 // Alsa seq handles.
85 snd_seq_t* in_client_;
86 snd_seq_t* out_client_;
87 int out_client_id_;
88
89 // One input port, many output ports.
90 int in_port_;
91 std::vector<int> out_ports_;
92
93 // Mapping from Alsa client:port to our index.
94 typedef std::map<int, uint32> SourceMap;
95 SourceMap source_map_;
96
97 // Alsa event <-> MIDI coders.
98 snd_midi_event_t* decoder_;
99 typedef std::vector<snd_midi_event_t*> EncoderList;
100 EncoderList encoders_;
101
agoode55a8b522015-03-08 12:40:17 -0700102 // udev, for querying hardware devices.
103#if defined(USE_UDEV)
104 device::ScopedUdevPtr udev_;
105#endif // defined(USE_UDEV)
106
toyoshim@chromium.orga97eebf2014-01-03 07:52:39 +0000107 base::Thread send_thread_;
toyoshim@chromium.org4a8657c2014-02-06 11:23:09 +0000108 base::Thread event_thread_;
109
agoode@chromium.org25227512014-06-08 05:12:05 +0000110 bool event_thread_shutdown_; // guarded by shutdown_lock_
111 base::Lock shutdown_lock_; // guards event_thread_shutdown_
toyoshim@chromium.org4a8657c2014-02-06 11:23:09 +0000112
toyoshim@chromium.orgc82e66e2014-02-04 07:05:47 +0000113 DISALLOW_COPY_AND_ASSIGN(MidiManagerAlsa);
toyoshim@chromium.orga97eebf2014-01-03 07:52:39 +0000114};
115
116} // namespace media
117
dnicoara@chromium.org9f2a6f02014-01-03 21:25:00 +0000118#endif // MEDIA_MIDI_MIDI_MANAGER_ALSA_H_