2 ==============================================================================
\r
4 This file is part of the async
\r
5 Copyright 2005-10 by Satoshi Fujiwara.
\r
7 async can be redistributed and/or modified under the terms of the
\r
8 GNU General Public License, as published by the Free Software Foundation;
\r
9 either version 2 of the License, or (at your option) any later version.
\r
11 async is distributed in the hope that it will be useful,
\r
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 GNU General Public License for more details.
\r
16 You should have received a copy of the GNU General Public License
\r
17 along with async; if not, visit www.gnu.org/licenses or write to the
\r
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330,
\r
19 Boston, MA 02111-1307 USA
\r
21 ==============================================================================
\r
24 #include <commctrl.h>
\r
27 #define _CRTDBG_MAP_ALLOC
\r
29 #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
\r
32 #include "message_loop.h"
\r
34 #include "application.h"
\r
35 #include "input_thread.h"
\r
37 #include "async_reader.h"
\r
39 using namespace std;
\r
43 void input_thread_t::thread_main()
\r
46 sf::com_initialize init(0,multi_threaded);
\r
49 sf::av_mm_thread_characteristics avmm(wstring(L"Pro Audio"));
\r
50 avmm.set_priority(AVRT_PRIORITY_HIGH);
\r
53 //wasapi_device_manager::ptr m(wasapi_device_manager::instance());
\r
55 // m->current_input_device_index(),
\r
56 // m->current_input_device().params
\r
58 change_status(status_pause);
\r
59 application& app(*application::instance());
\r
60 int status = STATUS_ERROR;
\r
63 int source_counter ,dest_counter;
\r
64 source_counter = dest_counter = 0;
\r
65 //// 出力デバイスが稼働するまで待つ
\r
66 //app.output_thread().wait_status(output_thread_t::status_processing,10);
\r
68 //wasapi_device_manager::instance()->current_input_device_index(),
\r
69 //wasapi_device_manager::instance()->current_input_device().params);
\r
70 change_status(status_device_config);
\r
71 while(status = status_.load(),status != status_exit)
\r
76 case status_device_config:
\r
79 wasapi_input_->stop();
\r
82 change_status(status_device_config_ok);
\r
84 case status_process:
\r
85 if(!wasapi_input_->is_start()){
\r
86 wasapi_input_->start();
\r
88 change_status(status_processing);
\r
89 case status_processing:
\r
91 wasapi_input_->wait();// 入力待ち
\r
92 get_buffer g(*wasapi_input_);// キャプチャバッファの取得
\r
93 if(g.size() && g != 0)
\r
96 while(source_counter != g.size())
\r
98 BYTE * src = g + source_counter * wasapi_input_->get_frame_size();
\r
99 int size_byte_src = g.size_byte() - source_counter * wasapi_input_->get_frame_size();
\r
100 int size_src = g.size() - source_counter;
\r
102 BYTE * dest = buffer_[index_].get() + dest_counter * app.output_device().get_frame_size();
\r
103 int size_byte_dest = app.output_device().get_buffer_byte_size() - dest_counter * app.output_device().get_frame_size();
\r
104 int size_dest = app.output_device().get_buffer_size() - dest_counter;
\r
106 if(size_src <= size_dest)
\r
108 ::CopyMemory(dest,src,size_byte_src);
\r
109 source_counter += size_src;
\r
110 dest_counter += size_src;
\r
111 } else if(size_src > size_dest)
\r
113 ::CopyMemory(dest,src,size_byte_dest);
\r
114 source_counter += size_dest;
\r
115 dest_counter += size_dest;
\r
117 if(dest_counter == app.output_device().get_buffer_size())
\r
119 if(ringbuffer_.enqueue(buffer_[index_].get()))
\r
121 index_ = (index_ + 1) & (buffer_.size() - 1);
\r
132 wasapi_input_->stop();
\r
134 change_status(status_pause_ok);
\r
137 WaitForSingleObject(event_.get(),WAIT_TIMEOUT_DEFAULT);
\r
143 DOUT(L"##### input_threadは終了!" << endl);
\r
144 if(wasapi_input_ && wasapi_input_->is_start())
\r
146 wasapi_input_->stop();
\r
148 wasapi_input_.reset();
\r
151 void input_thread_t::apply_config(int device_index,wasapi_device_manager::device_info::params_t& params)
\r
153 if(status() != status_device_config_ok){
\r
154 change_and_wait(status_device_config,status_device_config_ok);
\r
156 apply_config_(device_index,params);
\r
158 change_and_wait(status_process,status_processing);
\r
161 void input_thread_t::apply_config_(int device_index,wasapi_device_manager::device_info::params_t& params)
\r
164 WAVEFORMATEXTENSIBLE form;
\r
167 if(wasapi_input_->is_start())
\r
169 wasapi_input_->stop();
\r
171 wasapi_input_.reset();
\r
174 //bits_pair bits = {params.bits,params.valid_bits};
\r
175 //make_wave_format(form,params.sample_rate,params.channel,bits);
\r
178 if(params.exclusive_mode)
\r
180 if(params.event_mode){
\r
181 wasapi_input_.reset(new sf::wasapi_capture_exclusive_event(device_index,params));
\r
183 wasapi_input_.reset(new sf::wasapi_capture_exclusive_timer(device_index,params));
\r
186 if(params.event_mode)
\r
188 wasapi_input_.reset(new sf::wasapi_capture_shared_event(device_index,params));
\r
190 wasapi_input_.reset(new sf::wasapi_capture_shared_timer(device_index,params));
\r
193 } catch (win32_error_exception& e)
\r
196 //window_->message_box((boost::wformat(L"WASAPI初期化エラーが発生しました。設定パラメータを見なおしてください。%s") % e.error()).str(),wstring(L"WASAPI初期化エラー"));
\r
200 wasapi_device_manager::instance()->select_input_device(device_index);
\r
201 wasapi_device_manager::instance()->current_input_device().params = params;
\r
205 //void input_thread_t::init_buffer()
\r
207 // audio_base& in(application::instance()->input_device());
\r
208 // for(int i = 0,size = buffer_.size();i < size;++i)
\r
210 // buffer_[i].reset(reinterpret_cast<uint8_t*>(_aligned_malloc(sizeof(uint8_t) * in.get_buffer_byte_size(),16)));
\r