Created
January 4, 2016 18:01
-
-
Save saivert/19794df8b8bec35cd140 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
#include "ConIo.h" | |
CConIo::CConIo(LPWSTR child) : isRunning(false) | |
{ | |
lstrcpy(cmdline, child); | |
} | |
void CConIo::threadProc(void) | |
{ | |
// Set the security attributes for the pipe handles created | |
security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES); | |
security_attributes.bInheritHandle = TRUE; | |
security_attributes.lpSecurityDescriptor = NULL; | |
//CreatePipe(&child_output_read, &child_output_write, &security_attributes, 0); | |
CreatePipe(&child_input_read, &child_input_write, &security_attributes, 0); | |
// Create the child process | |
ZeroMemory(&process_info, sizeof(PROCESS_INFORMATION)); | |
ZeroMemory(&startup_info, sizeof(STARTUPINFO)); | |
startup_info.cb = sizeof(STARTUPINFO); | |
startup_info.hStdInput = child_input_read; | |
//startup_info.hStdOutput = child_output_write; | |
//startup_info.hStdError = child_output_write; | |
startup_info.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; | |
#ifdef _DEBUG | |
startup_info.wShowWindow = SW_SHOWDEFAULT; | |
#else | |
startup_info.wShowWindow = SW_HIDE; | |
#endif | |
CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &process_info); | |
CloseHandle(child_input_read); | |
isRunning = true; | |
while (isRunning) { | |
//DWORD bytes_written; | |
//WriteFile(child_input_write, buffer, sizeof(buffer), &bytes_written, NULL); | |
__noop; | |
} | |
CloseHandle(child_input_write); | |
WaitForSingleObject(process_info.hProcess, INFINITE); | |
//CloseHandle(process_info.hProcess); | |
//CloseHandle(process_info.hThread); | |
} | |
bool CConIo::Write(void* data, DWORD len, LPDWORD bytes_written) | |
{ | |
if (isRunning) return WriteFile(child_input_write, data, len, bytes_written, NULL)>0; | |
//memcpy(buffer, data, sizeof(buffer)); | |
return true; | |
} | |
bool CConIo::Read(void* data, DWORD len, LPDWORD bytes_read) | |
{ | |
return ReadFile(child_output_read, data, len, bytes_read, NULL)>0; | |
} | |
CConIo::~CConIo() | |
{ | |
isRunning = false; | |
waitTillDone(); | |
//CloseHandle(process_info.hProcess); | |
//CloseHandle(process_info.hThread); | |
//CloseHandle(child_output_read); | |
//CloseHandle(child_output_write); | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
class CConIo : public pfc::thread | |
{ | |
private: | |
WCHAR cmdline[MAX_PATH]; | |
HANDLE child_input_read; | |
HANDLE child_input_write; | |
HANDLE child_output_read; | |
HANDLE child_output_write; | |
PROCESS_INFORMATION process_info; | |
STARTUPINFO startup_info; | |
SECURITY_ATTRIBUTES security_attributes; | |
BYTE buffer[4096]; | |
bool isRunning; | |
public: | |
CConIo(LPWSTR child); | |
void threadProc(void); | |
bool Write(void* data, DWORD len, LPDWORD bytes_written); | |
bool Read(void* data, DWORD len, LPDWORD bytes_read); | |
~CConIo(); | |
}; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
//#include "wavefile.h" | |
#include "ConIo.h" | |
#define COMPONENT_NAME "foo_output_pipe" | |
DECLARE_COMPONENT_VERSION( | |
COMPONENT_NAME, | |
"0.0.1", | |
"pipes audio via a console app" | |
); | |
VALIDATE_COMPONENT_FILENAME("foo_output_pipe.dll"); | |
class myinitquit : public initquit { | |
public: | |
void on_init() { | |
console::print(COMPONENT_NAME " component: on_init()"); | |
} | |
void on_quit() { | |
console::print(COMPONENT_NAME " component: on_quit()"); | |
} | |
}; | |
static initquit_factory_t<myinitquit> g_myinitquit_factory; | |
//CWaveFile wf; | |
int g_iswriting=0; | |
CConIo * g_conio; | |
class mycapturestream : public playback_stream_capture_callback, public service_base { | |
private: | |
int count; | |
public: | |
void on_chunk(const audio_chunk &d) { | |
//if (d.get_used_size() == 0) return; | |
console::printf(COMPONENT_NAME " got chunk #%d: samplecount=%d used size=%d", ++count, d.get_sample_count(), d.get_used_size() ); | |
//WAVEFORMATEX wfx; | |
mem_block_container_impl_t<> out; | |
DWORD written; | |
out.set_size(d.get_used_size()); | |
d.toFixedPoint(out, 16, 16); | |
if (!g_iswriting) { | |
g_iswriting = 1; | |
pfc::string_formatter s; | |
WCHAR buf[256]; | |
s << "D:\\ffmpeg32\\bin\\ffmpeg.exe -f s16le -ar " << d.get_sample_rate() << " -ac " << d.get_channels() << " -i - -y d:\\out.mp3"; | |
//DeleteFile(L"d:\\out.mp3"); | |
//s << "D:\\lame\\lame.exe -r - d:\\out.mp3"; | |
console::printf(COMPONENT_NAME " %s", s.toString()); | |
pfc::stringcvt::convert_utf8_to_wide(buf, sizeof(buf), s.toString(), s.get_length()); | |
g_conio = new CConIo(buf); | |
g_conio->start(); | |
} | |
if (g_conio->Write(out.get_ptr(), out.get_size(), &written)) { | |
console::printf(COMPONENT_NAME " written %d bytes to file", written); | |
} | |
else { | |
console::printf(COMPONENT_NAME "Unable to write to pipe"); | |
} | |
#if 0 | |
if (!g_iswriting) { | |
g_iswriting = 1; | |
wfx.cbSize = sizeof(wfx); | |
wfx.nChannels = d.get_channels(); | |
wfx.nSamplesPerSec = d.get_sample_rate(); | |
wfx.wBitsPerSample = 16; | |
wfx.wFormatTag = WAVE_FORMAT_PCM; | |
wfx.nBlockAlign = (16 * 2) / 8; | |
wfx.nAvgBytesPerSec = wfx.nBlockAlign*wfx.nSamplesPerSec; | |
wf.Open(L"D:\\out.wav", &wfx, NULL); | |
} | |
wf.Write(out.get_size(), (BYTE*)out.get_ptr(), &written); | |
#endif | |
} | |
}; | |
static service_impl_single_t< mycapturestream >g_mycapturestream; | |
class vstream_play_callback_ui :public play_callback_static{ | |
public: | |
virtual unsigned get_flags(){ | |
return play_callback::flag_on_playback_dynamic_info_track | | |
play_callback::flag_on_playback_new_track | | |
play_callback::flag_on_playback_starting | | |
play_callback::flag_on_playback_stop | | |
play_callback::flag_on_playback_pause | | |
play_callback::flag_on_playback_edited; | |
} | |
virtual void on_playback_pause(bool p_state){ | |
static_api_ptr_t<playback_stream_capture> api; | |
console::print(COMPONENT_NAME " on_playback_pause"); | |
if (!p_state) { | |
api->add_callback(&g_mycapturestream); | |
} else { | |
//wf.Close(); | |
g_iswriting = 0; | |
delete g_conio; | |
api->remove_callback(&g_mycapturestream); | |
} | |
} | |
virtual void on_playback_new_track(metadb_handle_ptr p_track) { } | |
virtual void on_playback_edited(metadb_handle_ptr p_track){ } | |
virtual void on_playback_dynamic_info_track(const file_info&p_info){ } | |
virtual void on_playback_starting(play_control::t_track_command p_command, bool p_paused){ on_playback_pause(p_paused); } | |
virtual void on_playback_stop(play_control::t_stop_reason p_reason){ | |
if (!(p_reason == play_control::stop_reason_starting_another)) | |
this->on_playback_pause(true); | |
} | |
virtual void on_playback_seek(double p_time){} | |
virtual void on_playback_dynamic_info(const file_info & p_info){} | |
virtual void on_playback_time(double p_time){} | |
virtual void on_volume_change(float p_new_val){} | |
}; | |
static service_factory_single_t<vstream_play_callback_ui>vstream_callback; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment