diff --git a/samplebrain/qt/audio_thread.cpp b/samplebrain/qt/audio_thread.cpp index 2ed5fd0..a810f6a 100644 --- a/samplebrain/qt/audio_thread.cpp +++ b/samplebrain/qt/audio_thread.cpp @@ -48,7 +48,8 @@ audio_thread::~audio_thread() { void audio_thread::start_audio() { if (m_audio_device!=NULL) delete m_audio_device; - m_audio_device = new audio_device("samplebrain",44100,2048); + m_audio_device = new audio_device("samplebrain",48000,2048); + //m_audio_device = new audio_device("samplebrain",48000,2048*4); m_audio_device->m_client.set_callback(run_audio, this); } diff --git a/samplebrain/src/block.cpp b/samplebrain/src/block.cpp index aeedbaf..038808c 100644 --- a/samplebrain/src/block.cpp +++ b/samplebrain/src/block.cpp @@ -114,7 +114,7 @@ void block::process(const sample &pcm, sample &fft, sample &mfcc, float &freq) { std::vector > mfspec; for (u32 i=0; i(m_fftw->m_spectrum[i][0], - m_fftw->m_spectrum[i][1])); + m_fftw->m_spectrum[i][1])); } freq = m_fftw->calculate_dominant_freq(); diff --git a/samplebrain/src/block_stream.cpp b/samplebrain/src/block_stream.cpp index 72e99ae..8858d30 100644 --- a/samplebrain/src/block_stream.cpp +++ b/samplebrain/src/block_stream.cpp @@ -14,6 +14,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include #include #include "block_stream.h" @@ -22,6 +23,7 @@ using namespace std; #define BUFFER_SIZE 4096*10 #define MAX_BLOCKS 200 +#define NUM_WORKERS 4 block_stream::block_stream() : m_ready(false), @@ -29,8 +31,13 @@ block_stream::block_stream() : m_block_position(0), m_buffer_position(0), m_buffer(BUFFER_SIZE), - m_block_index_offset(0) + m_block_index_offset(0), + m_sent_block_index(0) { + for (u32 i=0; i=m_block_size) m_overlap=0; - cerr<MAX_BLOCKS) { m_blocks.erase(m_blocks.begin()); @@ -80,9 +100,70 @@ void block_stream::process(const sample &left, const sample &right) { m_block_position++; } - cerr<<"num blocks: "<run(); +} + +block_stream::worker::worker(u32 id, window *w) : + m_id(id), + m_status(READY), + m_window(w) +{ + m_worker_mutex = new pthread_mutex_t; + pthread_mutex_init(m_worker_mutex,NULL); + m_thread = new pthread_t; + pthread_create(m_thread,NULL,(void*(*)(void*))_run_worker,this); +} + +void block_stream::worker::run() { + //cerr<<"worker "<m_worker_mutex)) { + if (w->m_status == worker::FINISHED) { + //cerr<<"adding finished block "<m_block_index<m_block_index]=*w->m_output; + w->m_status = worker::READY; + } + + if (w->m_status == worker::READY) { + w->m_region = region; + w->m_status = worker::ACTIVATE; + w->m_block_index = block_index; + return; + } + pthread_mutex_unlock(w->m_worker_mutex); + } + } + } +} + diff --git a/samplebrain/src/block_stream.h b/samplebrain/src/block_stream.h index 825c144..676351f 100644 --- a/samplebrain/src/block_stream.h +++ b/samplebrain/src/block_stream.h @@ -17,6 +17,7 @@ #include #include "window.h" #include "block.h" +#include "jellyfish/sample.h" #include "block_source.h" #ifndef BLOCK_STREAM @@ -39,10 +40,33 @@ class block_stream : public block_source { virtual const block &get_block(u32 index) const; virtual u32 get_num_blocks() const { return UINT_MAX; } - u32 last_block_index() const { return m_block_index_offset+m_blocks.size(); } + u32 last_block_index() const { return m_block_index_offset+m_blocks.size()-1; } + + class worker { + public: + worker(u32 id, window *w); + + enum worker_status { READY=0, ACTIVATE, WORKING, FINISHED }; + + void run(); + + u32 m_id; + worker_status m_status; + pthread_mutex_t* m_worker_mutex; + sample m_region; + block *m_output; + window *m_window; + u32 m_block_index; + + pthread_t *m_thread; + }; private: + void scatter_gather(u32 block_index, const sample ®ion); + + vector m_workers; + bool m_ready; u32 m_block_index; @@ -55,6 +79,10 @@ class block_stream : public block_source { u32 m_block_index_offset; vector m_blocks; + mutable s32 m_sent_block_index; + + block *m_dummy_block; + }; } diff --git a/samplebrain/src/jellyfish/command_ring_buffer.cpp b/samplebrain/src/jellyfish/command_ring_buffer.cpp index 1d4f547..f79d47a 100644 --- a/samplebrain/src/jellyfish/command_ring_buffer.cpp +++ b/samplebrain/src/jellyfish/command_ring_buffer.cpp @@ -22,57 +22,57 @@ using namespace std; command_ring_buffer::command::command(const char *name, const char *types, const char *data, unsigned int datasize) { - strcpy(m_name,name); - strcpy(m_types,types); - // already checking datasize fits in OSCserver.cpp - memcpy(m_data,data,datasize); + strcpy(m_name,name); + strcpy(m_types,types); + // already checking datasize fits in OSCserver.cpp + memcpy(m_data,data,datasize); - m_num_args=strlen(types); + m_num_args=strlen(types); - // figure out the offsets into the data to use later - int pos=0; - for(unsigned int i=0; idefaultLowOutputLatency; output_parameters.hostApiSpecificStreamInfo = NULL; + cerr<<"Connecting to "<name<<" for output"<defaultLowInputLatency; input_parameters.hostApiSpecificStreamInfo = NULL; + cerr<<"Connecting to "<name<<" for input"<m_size) return false; + //cerr<<"read pos: "<m_size) return false; - if (size read) return (read - write + m_size) & (m_size_mask - 1); - if (write < read) return (read - write) - 1; - return m_size - 1; + if (write > read) return (read - write + m_size) & (m_size_mask - 1); + if (write < read) return (read - write) - 1; + return m_size - 1; } unsigned int ring_buffer::read_space() { - unsigned int read = m_read_pos; - unsigned int write = m_write_pos; + unsigned int read = m_read_pos; + unsigned int write = m_write_pos; - if (write > read) return write - read; - else return (write - read + m_size) & m_size_mask; + if (write > read) return write - read; + else return (write - read + m_size) & m_size_mask; } diff --git a/samplebrain/src/jellyfish/ring_buffer.h b/samplebrain/src/jellyfish/ring_buffer.h index 0dbcddb..c3cdab4 100644 --- a/samplebrain/src/jellyfish/ring_buffer.h +++ b/samplebrain/src/jellyfish/ring_buffer.h @@ -22,25 +22,25 @@ class ring_buffer { -public: - ring_buffer(unsigned int size); - ~ring_buffer(); + public: + ring_buffer(unsigned int size); + ~ring_buffer(); - //bool lock(); - //bool unlock(); - bool write(char *src, unsigned int size); - bool read(char *dest, unsigned int size); - void dump(); + //bool lock(); + //bool unlock(); + bool write(char *src, unsigned int size); + bool read(char *dest, unsigned int size); + void dump(); -private: - unsigned int write_space(); - unsigned int read_space(); + private: + unsigned int write_space(); + unsigned int read_space(); - unsigned int m_read_pos; - unsigned int m_write_pos; - unsigned int m_size; - unsigned int m_size_mask; - char *m_buffer; + unsigned int m_read_pos; + unsigned int m_write_pos; + unsigned int m_size; + unsigned int m_size_mask; + char *m_buffer; }; #endif diff --git a/samplebrain/src/jellyfish/stream.cpp b/samplebrain/src/jellyfish/stream.cpp index e7c0eed..39c8354 100644 --- a/samplebrain/src/jellyfish/stream.cpp +++ b/samplebrain/src/jellyfish/stream.cpp @@ -26,8 +26,8 @@ template<>ios &spiralcore::operator||(ios &s, string &v) { ofstream *pos=dynamic_cast(&s); if (pos!=NULL) { ofstream &os = *pos; - size_t len = v.length(); - os.write((char *)&len,sizeof(size_t)); + u64 len = v.length(); + os.write((char *)&len,sizeof(u64)); os.write((char*)(v.c_str()),v.length()); return os; } @@ -36,8 +36,8 @@ template<>ios &spiralcore::operator||(ios &s, string &v) { ifstream *pis=dynamic_cast(&s); assert(pis!=NULL); ifstream &is = *pis; - size_t len=0; - is.read((char *)&len,sizeof(size_t)); + u64 len=0; + is.read((char *)&len,sizeof(u64)); if (len>0) { char *str = new char[len+1]; is.read(str,len); diff --git a/samplebrain/src/main.cpp b/samplebrain/src/main.cpp index 58be419..91ce2c9 100644 --- a/samplebrain/src/main.cpp +++ b/samplebrain/src/main.cpp @@ -25,6 +25,7 @@ #include "block.h" #include "brain.h" #include "renderer.h" +#include "block_stream.h" #include using namespace std; @@ -46,12 +47,23 @@ void unit_test() { } audio_device *a = NULL; +block_stream *m_block_stream = NULL; +bool m_mic_mode = true; void run_audio(void* c, unsigned int frames) { a->left_out.zero(); renderer *rr = (renderer*)c; pthread_mutex_lock(m_fuz_mutex); - rr->process(frames,a->left_out.get_non_const_buffer()); + + block_stream *bs=NULL; + + if (m_mic_mode) { + m_block_stream->process(a->left_in,a->right_in); + bs = m_block_stream; + } + + rr->process(frames,a->left_out.get_non_const_buffer(),bs); + pthread_mutex_unlock(m_fuz_mutex); a->right_out=a->left_out; a->maybe_record(); @@ -127,8 +139,15 @@ void fuz() { brain target; target.load_sound(fuz_samplefile(),brain::MIX); - u32 len=fuz_rr_i(500,5000); - target.init(len,len-len/fuz_rr_i(1,16),window::HANN); + // u32 len=fuz_rr_i(500,5000); + //u32 overlap = len-len/fuz_rr_i(1,16); + + u32 len=5000; + u32 overlap=len/2; + target.init(len,overlap,window::HANN); + + m_block_stream = new block_stream(); + m_block_stream->init(len,overlap,window::HANN); cerr<<"ready..."<start_recording("debug"); - a->m_client.set_callback(run_audio, &rr); - + a->m_client.set_callback(run_audio, &rr); + //target.resynth("shosta-dream-0.5.wav",source,0.5); u32 counter=0; @@ -199,6 +218,8 @@ int main(int argc, char *argv[]) { m_fuz_mutex = new pthread_mutex_t; pthread_mutex_init(m_fuz_mutex,NULL); - unit_test(); + //unit_test(); + + fuz(); } diff --git a/samplebrain/src/renderer.cpp b/samplebrain/src/renderer.cpp index bbcbedd..aa1cbfa 100644 --- a/samplebrain/src/renderer.cpp +++ b/samplebrain/src/renderer.cpp @@ -57,15 +57,14 @@ void renderer::process(u32 nframes, float *buf, const block_stream *bs) { // or the realtime block stream const block_source *source = (block_source*)bs; if (source==NULL) { - cerr<<"not using block stream..."<last_block_index()-10) { - cerr<<"catch up..."<last_block_index()-100)) { + //cerr<<"catch up... "<<(s32)m_target_index<<" "<<(s32)bs->last_block_index()<last_block_index(); } if (m_target_index>bs->last_block_index()) { - cerr<<"catch down..."<last_block_index(); } } @@ -106,7 +105,7 @@ bool renderer::find_render_blocks(const block_source &target, u32 nframes) { } - cerr<<"-----------------"<