Commit e1848157 authored by crogers@google.com's avatar crogers@google.com

Revert 207983 "Implement Web MIDI API back-end"

> Implement Web MIDI API back-end
> 
> This involves browser-side support and IPC for sending and receiving
> MIDI messages.  Initially support for OSX is included.
> 
> BUG=163795
> R=palmer@chromium.org, piman@chromium.org, scherkus@chromium.org
> 
> Review URL: https://codereview.chromium.org/16025005

TBR=crogers@google.com

Review URL: https://codereview.chromium.org/17334006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@207989 0039d316-1c4b-4281-b951-d872f2087c98
parent a80773bb
...@@ -5,7 +5,6 @@ include_rules = [ ...@@ -5,7 +5,6 @@ include_rules = [
"+content/child/webkitplatformsupport_impl.h", # For in-process webkit "+content/child/webkitplatformsupport_impl.h", # For in-process webkit
"+media/audio", # For audio input for speech input feature. "+media/audio", # For audio input for speech input feature.
"+media/base", # For Android JNI registration. "+media/base", # For Android JNI registration.
"+media/midi", # For Web MIDI API
"+sql", "+sql",
"+ui/webui", "+ui/webui",
"+win8/util", "+win8/util",
......
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
#include "crypto/nss_util.h" #include "crypto/nss_util.h"
#include "media/audio/audio_manager.h" #include "media/audio/audio_manager.h"
#include "media/base/media.h" #include "media/base/media.h"
#include "media/midi/midi_manager.h"
#include "net/base/network_change_notifier.h" #include "net/base/network_change_notifier.h"
#include "net/socket/client_socket_factory.h" #include "net/socket/client_socket_factory.h"
#include "net/ssl/ssl_config_service.h" #include "net/ssl/ssl_config_service.h"
...@@ -401,10 +400,7 @@ void BrowserMainLoop::MainMessageLoopStart() { ...@@ -401,10 +400,7 @@ void BrowserMainLoop::MainMessageLoopStart() {
TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:AudioMan") TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:AudioMan")
audio_manager_.reset(media::AudioManager::Create()); audio_manager_.reset(media::AudioManager::Create());
} }
{
TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MIDIManager")
midi_manager_.reset(media::MIDIManager::Create());
}
#if !defined(OS_IOS) #if !defined(OS_IOS)
{ {
......
...@@ -20,7 +20,6 @@ class SystemMonitor; ...@@ -20,7 +20,6 @@ class SystemMonitor;
namespace media { namespace media {
class AudioManager; class AudioManager;
class MIDIManager;
} }
namespace net { namespace net {
...@@ -82,7 +81,6 @@ class BrowserMainLoop { ...@@ -82,7 +81,6 @@ class BrowserMainLoop {
MediaStreamManager* media_stream_manager() const { MediaStreamManager* media_stream_manager() const {
return media_stream_manager_.get(); return media_stream_manager_.get();
} }
media::MIDIManager* midi_manager() const { return midi_manager_.get(); }
private: private:
class MemoryObserver; class MemoryObserver;
...@@ -108,7 +106,6 @@ class BrowserMainLoop { ...@@ -108,7 +106,6 @@ class BrowserMainLoop {
scoped_ptr<HighResolutionTimerManager> hi_res_timer_manager_; scoped_ptr<HighResolutionTimerManager> hi_res_timer_manager_;
scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_;
scoped_ptr<media::AudioManager> audio_manager_; scoped_ptr<media::AudioManager> audio_manager_;
scoped_ptr<media::MIDIManager> midi_manager_;
scoped_ptr<AudioMirroringManager> audio_mirroring_manager_; scoped_ptr<AudioMirroringManager> audio_mirroring_manager_;
scoped_ptr<MediaStreamManager> media_stream_manager_; scoped_ptr<MediaStreamManager> media_stream_manager_;
// Per-process listener for online state changes. // Per-process listener for online state changes.
......
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/renderer_host/media/midi_host.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/debug/trace_event.h"
#include "base/process.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/media/media_internals.h"
#include "content/common/media/midi_messages.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/media_observer.h"
#include "media/midi/midi_manager.h"
using media::MIDIManager;
using media::MIDIPortInfoList;
namespace content {
MIDIHost::MIDIHost(media::MIDIManager* midi_manager)
: midi_manager_(midi_manager) {
}
MIDIHost::~MIDIHost() {
if (midi_manager_)
midi_manager_->ReleaseAccess(this);
}
void MIDIHost::OnChannelClosing() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
BrowserMessageFilter::OnChannelClosing();
}
void MIDIHost::OnDestruct() const {
BrowserThread::DeleteOnIOThread::Destruct(this);
}
///////////////////////////////////////////////////////////////////////////////
// IPC Messages handler
bool MIDIHost::OnMessageReceived(const IPC::Message& message,
bool* message_was_ok) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP_EX(MIDIHost, message, *message_was_ok)
IPC_MESSAGE_HANDLER(MIDIHostMsg_RequestAccess, OnRequestAccess)
IPC_MESSAGE_HANDLER(MIDIHostMsg_SendData, OnSendData)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP_EX()
return handled;
}
void MIDIHost::OnRequestAccess(int client_id, int access) {
MIDIPortInfoList input_ports;
MIDIPortInfoList output_ports;
// Ask permission and register to receive MIDI data.
bool approved = false;
if (midi_manager_) {
approved = midi_manager_->RequestAccess(this, access);
if (approved) {
input_ports = midi_manager_->input_ports();
output_ports = midi_manager_->output_ports();
}
}
Send(new MIDIMsg_AccessApproved(
client_id,
access,
approved,
input_ports,
output_ports));
}
void MIDIHost::OnSendData(int port,
const std::vector<uint8>& data,
double timestamp) {
// TODO(crogers): we need to post this to a dedicated thread for
// sending MIDI. For now, we will not implement the sending of MIDI data.
NOTIMPLEMENTED();
// if (midi_manager_)
// midi_manager_->SendMIDIData(port, data.data(), data.size(), timestamp);
}
void MIDIHost::ReceiveMIDIData(
int port_index,
const uint8* data,
size_t length,
double timestamp) {
TRACE_EVENT0("midi", "MIDIHost::ReceiveMIDIData");
// Send to the renderer.
std::vector<uint8> v(data, data + length);
Send(new MIDIMsg_DataReceived(port_index, v, timestamp));
}
} // namespace content
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_MIDI_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_MIDI_HOST_H_
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/browser/browser_thread.h"
#include "media/midi/midi_manager.h"
namespace media {
class MIDIManager;
}
namespace content {
class CONTENT_EXPORT MIDIHost
: public BrowserMessageFilter,
public media::MIDIManagerClient {
public:
// Called from UI thread from the owner of this object.
MIDIHost(media::MIDIManager* midi_manager);
// BrowserMessageFilter implementation.
virtual void OnChannelClosing() OVERRIDE;
virtual void OnDestruct() const OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message,
bool* message_was_ok) OVERRIDE;
// MIDIManagerClient implementation.
virtual void ReceiveMIDIData(
int port_index,
const uint8* data,
size_t length,
double timestamp) OVERRIDE;
// Request access to MIDI hardware.
void OnRequestAccess(int client_id, int access);
// Data to be sent to a MIDI output port.
void OnSendData(int port,
const std::vector<uint8>& data,
double timestamp);
private:
friend class base::DeleteHelper<MIDIHost>;
friend class BrowserThread;
virtual ~MIDIHost();
media::MIDIManager* const midi_manager_;
DISALLOW_COPY_AND_ASSIGN(MIDIHost);
};
} // namespace content
#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_MIDI_HOST_H_
...@@ -73,7 +73,6 @@ ...@@ -73,7 +73,6 @@
#include "content/browser/renderer_host/media/audio_mirroring_manager.h" #include "content/browser/renderer_host/media/audio_mirroring_manager.h"
#include "content/browser/renderer_host/media/audio_renderer_host.h" #include "content/browser/renderer_host/media/audio_renderer_host.h"
#include "content/browser/renderer_host/media/media_stream_dispatcher_host.h" #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
#include "content/browser/renderer_host/media/midi_host.h"
#include "content/browser/renderer_host/media/peer_connection_tracker_host.h" #include "content/browser/renderer_host/media/peer_connection_tracker_host.h"
#include "content/browser/renderer_host/media/video_capture_host.h" #include "content/browser/renderer_host/media/video_capture_host.h"
#include "content/browser/renderer_host/memory_benchmark_message_filter.h" #include "content/browser/renderer_host/memory_benchmark_message_filter.h"
...@@ -605,8 +604,6 @@ void RenderProcessHostImpl::CreateMessageFilters() { ...@@ -605,8 +604,6 @@ void RenderProcessHostImpl::CreateMessageFilters() {
GetID(), audio_manager, GetID(), audio_manager,
BrowserMainLoop::GetInstance()->audio_mirroring_manager(), BrowserMainLoop::GetInstance()->audio_mirroring_manager(),
media_internals, media_stream_manager)); media_internals, media_stream_manager));
channel_->AddFilter(
new MIDIHost(BrowserMainLoop::GetInstance()->midi_manager()));
channel_->AddFilter(new VideoCaptureHost(media_stream_manager)); channel_->AddFilter(new VideoCaptureHost(media_stream_manager));
channel_->AddFilter(new AppCacheDispatcherHost( channel_->AddFilter(new AppCacheDispatcherHost(
storage_partition_impl_->GetAppCacheService(), storage_partition_impl_->GetAppCacheService(),
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
#include "content/common/input_messages.h" #include "content/common/input_messages.h"
#include "content/common/java_bridge_messages.h" #include "content/common/java_bridge_messages.h"
#include "content/common/media/audio_messages.h" #include "content/common/media/audio_messages.h"
#include "content/common/media/midi_messages.h"
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
#include "content/common/media/media_player_messages_android.h" #include "content/common/media/media_player_messages_android.h"
#endif #endif
......
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// IPC messages for access to MIDI hardware.
// Multiply-included message file, hence no include guard.
#include "base/basictypes.h"
#include "content/common/content_export.h"
#include "ipc/ipc_message_macros.h"
#include "media/midi/midi_port_info.h"
#undef IPC_MESSAGE_EXPORT
#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
#define IPC_MESSAGE_START MIDIMsgStart
IPC_STRUCT_TRAITS_BEGIN(media::MIDIPortInfo)
IPC_STRUCT_TRAITS_MEMBER(id)
IPC_STRUCT_TRAITS_MEMBER(manufacturer)
IPC_STRUCT_TRAITS_MEMBER(name)
IPC_STRUCT_TRAITS_MEMBER(version)
IPC_STRUCT_TRAITS_END()
// Renderer request to browser for access to MIDI services.
IPC_MESSAGE_CONTROL2(MIDIHostMsg_RequestAccess,
int /* client id */,
int /* access */)
IPC_MESSAGE_CONTROL3(MIDIHostMsg_SendData,
int /* port */,
std::vector<uint8> /* data */,
double /* timestamp */)
// Messages sent from the browser to the renderer.
IPC_MESSAGE_CONTROL5(MIDIMsg_AccessApproved,
int /* client id */,
int /* access */,
bool /* success */,
media::MIDIPortInfoList /* input ports */,
media::MIDIPortInfoList /* output ports */)
IPC_MESSAGE_CONTROL3(MIDIMsg_DataReceived,
int /* port */,
std::vector<uint8> /* data */,
double /* timestamp */)
...@@ -791,8 +791,6 @@ ...@@ -791,8 +791,6 @@
'browser/renderer_host/media/media_stream_requester.h', 'browser/renderer_host/media/media_stream_requester.h',
'browser/renderer_host/media/media_stream_ui_proxy.cc', 'browser/renderer_host/media/media_stream_ui_proxy.cc',
'browser/renderer_host/media/media_stream_ui_proxy.h', 'browser/renderer_host/media/media_stream_ui_proxy.h',
'browser/renderer_host/media/midi_host.cc',
'browser/renderer_host/media/midi_host.h',
'browser/renderer_host/media/video_capture_buffer_pool.cc', 'browser/renderer_host/media/video_capture_buffer_pool.cc',
'browser/renderer_host/media/video_capture_buffer_pool.h', 'browser/renderer_host/media/video_capture_buffer_pool.h',
'browser/renderer_host/media/video_capture_controller.cc', 'browser/renderer_host/media/video_capture_controller.cc',
......
...@@ -265,7 +265,6 @@ ...@@ -265,7 +265,6 @@
'common/media/media_stream_messages.h', 'common/media/media_stream_messages.h',
'common/media/media_stream_options.cc', 'common/media/media_stream_options.cc',
'common/media/media_stream_options.h', 'common/media/media_stream_options.h',
'common/media/midi_messages.h',
'common/media/video_capture.h', 'common/media/video_capture.h',
'common/media/video_capture_messages.h', 'common/media/video_capture_messages.h',
'common/memory_benchmark_messages.h', 'common/memory_benchmark_messages.h',
......
...@@ -156,8 +156,6 @@ ...@@ -156,8 +156,6 @@
'renderer/media/media_stream_dispatcher.h', 'renderer/media/media_stream_dispatcher.h',
'renderer/media/media_stream_dispatcher_eventhandler.h', 'renderer/media/media_stream_dispatcher_eventhandler.h',
'renderer/media/media_stream_impl.h', 'renderer/media/media_stream_impl.h',
'renderer/media/midi_message_filter.cc',
'renderer/media/midi_message_filter.h',
'renderer/media/pepper_platform_video_decoder_impl.cc', 'renderer/media/pepper_platform_video_decoder_impl.cc',
'renderer/media/pepper_platform_video_decoder_impl.h', 'renderer/media/pepper_platform_video_decoder_impl.h',
'renderer/media/render_media_log.cc', 'renderer/media/render_media_log.cc',
...@@ -166,8 +164,6 @@ ...@@ -166,8 +164,6 @@
'renderer/media/renderer_gpu_video_decoder_factories.h', 'renderer/media/renderer_gpu_video_decoder_factories.h',
'renderer/media/renderer_webaudiodevice_impl.cc', 'renderer/media/renderer_webaudiodevice_impl.cc',
'renderer/media/renderer_webaudiodevice_impl.h', 'renderer/media/renderer_webaudiodevice_impl.h',
'renderer/media/renderer_webmidiaccessor_impl.cc',
'renderer/media/renderer_webmidiaccessor_impl.h',
'renderer/media/rtc_video_renderer.cc', 'renderer/media/rtc_video_renderer.cc',
'renderer/media/rtc_video_renderer.h', 'renderer/media/rtc_video_renderer.h',
'renderer/media/stream_texture_factory_impl_android.cc', 'renderer/media/stream_texture_factory_impl_android.cc',
......
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/renderer/media/midi_message_filter.h"
#include "base/bind.h"
#include "base/debug/trace_event.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/strings/utf_string_conversions.h"
#include "content/common/media/midi_messages.h"
#include "content/renderer/render_thread_impl.h"
#include "ipc/ipc_logging.h"
using media::MIDIPortInfoList;
using base::AutoLock;
namespace content {
MIDIMessageFilter::MIDIMessageFilter(
const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
: channel_(NULL),
io_message_loop_(io_message_loop),
next_available_id_(0) {
}
MIDIMessageFilter::~MIDIMessageFilter() {}
void MIDIMessageFilter::Send(IPC::Message* message) {
DCHECK(io_message_loop_->BelongsToCurrentThread());
if (!channel_) {
delete message;
} else {
channel_->Send(message);
}
}
bool MIDIMessageFilter::OnMessageReceived(const IPC::Message& message) {
DCHECK(io_message_loop_->BelongsToCurrentThread());
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(MIDIMessageFilter, message)
IPC_MESSAGE_HANDLER(MIDIMsg_AccessApproved, OnAccessApproved)
IPC_MESSAGE_HANDLER(MIDIMsg_DataReceived, OnDataReceived)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void MIDIMessageFilter::OnFilterAdded(IPC::Channel* channel) {
DCHECK(io_message_loop_->BelongsToCurrentThread());
channel_ = channel;
}
void MIDIMessageFilter::OnFilterRemoved() {
DCHECK(io_message_loop_->BelongsToCurrentThread());
// Once removed, a filter will not be used again. At this time all
// delegates must be notified so they release their reference.
OnChannelClosing();
}
void MIDIMessageFilter::OnChannelClosing() {
DCHECK(io_message_loop_->BelongsToCurrentThread());
channel_ = NULL;
}
void MIDIMessageFilter::RequestAccess(
WebKit::WebMIDIAccessorClient* client, int access) {
// Generate and keep track of a "client id" which is sent to the browser
// to ask permission to talk to MIDI hardware.
// This id is handed back when we receive the answer in OnAccessApproved().
if (clients_.find(client) == clients_.end()) {
int client_id = next_available_id_++;
clients_[client] = client_id;
io_message_loop_->PostTask(FROM_HERE,
base::Bind(&MIDIMessageFilter::RequestAccessOnIOThread, this,
client_id, access));
}
}
void MIDIMessageFilter::RequestAccessOnIOThread(int client_id, int access) {
Send(new MIDIHostMsg_RequestAccess(client_id, access));
}
void MIDIMessageFilter::RemoveClient(WebKit::WebMIDIAccessorClient* client) {
ClientsMap::iterator i = clients_.find(client);
if (i != clients_.end())
clients_.erase(i);
}
// Received from browser.
void MIDIMessageFilter::OnAccessApproved(
int client_id,
int access,
bool success,
MIDIPortInfoList inputs,
MIDIPortInfoList outputs) {
// Handle on the main JS thread.
ChildThread::current()->message_loop()->PostTask(FROM_HERE,
base::Bind(&MIDIMessageFilter::HandleAccessApproved, this,
client_id, access, success, inputs, outputs));
}
void MIDIMessageFilter::HandleAccessApproved(
int client_id,
int access,
bool success,
MIDIPortInfoList inputs,
MIDIPortInfoList outputs) {
WebKit::WebMIDIAccessorClient* client = GetClientFromId(client_id);
if (!client)
return;
if (success) {
// Add the client's input and output ports.
for (size_t i = 0; i < inputs.size(); ++i) {
client->didAddInputPort(
UTF8ToUTF16(inputs[i].id),
UTF8ToUTF16(inputs[i].manufacturer),
UTF8ToUTF16(inputs[i].name),
UTF8ToUTF16(inputs[i].version));
}
for (size_t i = 0; i < outputs.size(); ++i) {
client->didAddOutputPort(
UTF8ToUTF16(outputs[i].id),
UTF8ToUTF16(outputs[i].manufacturer),
UTF8ToUTF16(outputs[i].name),
UTF8ToUTF16(outputs[i].version));
}
}
if (success)
client->didAllowAccess();
else
client->didBlockAccess();
}
WebKit::WebMIDIAccessorClient*
MIDIMessageFilter::GetClientFromId(int client_id) {
// Iterating like this seems inefficient, but in practice there generally
// will be very few clients (usually one). Additionally, this lookup
// usually happens one time during page load. So the performance hit is
// negligible.
for (ClientsMap::iterator i = clients_.begin(); i != clients_.end(); ++i) {
if ((*i).second == client_id)
return (*i).first;
}
return NULL;
}
void MIDIMessageFilter::OnDataReceived(int port,
const std::vector<uint8>& data,
double timestamp) {
TRACE_EVENT0("midi", "MIDIMessageFilter::OnDataReceived");
ChildThread::current()->message_loop()->PostTask(FROM_HERE,
base::Bind(&MIDIMessageFilter::HandleDataReceived, this,
port, data, timestamp));
}
void MIDIMessageFilter::HandleDataReceived(int port,
const std::vector<uint8>& data,
double timestamp) {
TRACE_EVENT0("midi", "MIDIMessageFilter::HandleDataReceived");
#if defined(OS_ANDROID)
// TODO(crogers): figure out why data() method does not compile on Android.
NOTIMPLEMENTED();
#else
for (ClientsMap::iterator i = clients_.begin(); i != clients_.end(); ++i)
(*i).first->didReceiveMIDIData(port, data.data(), data.size(), timestamp);
#endif
}
void MIDIMessageFilter::SendMIDIData(int port,
const uint8* data,
size_t length,
double timestamp) {
// TODO(crogers): we need more work to check the amount of data sent,
// throttle if necessary, and filter out the SYSEX messages if not
// approved. For now, we will not implement the sending of MIDI data.
NOTIMPLEMENTED();
// std::vector<uint8> v(data, data + length);
// io_message_loop_->PostTask(FROM_HERE,
// base::Bind(&MIDIMessageFilter::SendMIDIDataOnIOThread, this,
// port, v, timestamp));
}
void MIDIMessageFilter::SendMIDIDataOnIOThread(int port,
const std::vector<uint8>& data,
double timestamp) {
// Send to the browser.
Send(new MIDIHostMsg_SendData(port, data, timestamp));
}
} // namespace content
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_RENDERER_MEDIA_MIDI_MESSAGE_FILTER_H_
#define CONTENT_RENDERER_MEDIA_MIDI_MESSAGE_FILTER_H_
#include <map>
#include <vector>
#include "base/memory/scoped_ptr.h"
#include "content/common/content_export.h"
#include "ipc/ipc_channel_proxy.h"
#include "media/midi/midi_port_info.h"
#include "third_party/WebKit/public/platform/WebMIDIAccessor.h"
#include "third_party/WebKit/public/platform/WebMIDIAccessorClient.h"
namespace base {
class MessageLoopProxy;
}
namespace content {
// MessageFilter that handles MIDI messages.
class CONTENT_EXPORT MIDIMessageFilter
: public IPC::ChannelProxy::MessageFilter {
public:
explicit MIDIMessageFilter(
const scoped_refptr<base::MessageLoopProxy>& io_message_loop);
// Each client registers for MIDI access here.
// If permission is granted, then the client's
// addInputPort() and addOutputPort() methods will be called,
// giving the client access to receive and send data.
void RequestAccess(WebKit::WebMIDIAccessorClient* client, int access);
void RemoveClient(WebKit::WebMIDIAccessorClient* client);
// A client will only be able to call this method if it has a suitable
// output port (from addOutputPort()).
void SendMIDIData(int port,
const uint8* data,
size_t length,
double timestamp);
// IO message loop associated with this message filter.
scoped_refptr<base::MessageLoopProxy> io_message_loop() const {
return io_message_loop_;
}
protected:
virtual ~MIDIMessageFilter();
private:
// Sends an IPC message using |channel_|.
void Send(IPC::Message* message);
// IPC::ChannelProxy::MessageFilter override. Called on |io_message_loop|.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE;
virtual void OnFilterRemoved() OVERRIDE;
virtual void OnChannelClosing() OVERRIDE;
// Called when the browser process has approved (or denied) access to
// MIDI hardware.
void OnAccessApproved(int client_id,
int access,
bool success,
media::MIDIPortInfoList inputs,
media::MIDIPortInfoList outputs);
// Called when the browser process has sent MIDI data containing one or
// more messages.
void OnDataReceived(int port,
const std::vector<uint8>& data,
double timestamp);
void HandleAccessApproved(int client_id,
int access,
bool success,
media::MIDIPortInfoList inputs,
media::MIDIPortInfoList outputs);
void HandleDataReceived(int port,
const std::vector<uint8>& data,
double timestamp);
void RequestAccessOnIOThread(int client_id, int access);
void SendMIDIDataOnIOThread(int port,
const std::vector<uint8>& data,
double timestamp);
WebKit::WebMIDIAccessorClient* GetClientFromId(int client_id);
// IPC channel for Send(); must only be accessed on |io_message_loop_|.
IPC::Channel* channel_;
// Message loop on which IPC calls are driven.
const scoped_refptr<base::MessageLoopProxy> io_message_loop_;
// Keeps track of all MIDI clients.
// We map client to "client id" used to track permission.
// When access has been approved, we add the input and output ports to
// the client, allowing it to actually receive and send MIDI data.
typedef std::map<WebKit::WebMIDIAccessorClient*, int> ClientsMap;
ClientsMap clients_;
// Dishes out client ids.
int next_available_id_;
DISALLOW_COPY_AND_ASSIGN(MIDIMessageFilter);
};
} // namespace content
#endif // CONTENT_RENDERER_MEDIA_MIDI_MESSAGE_FILTER_H_
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/renderer/media/renderer_webmidiaccessor_impl.h"
#include "base/logging.h"
#include "content/renderer/media/midi_message_filter.h"
#include "content/renderer/render_thread_impl.h"
namespace content {
RendererWebMIDIAccessorImpl::RendererWebMIDIAccessorImpl(
WebKit::WebMIDIAccessorClient* client)
: client_(client) {
DCHECK(client_);
}
RendererWebMIDIAccessorImpl::~RendererWebMIDIAccessorImpl() {
midi_message_filter()->RemoveClient(client_);
}
void RendererWebMIDIAccessorImpl::requestAccess(bool access) {
midi_message_filter()->RequestAccess(client_, access ? 1 : 0);
}
void RendererWebMIDIAccessorImpl::sendMIDIData(
unsigned port_index,
const unsigned char* data,
size_t length,
double timestamp) {
midi_message_filter()->SendMIDIData(
port_index,
data,
length,
timestamp);
}
MIDIMessageFilter* RendererWebMIDIAccessorImpl::midi_message_filter() {
return RenderThreadImpl::current()->midi_message_filter();
}
} // namespace content
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_RENDERER_MEDIA_RENDERER_WEBMIDIACCESSOR_IMPL_H_
#define CONTENT_RENDERER_MEDIA_RENDERER_WEBMIDIACCESSOR_IMPL_H_
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "third_party/WebKit/public/platform/WebMIDIAccessor.h"
#include "third_party/WebKit/public/platform/WebMIDIAccessorClient.h"
namespace content {
class MIDIMessageFilter;
class RendererWebMIDIAccessorImpl
: public WebKit::WebMIDIAccessor {
public:
explicit RendererWebMIDIAccessorImpl(
WebKit::WebMIDIAccessorClient* client);
virtual ~RendererWebMIDIAccessorImpl();
// WebKit::WebMIDIAccessor implementation.
virtual void requestAccess(bool access) OVERRIDE;
virtual void sendMIDIData(unsigned port_index,
const unsigned char* data,
size_t length,
double timestamp) OVERRIDE;
private:
WebKit::WebMIDIAccessorClient* client_;
MIDIMessageFilter* midi_message_filter();
DISALLOW_COPY_AND_ASSIGN(RendererWebMIDIAccessorImpl);
};
} // namespace content
#endif // CONTENT_RENDERER_MEDIA_RENDERER_WEBMIDIACCESSOR_IMPL_H_
...@@ -65,7 +65,6 @@ ...@@ -65,7 +65,6 @@
#include "content/renderer/media/audio_renderer_mixer_manager.h" #include "content/renderer/media/audio_renderer_mixer_manager.h"
#include "content/renderer/media/media_stream_center.h" #include "content/renderer/media/media_stream_center.h"
#include "content/renderer/media/media_stream_dependency_factory.h" #include "content/renderer/media/media_stream_dependency_factory.h"
#include "content/renderer/media/midi_message_filter.h"
#include "content/renderer/media/peer_connection_tracker.h" #include "content/renderer/media/peer_connection_tracker.h"
#include "content/renderer/media/video_capture_impl_manager.h" #include "content/renderer/media/video_capture_impl_manager.h"
#include "content/renderer/media/video_capture_message_filter.h" #include "content/renderer/media/video_capture_message_filter.h"
...@@ -369,9 +368,6 @@ void RenderThreadImpl::Init() { ...@@ -369,9 +368,6 @@ void RenderThreadImpl::Init() {
audio_message_filter_ = new AudioMessageFilter(GetIOMessageLoopProxy()); audio_message_filter_ = new AudioMessageFilter(GetIOMessageLoopProxy());
AddFilter(audio_message_filter_.get()); AddFilter(audio_message_filter_.get());
midi_message_filter_ = new MIDIMessageFilter(GetIOMessageLoopProxy());
AddFilter(midi_message_filter_.get());
AddFilter(new IndexedDBMessageFilter); AddFilter(new IndexedDBMessageFilter);
GetContentClient()->renderer()->RenderThreadStarted(); GetContentClient()->renderer()->RenderThreadStarted();
......
...@@ -81,7 +81,6 @@ class InputEventFilter; ...@@ -81,7 +81,6 @@ class InputEventFilter;
class InputHandlerManager; class InputHandlerManager;
class MediaStreamCenter; class MediaStreamCenter;
class MediaStreamDependencyFactory; class MediaStreamDependencyFactory;
class MIDIMessageFilter;
class P2PSocketDispatcher; class P2PSocketDispatcher;
class PeerConnectionTracker; class PeerConnectionTracker;
class RendererWebKitPlatformSupportImpl; class RendererWebKitPlatformSupportImpl;
...@@ -228,9 +227,6 @@ class CONTENT_EXPORT RenderThreadImpl : public RenderThread, ...@@ -228,9 +227,6 @@ class CONTENT_EXPORT RenderThreadImpl : public RenderThread,
return audio_message_filter_.get(); return audio_message_filter_.get();
} }
MIDIMessageFilter* midi_message_filter() {
return midi_message_filter_.get();
}
// Creates the embedder implementation of WebMediaStreamCenter. // Creates the embedder implementation of WebMediaStreamCenter.
// The resulting object is owned by WebKit and deleted by WebKit at tear-down. // The resulting object is owned by WebKit and deleted by WebKit at tear-down.
...@@ -383,7 +379,6 @@ class CONTENT_EXPORT RenderThreadImpl : public RenderThread, ...@@ -383,7 +379,6 @@ class CONTENT_EXPORT RenderThreadImpl : public RenderThread,
scoped_refptr<DBMessageFilter> db_message_filter_; scoped_refptr<DBMessageFilter> db_message_filter_;
scoped_refptr<AudioInputMessageFilter> audio_input_message_filter_; scoped_refptr<AudioInputMessageFilter> audio_input_message_filter_;
scoped_refptr<AudioMessageFilter> audio_message_filter_; scoped_refptr<AudioMessageFilter> audio_message_filter_;
scoped_refptr<MIDIMessageFilter> midi_message_filter_;
scoped_refptr<DevToolsAgentFilter> devtools_agent_message_filter_; scoped_refptr<DevToolsAgentFilter> devtools_agent_message_filter_;
scoped_ptr<MediaStreamDependencyFactory> media_stream_factory_; scoped_ptr<MediaStreamDependencyFactory> media_stream_factory_;
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
#include "content/renderer/hyphenator/hyphenator.h" #include "content/renderer/hyphenator/hyphenator.h"
#include "content/renderer/media/media_stream_dependency_factory.h" #include "content/renderer/media/media_stream_dependency_factory.h"
#include "content/renderer/media/renderer_webaudiodevice_impl.h" #include "content/renderer/media/renderer_webaudiodevice_impl.h"
#include "content/renderer/media/renderer_webmidiaccessor_impl.h"
#include "content/renderer/media/webcontentdecryptionmodule_impl.h" #include "content/renderer/media/webcontentdecryptionmodule_impl.h"
#include "content/renderer/render_thread_impl.h" #include "content/renderer/render_thread_impl.h"
#include "content/renderer/renderer_clipboard_client.h" #include "content/renderer/renderer_clipboard_client.h"
...@@ -92,7 +91,6 @@ using WebKit::WebFileSystem; ...@@ -92,7 +91,6 @@ using WebKit::WebFileSystem;
using WebKit::WebFrame; using WebKit::WebFrame;
using WebKit::WebGamepads; using WebKit::WebGamepads;
using WebKit::WebIDBFactory; using WebKit::WebIDBFactory;
using WebKit::WebMIDIAccessor;
using WebKit::Platform; using WebKit::Platform;
using WebKit::WebMediaStreamCenter; using WebKit::WebMediaStreamCenter;
using WebKit::WebMediaStreamCenterClient; using WebKit::WebMediaStreamCenterClient;
...@@ -773,14 +771,6 @@ RendererWebKitPlatformSupportImpl::createContentDecryptionModule( ...@@ -773,14 +771,6 @@ RendererWebKitPlatformSupportImpl::createContentDecryptionModule(
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
WebKit::WebMIDIAccessor*
RendererWebKitPlatformSupportImpl::createMIDIAccessor(
WebKit::WebMIDIAccessorClient* client) {
return new RendererWebMIDIAccessorImpl(client);
}
//------------------------------------------------------------------------------
WebKit::WebString WebKit::WebString
RendererWebKitPlatformSupportImpl::signedPublicKeyAndChallengeString( RendererWebKitPlatformSupportImpl::signedPublicKeyAndChallengeString(
unsigned key_size_index, unsigned key_size_index,
......
...@@ -107,8 +107,6 @@ class CONTENT_EXPORT RendererWebKitPlatformSupportImpl ...@@ -107,8 +107,6 @@ class CONTENT_EXPORT RendererWebKitPlatformSupportImpl
virtual WebKit::WebContentDecryptionModule* createContentDecryptionModule( virtual WebKit::WebContentDecryptionModule* createContentDecryptionModule(
const WebKit::WebString& key_system); const WebKit::WebString& key_system);
virtual WebKit::WebMIDIAccessor*
createMIDIAccessor(WebKit::WebMIDIAccessorClient* client);
virtual WebKit::WebBlobRegistry* blobRegistry(); virtual WebKit::WebBlobRegistry* blobRegistry();
virtual void sampleGamepads(WebKit::WebGamepads&); virtual void sampleGamepads(WebKit::WebGamepads&);
......
...@@ -47,7 +47,6 @@ enum IPCMessageStart { ...@@ -47,7 +47,6 @@ enum IPCMessageStart {
DesktopNotificationMsgStart, DesktopNotificationMsgStart,
GeolocationMsgStart, GeolocationMsgStart,
AudioMsgStart, AudioMsgStart,
MIDIMsgStart,
ChromeMsgStart, ChromeMsgStart,
DragMsgStart, DragMsgStart,
PrintMsgStart, PrintMsgStart,
......
...@@ -373,12 +373,6 @@ ...@@ -373,12 +373,6 @@
'filters/video_renderer_base.h', 'filters/video_renderer_base.h',
'filters/vpx_video_decoder.cc', 'filters/vpx_video_decoder.cc',
'filters/vpx_video_decoder.h', 'filters/vpx_video_decoder.h',
'midi/midi_manager.h',
'midi/midi_manager.cc',
'midi/midi_manager_mac.h',
'midi/midi_manager_mac.cc',
'midi/midi_port_info.h',
'midi/midi_port_info.cc',
'video/capture/android/video_capture_device_android.cc', 'video/capture/android/video_capture_device_android.cc',
'video/capture/android/video_capture_device_android.h', 'video/capture/android/video_capture_device_android.h',
'video/capture/fake_video_capture_device.cc', 'video/capture/fake_video_capture_device.cc',
...@@ -541,7 +535,6 @@ ...@@ -541,7 +535,6 @@
'$(SDKROOT)/System/Library/Frameworks/AudioToolbox.framework', '$(SDKROOT)/System/Library/Frameworks/AudioToolbox.framework',
'$(SDKROOT)/System/Library/Frameworks/AVFoundation.framework', '$(SDKROOT)/System/Library/Frameworks/AVFoundation.framework',
'$(SDKROOT)/System/Library/Frameworks/CoreAudio.framework', '$(SDKROOT)/System/Library/Frameworks/CoreAudio.framework',
'$(SDKROOT)/System/Library/Frameworks/CoreMIDI.framework',
], ],
}, },
}], }],
...@@ -754,7 +747,6 @@ ...@@ -754,7 +747,6 @@
'$(SDKROOT)/System/Library/Frameworks/AudioToolbox.framework', '$(SDKROOT)/System/Library/Frameworks/AudioToolbox.framework',
'$(SDKROOT)/System/Library/Frameworks/AudioUnit.framework', '$(SDKROOT)/System/Library/Frameworks/AudioUnit.framework',
'$(SDKROOT)/System/Library/Frameworks/CoreAudio.framework', '$(SDKROOT)/System/Library/Frameworks/CoreAudio.framework',
'$(SDKROOT)/System/Library/Frameworks/CoreMIDI.framework',
'$(SDKROOT)/System/Library/Frameworks/CoreVideo.framework', '$(SDKROOT)/System/Library/Frameworks/CoreVideo.framework',
'$(SDKROOT)/System/Library/Frameworks/OpenGL.framework', '$(SDKROOT)/System/Library/Frameworks/OpenGL.framework',
'$(SDKROOT)/System/Library/Frameworks/QTKit.framework', '$(SDKROOT)/System/Library/Frameworks/QTKit.framework',
......
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/midi/midi_manager.h"
namespace media {
#if !defined(OS_MACOSX)
// TODO(crogers): implement MIDIManager for other platforms.
MIDIManager* MIDIManager::Create() {
return NULL;
}
#endif
MIDIManager::MIDIManager()
: initialized_(false) {
}
MIDIManager::~MIDIManager() {}
bool MIDIManager::RequestAccess(MIDIManagerClient* client, int access) {
// TODO(crogers): determine if user prompt is necessary here.
// For now, simply don't allow sysex.
if (access != kNoSystemExclusive)
return false;
// Lazily initialize the MIDI back-end.
if (!initialized_)
initialized_ = Initialize();
if (initialized_) {
base::AutoLock auto_lock(clients_lock_);
clients_.insert(client);
}
return initialized_;
}
void MIDIManager::ReleaseAccess(MIDIManagerClient* client) {
base::AutoLock auto_lock(clients_lock_);
ClientList::iterator i = clients_.find(client);
if (i != clients_.end())
clients_.erase(i);
}
void MIDIManager::AddInputPort(const MIDIPortInfo& info) {
input_ports_.push_back(info);
}
void MIDIManager::AddOutputPort(const MIDIPortInfo& info) {
output_ports_.push_back(info);
}
void MIDIManager::ReceiveMIDIData(
int port_index,
const uint8* data,
size_t length,
double timestamp) {
base::AutoLock auto_lock(clients_lock_);
// TODO(crogers): Filter out sysex.
for (ClientList::iterator i = clients_.begin(); i != clients_.end(); ++i)
(*i)->ReceiveMIDIData(port_index, data, length, timestamp);
};
} // namespace media
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_MIDI_MIDI_MANAGER_H_
#define MEDIA_MIDI_MIDI_MANAGER_H_
#include <set>
#include "base/basictypes.h"
#include "base/synchronization/lock.h"
#include "media/base/media_export.h"
#include "media/midi/midi_port_info.h"
namespace media {
// A MIDIManagerClient registers with the MIDIManager to receive MIDI data.
// See MIDIManager::RequestAccess() and MIDIManager::ReleaseAccess()
// for details.
class MEDIA_EXPORT MIDIManagerClient {
public:
virtual ~MIDIManagerClient() {}
// ReceiveMIDIData() is called when MIDI data has been received from the
// MIDI system.
// |port_index| represents the specific input port from input_ports().
// |data| represents a series of bytes encoding one or more MIDI messages.
// |length| is the number of bytes in |data|.
// |timestamp| is the time the data was received, in seconds.
virtual void ReceiveMIDIData(int port_index,
const uint8* data,
size_t length,
double timestamp) = 0;
};
// Manages access to all MIDI hardware.
class MEDIA_EXPORT MIDIManager {
public:
enum AccessType {
kNoSystemExclusive,
kSystemExclusive
};
static MIDIManager* Create();
MIDIManager();
virtual ~MIDIManager();
// A client calls RequestAccess() to receive and send MIDI data.
// If access is approved, the MIDI system is lazily initialized
// and the client is registered to receive MIDI data.
// Returns |true| if access is approved.
bool RequestAccess(MIDIManagerClient* client, int access);
// A client calls ReleaseAccess() to stop receiving MIDI data.
void ReleaseAccess(MIDIManagerClient* client);
// SendMIDIData() sends one or more messages at the given time.
// |port_index| represents the specific output port from output_ports().
// |data| represents a series of bytes encoding one or more MIDI messages.
// |length| is the number of bytes in |data|.
// |timestamp| is the time to send the data, in seconds.
virtual void SendMIDIData(int port_index,
const uint8* data,
size_t length,
double timestamp) = 0;
// input_ports() is a list of MIDI ports for receiving MIDI data.
// Each individual port in this list can be identified by its
// integer index into this list.
const MIDIPortInfoList& input_ports() { return input_ports_; }
// output_ports() is a list of MIDI ports for sending MIDI data.
// Each individual port in this list can be identified by its
// integer index into this list.
const MIDIPortInfoList& output_ports() { return output_ports_; }
protected:
// Initializes the MIDI system, returning |true| on success.
virtual bool Initialize() = 0;
void AddInputPort(const MIDIPortInfo& info);
void AddOutputPort(const MIDIPortInfo& info);
// Dispatches to all clients.
void ReceiveMIDIData(
int port_index,
const uint8* data,
size_t length,
double timestamp);
bool initialized_;
// Keeps track of all clients who wish to receive MIDI data.
typedef std::set<MIDIManagerClient*> ClientList;
ClientList clients_;
// Protects access to our clients.
base::Lock clients_lock_;
MIDIPortInfoList input_ports_;
MIDIPortInfoList output_ports_;
DISALLOW_COPY_AND_ASSIGN(MIDIManager);
};
} // namespace media
#endif // MEDIA_MIDI_MIDI_MANAGER_H_
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/midi/midi_manager_mac.h"
#include <iostream>
#include <string>
#include "base/debug/trace_event.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/sys_string_conversions.h"
#include <CoreAudio/HostTime.h>
using base::IntToString;
using base::SysCFStringRefToUTF8;
using std::string;
namespace media {
MIDIManager* MIDIManager::Create() {
return new MIDIManagerMac();
}
MIDIManagerMac::MIDIManagerMac()
: midi_client_(NULL),
coremidi_input_(NULL),
coremidi_output_(NULL),
packet_list_(NULL),
midi_packet_(NULL) {
}
bool MIDIManagerMac::Initialize() {
TRACE_EVENT0("midi", "MIDIManagerMac::Initialize");
// CoreMIDI registration.
midi_client_ = NULL;
OSStatus result = MIDIClientCreate(
CFSTR("Google Chrome"),
NULL,
NULL,
&midi_client_);
if (result != noErr)
return false;
coremidi_input_ = NULL;
// Create input and output port.
result = MIDIInputPortCreate(
midi_client_,
CFSTR("MIDI Input"),
ReadMidiDispatch,
this,
&coremidi_input_);
if (result != noErr)
return false;
result = MIDIOutputPortCreate(
midi_client_,
CFSTR("MIDI Output"),
&coremidi_output_);
if (result != noErr)
return false;
int destination_count = MIDIGetNumberOfDestinations();
destinations_.reserve(destination_count);
for (int i = 0; i < destination_count ; i++) {
MIDIEndpointRef destination = MIDIGetDestination(i);
// Keep track of all destinations (known as outputs by the Web MIDI API).
// Cache to avoid any possible overhead in calling MIDIGetDestination().
destinations_[i] = destination;
MIDIPortInfo info = GetPortInfoFromEndpoint(destination);
AddOutputPort(info);
}
// Open connections from all sources.
int source_count = MIDIGetNumberOfSources();
for (int i = 0; i < source_count; ++i) {
// Receive from all sources.
MIDIEndpointRef src = MIDIGetSource(i);
MIDIPortConnectSource(coremidi_input_, src, src);
// Keep track of all sources (known as inputs in Web MIDI API terminology).
source_map_[src] = i;
MIDIPortInfo info = GetPortInfoFromEndpoint(src);
AddInputPort(info);
}
// TODO(crogers): Fix the memory management here!
packet_list_ = reinterpret_cast<MIDIPacketList*>(midi_buffer_);
midi_packet_ = MIDIPacketListInit(packet_list_);
return true;
}
MIDIManagerMac::~MIDIManagerMac() {
if (coremidi_input_)
MIDIPortDispose(coremidi_input_);
if (coremidi_output_)
MIDIPortDispose(coremidi_output_);
}
void MIDIManagerMac::ReadMidiDispatch(const MIDIPacketList* packet_list,
void* read_proc_refcon,
void* src_conn_refcon) {
MIDIManagerMac* manager = static_cast<MIDIManagerMac*>(read_proc_refcon);
MIDIEndpointRef source = static_cast<MIDIEndpointRef>(src_conn_refcon);
// Dispatch to class method.
manager->ReadMidi(source, packet_list);
}
void MIDIManagerMac::ReadMidi(MIDIEndpointRef source,
const MIDIPacketList* packet_list) {
// Lookup the port index based on the source.
SourceMap::iterator j = source_map_.find(source);
if (j == source_map_.end())
return;
int port_index = source_map_[source];
// Go through each packet and process separately.
for(size_t i = 0; i < packet_list->numPackets; i++) {
// Each packet contains MIDI data for one or more messages (like note-on).
const MIDIPacket &packet = packet_list->packet[i];
double timestamp_seconds = MIDITimeStampToSeconds(packet.timeStamp);
ReceiveMIDIData(
port_index,
packet.data,
packet.length,
timestamp_seconds);
}
}
void MIDIManagerMac::SendMIDIData(int port_index,
const uint8* data,
size_t length,
double timestamp) {
// TODO(crogers): Filter out sysex.
MIDITimeStamp coremidi_timestamp = SecondsToMIDITimeStamp(timestamp);
midi_packet_ = MIDIPacketListAdd(
packet_list_,
kMaxPacketListSize,
midi_packet_,
coremidi_timestamp,
length,
data);
// Lookup the destination based on the port index.
// TODO(crogers): re-factor |port_index| to use unsigned
// to avoid the need for this check.
if (port_index < 0 ||
static_cast<size_t>(port_index) >= destinations_.size())
return;
MIDIEndpointRef destination = destinations_[port_index];
MIDISend(coremidi_output_, destination, packet_list_);
// Re-initialize for next time.
midi_packet_ = MIDIPacketListInit(packet_list_);
}
MIDIPortInfo MIDIManagerMac::GetPortInfoFromEndpoint(
MIDIEndpointRef endpoint) {
SInt32 id_number = 0;
MIDIObjectGetIntegerProperty(endpoint, kMIDIPropertyUniqueID, &id_number);
string id = IntToString(id_number);
CFStringRef manufacturer_ref = NULL;
MIDIObjectGetStringProperty(
endpoint, kMIDIPropertyManufacturer, &manufacturer_ref);
string manufacturer = SysCFStringRefToUTF8(manufacturer_ref);
CFStringRef name_ref = NULL;
MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &name_ref);
string name = SysCFStringRefToUTF8(name_ref);
SInt32 version_number = 0;
MIDIObjectGetIntegerProperty(
endpoint, kMIDIPropertyDriverVersion, &version_number);
string version = IntToString(version_number);
return MIDIPortInfo(id, manufacturer, name, version);
}
double MIDIManagerMac::MIDITimeStampToSeconds(MIDITimeStamp timestamp) {
UInt64 nanoseconds = AudioConvertHostTimeToNanos(timestamp);
return static_cast<double>(nanoseconds) / 1.0e9;
}
MIDITimeStamp MIDIManagerMac::SecondsToMIDITimeStamp(double seconds) {
UInt64 nanos = UInt64(seconds * 1.0e9);
return AudioConvertNanosToHostTime(nanos);
}
} // namespace media
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_MIDI_MIDI_MANAGER_MAC_H_
#define MEDIA_MIDI_MIDI_MANAGER_MAC_H_
#include <CoreMIDI/MIDIServices.h>
#include <map>
#include <string>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "media/midi/midi_manager.h"
#include "media/midi/midi_port_info.h"
namespace media {
class MEDIA_EXPORT MIDIManagerMac : public MIDIManager {
public:
MIDIManagerMac();
virtual ~MIDIManagerMac();
// MIDIManager implementation.
virtual bool Initialize() OVERRIDE;
virtual void SendMIDIData(int port_index,
const uint8* data,
size_t length,
double timestamp) OVERRIDE;
private:
// CoreMIDI callback for MIDI data.
// Each callback can contain multiple packets, each of which can contain
// multiple MIDI messages.
static void ReadMidiDispatch(
const MIDIPacketList *pktlist,
void *read_proc_refcon,
void *src_conn_refcon);
virtual void ReadMidi(MIDIEndpointRef source, const MIDIPacketList *pktlist);
// Helper
static media::MIDIPortInfo GetPortInfoFromEndpoint(MIDIEndpointRef endpoint);
static double MIDITimeStampToSeconds(MIDITimeStamp timestamp);
static MIDITimeStamp SecondsToMIDITimeStamp(double seconds);
// CoreMIDI
MIDIClientRef midi_client_;
MIDIPortRef coremidi_input_;
MIDIPortRef coremidi_output_;
enum{ kMaxPacketListSize = 512 };
char midi_buffer_[kMaxPacketListSize];
MIDIPacketList* packet_list_;
MIDIPacket* midi_packet_;
typedef std::map<MIDIEndpointRef, int> SourceMap;
// Keeps track of the index (0-based) for each of our sources.
SourceMap source_map_;
// Keeps track of all destinations.
std::vector<MIDIEndpointRef> destinations_;
DISALLOW_COPY_AND_ASSIGN(MIDIManagerMac);
};
} // namespace media
#endif // MEDIA_MIDI_MIDI_MANAGER_MAC_H_
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/midi/midi_port_info.h"
#include <iostream>
using std::cout;
namespace media {
MIDIPortInfo::MIDIPortInfo() {}
MIDIPortInfo::MIDIPortInfo(const std::string& in_id,
const std::string& in_manufacturer,
const std::string& in_name,
const std::string& in_version)
: id(in_id),
manufacturer(in_manufacturer),
name(in_name),
version(in_version) {}
MIDIPortInfo::~MIDIPortInfo() {}
MIDIPortInfo::MIDIPortInfo(const MIDIPortInfo& info)
: id(info.id),
manufacturer(info.manufacturer),
name(info.name),
version(info.version) {}
} // namespace media
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_MIDI_MIDI_PORT_INFO_H_
#define MEDIA_MIDI_MIDI_PORT_INFO_H_
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "media/base/media_export.h"
namespace media {
struct MEDIA_EXPORT MIDIPortInfo {
MIDIPortInfo();
MIDIPortInfo(const std::string& in_id,
const std::string& in_manufacturer,
const std::string& in_name,
const std::string& in_version);
MIDIPortInfo(const MIDIPortInfo& info);
~MIDIPortInfo();
std::string id;
std::string manufacturer;
std::string name;
std::string version;
};
typedef std::vector<MIDIPortInfo> MIDIPortInfoList;
} // namespace media
#endif // MEDIA_MIDI_MIDI_PORT_INFO_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment