2 ==============================================================================
4 This file is part of the async
5 Copyright 2005-10 by Satoshi Fujiwara.
7 async can be redistributed and/or modified under the terms of the
8 GNU General Public License, as published by the Free Software Foundation;
9 either version 2 of the License, or (at your option) any later version.
11 async 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.
16 You should have received a copy of the GNU General Public License
17 along with async; if not, visit www.gnu.org/licenses or write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 Boston, MA 02111-1307 USA
21 ==============================================================================
27 #define _CRTDBG_MAP_ALLOC
29 #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
32 #include "message_loop.h"
34 #include "application.h"
35 #include "input_agent.h"
37 #include "async_reader.h"
43 void input_agent_t::run()
46 sf::com_initialize init(0,multi_threaded);
49 sf::av_mm_thread_characteristics avmm(wstring(L"Pro Audio"));
50 avmm.set_priority(AVRT_PRIORITY_HIGH);
53 //wasapi_device_manager::ptr m(wasapi_device_manager::instance());
55 // m->current_input_device_index(),
56 // m->current_input_device().params
58 change_status(status_pause);
59 application& app(*application::instance());
60 int status = STATUS_ERROR;
63 int source_counter ,dest_counter;
64 source_counter = dest_counter = 0;
66 //app.output_thread().wait_status(output_agent_t::status_processing,10);
68 //wasapi_device_manager::instance()->current_input_device_index(),
69 //wasapi_device_manager::instance()->current_input_device().params);
70 change_status(status_device_config);
71 while(status = status_.load(),status != status_exit)
76 case status_device_config:
79 wasapi_input_->stop();
81 change_status(status_device_config_ok);
83 change_status(status_nodevice);
88 if(!wasapi_input_->is_start()){
89 wasapi_input_->start();
91 change_status(status_processing);
94 case status_processing:
97 assert(wasapi_input_ != nullptr);
98 wasapi_input_->wait();// 入力待ち
100 get_buffer g(*wasapi_input_);// キャプチャバッファの取得
101 if(g.size() && g != 0)
104 while(source_counter != g.size())
106 BYTE * src = g + source_counter * wasapi_input_->get_frame_size();
107 int size_byte_src = g.size_byte() - source_counter * wasapi_input_->get_frame_size();
108 int size_src = g.size() - source_counter;
110 BYTE * dest = buffer_[index_].get() + dest_counter * app.output_device().get_frame_size();
111 int size_byte_dest = app.output_device().get_buffer_byte_size() - dest_counter * app.output_device().get_frame_size();
112 int size_dest = app.output_device().get_buffer_size() - dest_counter;
114 if(size_src <= size_dest)
116 ::CopyMemory(dest,src,size_byte_src);
117 source_counter += size_src;
118 dest_counter += size_src;
119 } else if(size_src > size_dest)
121 ::CopyMemory(dest,src,size_byte_dest);
122 source_counter += size_dest;
123 dest_counter += size_dest;
125 if(dest_counter == app.output_device().get_buffer_size())
127 if(ringbuffer_.enqueue(buffer_[index_].get()))
129 index_ = (index_ + 1) & (buffer_.size() - 1);
144 wasapi_input_->stop();
146 change_status(status_pause_ok);
150 // WaitForSingleObject(event_.get(),WAIT_TIMEOUT_DEFAULT);
156 DOUT(L"##### input_threadは終了!" << endl);
157 if(wasapi_input_ && wasapi_input_->is_start())
159 wasapi_input_->stop();
160 wasapi_input_.reset();
166 void input_agent_t::apply_config(int device_index,wasapi_device_manager::device_info::params_t& params)
168 if(status() != status_device_config_ok && status() != status_nodevice)
170 change_and_wait(status_device_config,status_device_config_ok);
173 apply_config_(device_index,params);
176 change_and_wait(status_device_config,status_device_config_ok);
178 if(status() != status_nodevice)
181 change_and_wait(status_process,status_processing);
185 void input_agent_t::apply_config_(int device_index,wasapi_device_manager::device_info::params_t& params)
188 WAVEFORMATEXTENSIBLE form;
191 if(wasapi_input_->is_start())
193 wasapi_input_->stop();
195 wasapi_input_.reset();
198 //bits_pair bits = {params.bits,params.valid_bits};
199 //make_wave_format(form,params.sample_rate,params.channel,bits);
202 if(params.exclusive_mode)
204 if(params.event_mode){
205 wasapi_input_.reset(new sf::wasapi_capture_exclusive_event(device_index,params));
207 wasapi_input_.reset(new sf::wasapi_capture_exclusive_timer(device_index,params));
210 if(params.event_mode)
212 wasapi_input_.reset(new sf::wasapi_capture_shared_event(device_index,params));
214 wasapi_input_.reset(new sf::wasapi_capture_shared_timer(device_index,params));
217 } catch (win32_error_exception& e)
220 //window_->message_box((boost::wformat(L"WASAPI初期化エラーが発生しました。設定パラメータを見なおしてください。%s") % e.error()).str(),wstring(L"WASAPI初期化エラー"));
224 wasapi_device_manager::instance()->select_input_device(device_index);
225 wasapi_device_manager::instance()->current_input_device().params = params;
229 //void input_agent_t::init_buffer()
231 // audio_base& in(application::instance()->input_device());
232 // for(int i = 0,size = buffer_.size();i < size;++i)
234 // buffer_[i].reset(reinterpret_cast<uint8_t*>(_aligned_malloc(sizeof(uint8_t) * in.get_buffer_byte_size(),16)));