diff options
Diffstat (limited to 'attic/muse2-oom/muse2/al')
-rw-r--r-- | attic/muse2-oom/muse2/al/CMakeLists.txt | 79 | ||||
-rw-r--r-- | attic/muse2-oom/muse2/al/al.cpp | 29 | ||||
-rw-r--r-- | attic/muse2-oom/muse2/al/al.h | 34 | ||||
-rw-r--r-- | attic/muse2-oom/muse2/al/dsp.cpp | 182 | ||||
-rw-r--r-- | attic/muse2-oom/muse2/al/dsp.h | 107 | ||||
-rw-r--r-- | attic/muse2-oom/muse2/al/dspSSE.cpp | 531 | ||||
-rw-r--r-- | attic/muse2-oom/muse2/al/dspXMM.cpp | 119 | ||||
-rw-r--r-- | attic/muse2-oom/muse2/al/sig.cpp | 617 | ||||
-rw-r--r-- | attic/muse2-oom/muse2/al/sig.h | 117 | ||||
-rw-r--r-- | attic/muse2-oom/muse2/al/xml.cpp | 366 | ||||
-rw-r--r-- | attic/muse2-oom/muse2/al/xml.h | 76 |
11 files changed, 2257 insertions, 0 deletions
diff --git a/attic/muse2-oom/muse2/al/CMakeLists.txt b/attic/muse2-oom/muse2/al/CMakeLists.txt new file mode 100644 index 00000000..a0031143 --- /dev/null +++ b/attic/muse2-oom/muse2/al/CMakeLists.txt @@ -0,0 +1,79 @@ +#============================================================================= +# MusE +# Linux Music Editor +# $Id:$ +# +# Copyright (C) 2002-2006 by Werner Schweer and others +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#============================================================================= + +include(${PROJECT_SOURCE_DIR}/pch.txt) + +## +## List of source files to compile +## +file (GLOB al_source_files + al.cpp + dsp.cpp + sig.cpp + xml.cpp + ) +if (USE_SSE) + file (GLOB al_source_files + ${al_source_files} + dspSSE.cpp + dspXMM.cpp + ) +endif (USE_SSE) + +## +## Define target +## +add_library(al SHARED + ${PROJECT_BINARY_DIR}/all.h.pch + ${al_source_files} + ) + +## +## Compilation flags and target name +## +set_target_properties( al + PROPERTIES OUTPUT_NAME muse_al + ) +set_source_files_properties( + al.cpp + dsp.cpp + dspXMM.cpp + sig.cpp + xml.cpp + PROPERTIES COMPILE_FLAGS "-fPIC -include ${PROJECT_BINARY_DIR}/all.h" + ) +set_source_files_properties( + dspSSE.cpp + PROPERTIES COMPILE_FLAGS "-x assembler" + ) + +## +## Linkage +## +target_link_libraries ( al + ${QT_LIBRARIES} + ) + +## +## Install location +## +install(TARGETS al + DESTINATION ${MusE_MODULES_DIR} + ) diff --git a/attic/muse2-oom/muse2/al/al.cpp b/attic/muse2-oom/muse2/al/al.cpp new file mode 100644 index 00000000..38cc301a --- /dev/null +++ b/attic/muse2-oom/muse2/al/al.cpp @@ -0,0 +1,29 @@ +//============================================================================= +// AL +// Audio Utility Library +// $Id: al.cpp,v 1.1.2.2 2009/12/06 01:39:33 terminator356 Exp $ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "al.h" + +namespace AL { + //int sampleRate = 44100; + //int mtcType = 0; + //int division = 384; + bool debugMsg = false; + }; + diff --git a/attic/muse2-oom/muse2/al/al.h b/attic/muse2-oom/muse2/al/al.h new file mode 100644 index 00000000..6f4a07cb --- /dev/null +++ b/attic/muse2-oom/muse2/al/al.h @@ -0,0 +1,34 @@ +//============================================================================= +// AL +// Audio Utility Library +// $Id: al.h,v 1.1.2.2 2009/12/06 01:39:33 terminator356 Exp $ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __AL_H__ +#define __AL_H__ + +namespace AL { + + extern bool debugMsg; + //extern int sampleRate; + //extern int mtcType; + //extern int division; + + } + +#endif + diff --git a/attic/muse2-oom/muse2/al/dsp.cpp b/attic/muse2-oom/muse2/al/dsp.cpp new file mode 100644 index 00000000..fa9fa18b --- /dev/null +++ b/attic/muse2-oom/muse2/al/dsp.cpp @@ -0,0 +1,182 @@ +//============================================================================= +// AL +// Audio Utility Library +// $Id: dsp.cpp,v 1.1.2.1 2009/12/06 01:39:33 terminator356 Exp $ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include <stdio.h> +#include <stdint.h> +#include "dsp.h" +#include "config.h" +#include "../globals.h" + +namespace AL { + +Dsp* dsp = 0; + +#ifdef __i386__ + +//--------------------------------------------------------- +// DspSSE86 +//--------------------------------------------------------- + +extern "C" { +extern float x86_sse_compute_peak(float*, unsigned, float); +extern void x86_sse_apply_gain_to_buffer(float*, unsigned, float); +extern void x86_sse_mix_buffers_with_gain(float*, float*, unsigned, float); +extern void x86_sse_mix_buffers_no_gain(float*, float*, unsigned); + }; + +class DspSSE86 : public Dsp { + public: + DspSSE86() {} + virtual ~DspSSE86() {} + + virtual float peak(float* buf, unsigned n, float current) { + if ( ((intptr_t)buf % 16) != 0) { + fprintf(stderr, "peak(): buffer unaligned! (%p)\n", buf); + return Dsp::peak(buf, n, current); + } + return x86_sse_compute_peak(buf, n, current); + } + + virtual void applyGainToBuffer(float* buf, unsigned n, float gain) { + if ( ((intptr_t)buf % 16) != 0) { + fprintf(stderr, "applyGainToBuffer(): buffer unaligned! (%p)\n", buf); + Dsp::applyGainToBuffer(buf, n, gain); + } + else + x86_sse_apply_gain_to_buffer(buf, n, gain); + } + + virtual void mixWithGain(float* dst, float* src, unsigned n, float gain) { + if ( ((intptr_t)dst & 15) != 0) + fprintf(stderr, "mixWithGainain(): dst unaligned! (%p)\n", dst); + if (((intptr_t)dst & 15) != ((intptr_t)src & 15) ) { + fprintf(stderr, "mixWithGain(): dst & src don't have the same alignment!\n"); + Dsp::mixWithGain(dst, src,n, gain); + } + else + x86_sse_mix_buffers_with_gain(dst, src, n, gain); + } + virtual void mix(float* dst, float* src, unsigned n) { + if ( ((intptr_t)dst & 15) != 0) + fprintf(stderr, "mix_buffers_no_gain(): dst unaligned! %p\n", dst); + if ( ((intptr_t)dst & 15) != ((intptr_t)src & 15) ) { + fprintf(stderr, "mix_buffers_no_gain(): dst & src don't have the same alignment!\n"); + Dsp::mix(dst, src, n); + } + else + x86_sse_mix_buffers_no_gain(dst, src, n); + } + }; +#endif + +//--------------------------------------------------------- +// initDsp +//--------------------------------------------------------- + +void initDsp() + { +#if 0 // Disabled for now. +#if defined(__i386__) || defined(__x86_64__) + if(debugMsg) + printf("Muse: __i386__ or __x86_64__ defined. Using optimized float buffer copying (asm movsl).\n"); +#else + if(debugMsg) + printf("Muse: __i386__ or __x86_64__ not defined. Using non-optimized memcpy for float buffer copying.\n"); +#endif +#endif + +#if defined(__i386__) && defined(USE_SSE) + unsigned long useSSE = 0; + if(debugMsg) + printf("initDsp: __i386__ and USE_SSE defined\n"); + +// FIXME: 64? Shouldn't these routines work on 32 bit? +#ifdef __x86_64__ + useSSE = 1 << 25; // we know the platform has SSE + if(debugMsg) + printf("initDsp: __x86_64__ defined\n"); +#else + if(debugMsg) + printf("initDsp: getting cpuid via asm\n"); + asm ( + "mov $1, %%eax\n" + "pushl %%ebx\n" + "cpuid\n" + "movl %%edx, %0\n" + "popl %%ebx\n" + : "=r" (useSSE) + : + : "%eax", "%ecx", "%edx", "memory"); +#endif + if(debugMsg) + printf("initDsp: checking for bit 25 SSE support:%lX\n", useSSE); + useSSE &= (1 << 25); // bit 25 = SSE support + if (useSSE) { + printf("Using SSE optimized routines\n"); + dsp = new DspSSE86(); + return; + } + // fall through to not hardware optimized routines +#endif + if(debugMsg) + printf("Muse: using unoptimized non-SSE dsp routines\n"); + dsp = new Dsp(); + } + +//--------------------------------------------------------- +// exitDsp +//--------------------------------------------------------- + +void exitDsp() +{ + if(dsp) + delete dsp; + dsp = 0; +} + +void Dsp::cpy(float* dst, float* src, unsigned n) +{ +// FIXME: Changed by T356. Not defined. Where are these??? +//#if defined(ARCH_X86) || defined(ARCH_X86_64) +///#if defined(__i386__) || defined(__x86_64__) +#if 0 // Disabled for now. + //printf("Dsp: using asm cpy\n"); + // Changed by T356. Get To and From not declared in scope compile errors. + //register unsigned long int dummy; + //__asm__ __volatile__ ("rep; movsl" :"=&D"(dst), "=&S"(src), "=&c"(dummy) :"0" (to), "1" (from),"2" (n) : "memory"); + // FIXME: FIXME: I don't think this is correct but it works so far... + // Tried clobbering, get "Can't find a register in class `CREG' while reloading `asm'" + __asm__ __volatile__ ( + "cld\n\t" + "rep\n\t" + "movsl" + : + : "S" (src), "D" (dst), "c" (n) + : "memory" + ); + + //: "%ecx", "%esi", "%edi", "memory" +#else + //printf("Dsp: using memcpy\n"); + memcpy(dst, src, sizeof(float) * n); +#endif +} + +} // namespace AL diff --git a/attic/muse2-oom/muse2/al/dsp.h b/attic/muse2-oom/muse2/al/dsp.h new file mode 100644 index 00000000..f88a0122 --- /dev/null +++ b/attic/muse2-oom/muse2/al/dsp.h @@ -0,0 +1,107 @@ +//============================================================================= +// AL +// Audio Utility Library +// $Id: dsp.h,v 1.1.2.1 2009/12/06 01:39:33 terminator356 Exp $ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __DSP_H__ +#define __DSP_H__ + +#include <string.h> +#include <math.h> + +namespace AL { + +//--------------------------------------------------------- +// f_max +//--------------------------------------------------------- + +static inline float f_max(float x, float a) + { + x -= a; + x += fabsf(x); + x *= 0.5f; + x += a; + return x; + } + +//--------------------------------------------------------- +// Dsp +// standard version of all dsp routines without any +// hw acceleration +//--------------------------------------------------------- + +class Dsp { + public: + Dsp() {} + virtual ~Dsp() {} + + virtual float peak(float* buf, unsigned n, float current) { + for (unsigned i = 0; i < n; ++i) + current = f_max(current, fabsf(buf[i])); + return current; + } + virtual void applyGainToBuffer(float* buf, unsigned n, float gain) { + for (unsigned i = 0; i < n; ++i) + buf[i] *= gain; + } + virtual void mixWithGain(float* dst, float* src, unsigned n, float gain) { + for (unsigned i = 0; i < n; ++i) + dst[i] += src[i] * gain; + } + virtual void mix(float* dst, float* src, unsigned n) { + for (unsigned i = 0; i < n; ++i) + dst[i] += src[i]; + } + virtual void cpy(float* dst, float* src, unsigned n); +/* + { +// Changed by T356. Not defined. Where are these??? +//#if defined(ARCH_X86) || defined(ARCH_X86_64) +#if defined(__i386__) || defined(__x86_64__) + printf("Dsp: using asm cpy\n"); + // Changed by T356. Get To and From not declared in scope compile errors. + register unsigned long int dummy; + //__asm__ __volatile__ ("rep; movsl" :"=&D"(dst), "=&S"(src), "=&c"(dummy) :"0" (to), "1" (from),"2" (n) : "memory"); + // From http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html + __asm__ __volatile__ ( \ + "cld\n\t" \ + "rep\n\t" \ + "movsl" \ + : \ + : "S" (src), "D" (dst), "c" (n) \ + : "memory" + ); + + //: "%ecx", "%esi", "%edi", "memory" +#else + printf("Dsp: using memcpy\n"); + memcpy(dst, src, sizeof(float) * n); +#endif + } +*/ + + }; + +extern void initDsp(); +extern void exitDsp(); +extern Dsp* dsp; + +} + +#endif + diff --git a/attic/muse2-oom/muse2/al/dspSSE.cpp b/attic/muse2-oom/muse2/al/dspSSE.cpp new file mode 100644 index 00000000..a345e308 --- /dev/null +++ b/attic/muse2-oom/muse2/al/dspSSE.cpp @@ -0,0 +1,531 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: dspSSE.cpp,v 1.1.2.3 2009/12/20 00:04:25 spamatica Exp $ +// +// (C) Copyright 2007-2009 Werner Schweer (ws@seh.de) +// file originally from Ardour DAW project by Paul Davis (c) 2005 +// licensed through GPL +// Original author Sampo Savolainen +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//====================================================================== + +#; void x86_sse_mix_buffers_with_gain (float *dst, float *src, long nframes, float gain); + +.globl x86_sse_mix_buffers_with_gain + .type x86_sse_mix_buffers_with_gain,@function + +x86_sse_mix_buffers_with_gain: +#; 8(%ebp) = float *dst = %edi +#; 12(%ebp) = float *src = %esi +#; 16(%ebp) = long nframes = %ecx +#; 20(%ebp) = float gain = st(0) + + pushl %ebp + movl %esp, %ebp + + #; save the registers +#; pushl %eax + pushl %ebx +#; pushl %ecx + pushl %edi + pushl %esi + + #; if nframes == 0, go to end + movl 16(%ebp), %ecx #; nframes + cmp $0, %ecx + je .MBWG_END + + #; Check for alignment + + movl 8(%ebp), %edi #; dst + movl 12(%ebp), %esi #; src + + movl %edi, %eax + andl $12, %eax #; mask alignemnt offset + + movl %esi, %ebx + andl $12, %ebx #; mask alignment offset + + cmp %eax, %ebx + jne .MBWG_NONALIGN #; if not aligned, calculate manually + + #; if we are aligned + cmp $0, %ebx + jz .MBWG_SSE + + #; Pre-loop, we need to run 1-3 frames "manually" without + #; SSE instructions + + movss 20(%ebp), %xmm1 #; xmm1 + +.MBWG_PRELOOP: + + movss (%esi), %xmm0 + mulss %xmm1, %xmm0 + addss (%edi), %xmm0 + movss %xmm0, (%edi) + + addl $4, %edi #; dst++ + addl $4, %esi #; src++ + decl %ecx #; nframes-- + jz .MBWG_END + +#; cmp $0, %ecx +#; je .MBWG_END #; if we run out of frames, go to end + + addl $4, %ebx + + cmp $16, %ebx #; test if we've reached 16 byte alignment + jne .MBWG_PRELOOP + + +.MBWG_SSE: + + cmp $4, %ecx #; we know it's not zero, but if it's not >=4, then + jnge .MBWG_NONALIGN #; we jump straight to the "normal" code + + #; copy gain to fill %xmm1 + movss 20(%ebp), %xmm1 + shufps $0x00, %xmm1, %xmm1 + + +.MBWG_SSELOOP: + + movaps (%esi), %xmm0 #; source => xmm0 + mulps %xmm1, %xmm0 #; apply gain to source + addps (%edi), %xmm0 #; mix with destination + movaps %xmm0, (%edi) #; copy result to destination + + addl $16, %edi #; dst+=4 + addl $16, %esi #; src+=4 + + subl $4, %ecx #; nframes-=4 + cmp $4, %ecx + jge .MBWG_SSELOOP + + cmp $0, %ecx + je .MBWG_END + + #; if there are remaining frames, the nonalign code will do nicely + #; for the rest 1-3 frames. + +.MBWG_NONALIGN: + #; not aligned! + + movss 20(%ebp), %xmm1 #; gain => xmm1 + +.MBWG_NONALIGNLOOP: + + movss (%esi), %xmm0 + mulss %xmm1, %xmm0 + addss (%edi), %xmm0 + movss %xmm0, (%edi) + + addl $4, %edi + addl $4, %esi + + decl %ecx + jnz .MBWG_NONALIGNLOOP + +.MBWG_END: + + popl %esi + popl %edi +#; popl %ecx + popl %ebx +#; popl %eax + + #; return + leave + ret + +.size x86_sse_mix_buffers_with_gain, .-x86_sse_mix_buffers_with_gain + + + + +#; void x86_sse_mix_buffers_no_gain (float *dst, float *src, long nframes); + +.globl x86_sse_mix_buffers_no_gain + .type x86_sse_mix_buffers_no_gain,@function + +x86_sse_mix_buffers_no_gain: +#; 8(%ebp) = float *dst = %edi +#; 12(%ebp) = float *src = %esi +#; 16(%ebp) = long nframes = %ecx + + pushl %ebp + movl %esp, %ebp + + #; save the registers +#; pushl %eax + pushl %ebx +#; pushl %ecx + pushl %edi + pushl %esi + + #; the real function + + #; if nframes == 0, go to end + movl 16(%ebp), %ecx #; nframes + cmp $0, %ecx + je .MBNG_END + + #; Check for alignment + + movl 8(%ebp), %edi #; dst + movl 12(%ebp), %esi #; src + + movl %edi, %eax + andl $12, %eax #; mask alignemnt offset + + movl %esi, %ebx + andl $12, %ebx #; mask alignment offset + + cmp %eax, %ebx + jne .MBNG_NONALIGN #; if not aligned, calculate manually + + cmp $0, %ebx + je .MBNG_SSE + + #; Pre-loop, we need to run 1-3 frames "manually" without + #; SSE instructions + +.MBNG_PRELOOP: + + movss (%esi), %xmm0 + addss (%edi), %xmm0 + movss %xmm0, (%edi) + + addl $4, %edi #; dst++ + addl $4, %esi #; src++ + decl %ecx #; nframes-- + jz .MBNG_END + addl $4, %ebx + + cmp $16, %ebx #; test if we've reached 16 byte alignment + jne .MBNG_PRELOOP + +.MBNG_SSE: + + cmp $4, %ecx #; if there are frames left, but less than 4 + jnge .MBNG_NONALIGN #; we can't run SSE + +.MBNG_SSELOOP: + + movaps (%esi), %xmm0 #; source => xmm0 + addps (%edi), %xmm0 #; mix with destination + movaps %xmm0, (%edi) #; copy result to destination + + addl $16, %edi #; dst+=4 + addl $16, %esi #; src+=4 + + subl $4, %ecx #; nframes-=4 + cmp $4, %ecx + jge .MBNG_SSELOOP + + cmp $0, %ecx + je .MBNG_END + + #; if there are remaining frames, the nonalign code will do nicely + #; for the rest 1-3 frames. + +.MBNG_NONALIGN: + #; not aligned! + + movss (%esi), %xmm0 #; src => xmm0 + addss (%edi), %xmm0 #; xmm0 += dst + movss %xmm0, (%edi) #; xmm0 => dst + + addl $4, %edi + addl $4, %esi + + decl %ecx + jnz .MBNG_NONALIGN + +.MBNG_END: + + popl %esi + popl %edi +#; popl %ecx + popl %ebx +#; popl %eax + + #; return + leave + ret + +.size x86_sse_mix_buffers_no_gain, .-x86_sse_mix_buffers_no_gain + + + + +#; void x86_sse_apply_gain_to_buffer (float *buf, long nframes, float gain); + +.globl x86_sse_apply_gain_to_buffer + .type x86_sse_apply_gain_to_buffer,@function + +x86_sse_apply_gain_to_buffer: +#; 8(%ebp) = float *buf = %edi +#; 12(%ebp) = long nframes = %ecx +#; 16(%ebp) = float gain = st(0) + + pushl %ebp + movl %esp, %ebp + + #; save %edi + pushl %edi + + #; the real function + + #; if nframes == 0, go to end + movl 12(%ebp), %ecx #; nframes + cmp $0, %ecx + je .AG_END + + #; create the gain buffer in %xmm1 + movss 16(%ebp), %xmm1 + shufps $0x00, %xmm1, %xmm1 + + #; Check for alignment + + movl 8(%ebp), %edi #; buf + movl %edi, %edx #; buf => %edx + andl $12, %edx #; mask bits 1 & 2, result = 0, 4, 8 or 12 + jz .AG_SSE #; if buffer IS aligned + + #; PRE-LOOP + #; we iterate 1-3 times, doing normal x87 float comparison + #; so we reach a 16 byte aligned "buf" (=%edi) value + +.AGLP_START: + + #; Load next value from the buffer + movss (%edi), %xmm0 + mulss %xmm1, %xmm0 + movss %xmm0, (%edi) + + #; increment buffer, decrement counter + addl $4, %edi #; buf++; + + decl %ecx #; nframes-- + jz .AG_END #; if we run out of frames, we go to the end + + addl $4, %edx #; one non-aligned byte less + cmp $16, %edx + jne .AGLP_START #; if more non-aligned frames exist, we do a do-over + +.AG_SSE: + + #; We have reached the 16 byte aligned "buf" ("edi") value + + #; Figure out how many loops we should do + movl %ecx, %eax #; copy remaining nframes to %eax for division + movl $0, %edx #; 0 the edx register + + + pushl %edi + movl $4, %edi + divl %edi #; %edx = remainder == 0 + popl %edi + + #; %eax = SSE iterations + cmp $0, %eax + je .AGPOST_START + + +.AGLP_SSE: + + movaps (%edi), %xmm0 + mulps %xmm1, %xmm0 + movaps %xmm0, (%edi) + + addl $16, %edi +#; subl $4, %ecx #; nframes-=4 + + decl %eax + jnz .AGLP_SSE + + #; Next we need to post-process all remaining frames + #; the remaining frame count is in %ecx + + #; if no remaining frames, jump to the end +#; cmp $0, %ecx + andl $3, %ecx #; nframes % 4 + je .AG_END + +.AGPOST_START: + + movss (%edi), %xmm0 + mulss %xmm1, %xmm0 + movss %xmm0, (%edi) + + #; increment buffer, decrement counter + addl $4, %edi #; buf++; + + decl %ecx #; nframes-- + jnz .AGPOST_START #; if we run out of frames, we go to the end + +.AG_END: + + + popl %edi + + #; return + leave + ret + +.size x86_sse_apply_gain_to_buffer, .-x86_sse_apply_gain_to_buffer +#; end proc + + + +#; float x86_sse_compute_peak(float *buf, long nframes, float current); + +.globl x86_sse_compute_peak + .type x86_sse_compute_peak,@function + +x86_sse_compute_peak: +#; 8(%ebp) = float *buf = %edi +#; 12(%ebp) = long nframes = %ecx +#; 16(%ebp) = float current = st(0) + + pushl %ebp + movl %esp, %ebp + + #; save %edi + pushl %edi + + #; the real function + + #; Load "current" in xmm0 + movss 16(%ebp), %xmm0 + + #; if nframes == 0, go to end + movl 12(%ebp), %ecx #; nframes + cmp $0, %ecx + je .CP_END + + #; create the "abs" mask in %xmm2 + pushl $2147483647 + movss (%esp), %xmm2 + addl $4, %esp + shufps $0x00, %xmm2, %xmm2 + + #; Check for alignment + + movl 8(%ebp), %edi #; buf + movl %edi, %edx #; buf => %edx + andl $12, %edx #; mask bits 1 & 2, result = 0, 4, 8 or 12 + jz .CP_SSE #; if buffer IS aligned + + #; PRE-LOOP + #; we iterate 1-3 times, doing normal x87 float comparison + #; so we reach a 16 byte aligned "buf" (=%edi) value + +.LP_START: + + #; Load next value from the buffer + movss (%edi), %xmm1 + andps %xmm2, %xmm1 + maxss %xmm1, %xmm0 + + #; increment buffer, decrement counter + addl $4, %edi #; buf++; + + decl %ecx #; nframes-- + jz .CP_END #; if we run out of frames, we go to the end + + addl $4, %edx #; one non-aligned byte less + cmp $16, %edx + jne .LP_START #; if more non-aligned frames exist, we do a do-over + +.CP_SSE: + + #; We have reached the 16 byte aligned "buf" ("edi") value + + #; Figure out how many loops we should do + movl %ecx, %eax #; copy remaining nframes to %eax for division + + shr $2,%eax #; unsigned divide by 4 + jz .POST_START + + #; %eax = SSE iterations + + #; current maximum is at %xmm0, but we need to .. + shufps $0x00, %xmm0, %xmm0 #; shuffle "current" to all 4 FP's + + #;prefetcht0 16(%edi) + +.LP_SSE: + + movaps (%edi), %xmm1 + andps %xmm2, %xmm1 + maxps %xmm1, %xmm0 + + addl $16, %edi + + decl %eax + jnz .LP_SSE + + #; Calculate the maximum value contained in the 4 FP's in %xmm0 + movaps %xmm0, %xmm1 + shufps $0x4e, %xmm1, %xmm1 #; shuffle left & right pairs (1234 => 3412) + maxps %xmm1, %xmm0 #; maximums of the two pairs + movaps %xmm0, %xmm1 + shufps $0xb1, %xmm1, %xmm1 #; shuffle the floats inside the two pairs (1234 => 2143) + maxps %xmm1, %xmm0 + + #; now every float in %xmm0 is the same value, current maximum value + + #; Next we need to post-process all remaining frames + #; the remaining frame count is in %ecx + + #; if no remaining frames, jump to the end + + andl $3, %ecx #; nframes % 4 + jz .CP_END + +.POST_START: + + movss (%edi), %xmm1 + andps %xmm2, %xmm1 + maxss %xmm1, %xmm0 + + addl $4, %edi #; buf++; + + decl %ecx #; nframes--; + jnz .POST_START + +.CP_END: + + #; Load the value from xmm0 to the float stack for returning + movss %xmm0, 16(%ebp) + flds 16(%ebp) + + popl %edi + + #; return + leave + ret + +.size x86_sse_compute_peak, .-x86_sse_compute_peak +#; end proc + +#ifdef __ELF__ +.section .note.GNU-stack,"",%progbits +#endif + + diff --git a/attic/muse2-oom/muse2/al/dspXMM.cpp b/attic/muse2-oom/muse2/al/dspXMM.cpp new file mode 100644 index 00000000..99893c3f --- /dev/null +++ b/attic/muse2-oom/muse2/al/dspXMM.cpp @@ -0,0 +1,119 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: dspXMM.cpp,v 1.1.2.2 2009/12/20 00:04:25 spamatica Exp $ +// +// (C) Copyright 2007-2009 Werner Schweer (ws@seh.de) +// file originally from Ardour DAW project by Paul Davis (c) 2007 +// licensed through GPL +// Original author Sampo Savolainen +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//====================================================================== + + +#include <xmmintrin.h> + +void +x86_sse_find_peaks(float *buf, unsigned nframes, float *min, float *max) +{ + __m128 current_max, current_min, work; + + // Load max and min values into all four slots of the XMM registers + current_min = _mm_set1_ps(*min); + current_max = _mm_set1_ps(*max); + + // Work input until "buf" reaches 16 byte alignment + while ( ((unsigned long)buf) % 16 != 0 && nframes > 0) { + + // Load the next float into the work buffer + work = _mm_set1_ps(*buf); + + current_min = _mm_min_ps(current_min, work); + current_max = _mm_max_ps(current_max, work); + + buf++; + nframes--; + } + + // use 64 byte prefetch for quadruple quads + while (nframes >= 16) { + __builtin_prefetch(buf+64,0,0); + + work = _mm_load_ps(buf); + current_min = _mm_min_ps(current_min, work); + current_max = _mm_max_ps(current_max, work); + buf+=4; + work = _mm_load_ps(buf); + current_min = _mm_min_ps(current_min, work); + current_max = _mm_max_ps(current_max, work); + buf+=4; + work = _mm_load_ps(buf); + current_min = _mm_min_ps(current_min, work); + current_max = _mm_max_ps(current_max, work); + buf+=4; + work = _mm_load_ps(buf); + current_min = _mm_min_ps(current_min, work); + current_max = _mm_max_ps(current_max, work); + buf+=4; + nframes-=16; + } + + // work through aligned buffers + while (nframes >= 4) { + + work = _mm_load_ps(buf); + + current_min = _mm_min_ps(current_min, work); + current_max = _mm_max_ps(current_max, work); + + buf+=4; + nframes-=4; + } + + // work through the rest < 4 samples + while ( nframes > 0) { + + // Load the next float into the work buffer + work = _mm_set1_ps(*buf); + + current_min = _mm_min_ps(current_min, work); + current_max = _mm_max_ps(current_max, work); + + buf++; + nframes--; + } + + // Find min & max value in current_max through shuffle tricks + + work = current_min; + work = _mm_shuffle_ps(work, work, _MM_SHUFFLE(2, 3, 0, 1)); + work = _mm_min_ps (work, current_min); + current_min = work; + work = _mm_shuffle_ps(work, work, _MM_SHUFFLE(1, 0, 3, 2)); + work = _mm_min_ps (work, current_min); + + _mm_store_ss(min, work); + + work = current_max; + work = _mm_shuffle_ps(work, work, _MM_SHUFFLE(2, 3, 0, 1)); + work = _mm_max_ps (work, current_max); + current_max = work; + work = _mm_shuffle_ps(work, work, _MM_SHUFFLE(1, 0, 3, 2)); + work = _mm_max_ps (work, current_max); + + _mm_store_ss(max, work); +} + + + diff --git a/attic/muse2-oom/muse2/al/sig.cpp b/attic/muse2-oom/muse2/al/sig.cpp new file mode 100644 index 00000000..7eeae6be --- /dev/null +++ b/attic/muse2-oom/muse2/al/sig.cpp @@ -0,0 +1,617 @@ +//============================================================================= +// AL +// Audio Utility Library +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + + +///#include "al.h" +#include "gconfig.h" // Tim +#include "sig.h" +///#include "xml.h" + + +namespace AL { + +SigList sigmap; + +//--------------------------------------------------------- +// isValid +//--------------------------------------------------------- + +bool TimeSignature::isValid() const +{ + if((z < 1) || (z > 63)) + return false; + + switch(n) + { + case 1: + case 2: + case 3: + case 4: + case 8: + case 16: + case 32: + case 64: + case 128: + return true; + default: + return false; + } +} + +//--------------------------------------------------------- +// SigList +//--------------------------------------------------------- + +SigList::SigList() + { + insert(std::pair<const unsigned, SigEvent*> (MAX_TICK, new SigEvent(TimeSignature(4, 4), 0))); + } + +//--------------------------------------------------------- +// add +// signatures are only allowed at the beginning of +// a bar +//--------------------------------------------------------- + +void SigList::add(unsigned tick, const TimeSignature& s) + { + if (s.z == 0 || s.n == 0) { + printf("illegal signature %d/%d\n", s.z, s.n); + // Added by Tim. + return; + } + tick = raster1(tick, 0); + iSigEvent e = upper_bound(tick); + if(e == end()) + { + printf("SigList::add Signal not found tick:%d\n", tick); + return; + } + + if (tick == e->second->tick) { + e->second->sig = s; + } + else { + SigEvent* ne = e->second; + SigEvent* ev = new SigEvent(ne->sig, ne->tick); + ne->sig = s; + ne->tick = tick; + insert(std::pair<const unsigned, SigEvent*> (tick, ev)); + } + normalize(); + } + +/* +void SigList::add(unsigned tick, int z, int n) + { + if (z == 0 || n == 0) { + printf("SigList::add illegal signature %d/%d\n", z, n); + // Added by Tim. + return; + } + tick = raster1(tick, 0); + iSigEvent e = upper_bound(tick); + if(e == end()) + { + printf("SigList::add Signal not found tick:%d\n", tick); + return; + } + + if (tick == e->second->tick) { + e->second->sig.z = z; + e->second->sig.n = n; + } + else { + SigEvent* ne = e->second; + SigEvent* ev = new SigEvent(ne->sig.z, ne->sig.n, ne->tick); + ne->sig.z = z; + ne->sig.n = n; + ne->tick = tick; + insert(std::pair<const unsigned, SigEvent*> (tick, ev)); + } + normalize(); + } +*/ + +//--------------------------------------------------------- +// del +//--------------------------------------------------------- + +void SigList::del(unsigned tick) + { +// printf("SigList::del(%d)\n", tick); + iSigEvent e = find(tick); + if (e == end()) { + printf("SigList::del(%d): not found\n", tick); + return; + } + iSigEvent ne = e; + ++ne; + if (ne == end()) { + printf("SigList::del() next event not found!\n"); + return; + } + ne->second->sig = e->second->sig; + ne->second->tick = e->second->tick; + erase(e); + normalize(); + } + +//--------------------------------------------------------- +// SigList::normalize +//--------------------------------------------------------- + +void SigList::normalize() + { + TimeSignature sig(0, 0); + unsigned tick = 0; + iSigEvent ee; + + for (iSigEvent e = begin(); e != end();) { + if (sig.z == e->second->sig.z && sig.n == e->second->sig.n) { + e->second->tick = tick; + erase(ee); + } + sig = e->second->sig; + ee = e; + tick = e->second->tick; + ++e; + } + + int bar = 0; + for (iSigEvent e = begin(); e != end();) { + e->second->bar = bar; + int delta = e->first - e->second->tick; + int ticksB = ticks_beat(e->second->sig.n); + int ticksM = ticksB * e->second->sig.z; + bar += delta / ticksM; + if (delta % ticksM) // Teil eines Taktes + ++bar; + ++e; + } + } + +//--------------------------------------------------------- +// SigList::dump +//--------------------------------------------------------- + +void SigList::dump() const + { + printf("\nSigList:\n"); + for (ciSigEvent i = begin(); i != end(); ++i) { + printf("%6d %06d Bar %3d %02d/%d\n", + i->first, i->second->tick, + i->second->bar, i->second->sig.z, i->second->sig.n); + } + } + +void SigList::clear() + { + for (iSigEvent i = begin(); i != end(); ++i) + delete i->second; + SIGLIST::clear(); + insert(std::pair<const unsigned, SigEvent*> (MAX_TICK, new SigEvent(TimeSignature(4, 4), 0))); + } + +//--------------------------------------------------------- +// ticksMeasure +//--------------------------------------------------------- + +int SigList::ticksMeasure(const TimeSignature& sig) const + { + return ticks_beat(sig.n) * sig.z; + } + +int SigList::ticksMeasure(int Z, int N) const + { + return ticks_beat(N) * Z; + } + +int SigList::ticksMeasure(unsigned tick) const + { + ciSigEvent i = upper_bound(tick); + if (i == end()) { + printf("ticksMeasure: not found %d\n", tick); + // abort(); + return 0; + } + return ticksMeasure(i->second->sig); + } + +//--------------------------------------------------------- +// ticksBeat +//--------------------------------------------------------- + +int SigList::ticksBeat(unsigned tick) const + { + ciSigEvent i = upper_bound(tick); + if(i == end()) + { + printf("SigList::ticksBeat event not found! tick:%d\n", tick); + return 0; + } + return ticks_beat(i->second->sig.n); + } + +int SigList::ticks_beat(int n) const + { + + ///int m = AL::division; + int m = config.division; + + switch (n) { + case 1: m <<= 2; break; // 1536 + case 2: m <<= 1; break; // 768 + case 3: m += m >> 1; break; // 384+192 + case 4: break; // 384 + case 8: m >>= 1; break; // 192 + case 16: m >>= 2; break; // 96 + case 32: m >>= 3; break; // 48 + case 64: m >>= 4; break; // 24 + case 128: m >>= 5; break; // 12 + default: break; + } + return m; + } + +//--------------------------------------------------------- +// timesig +//--------------------------------------------------------- + +TimeSignature SigList::timesig(unsigned tick) const + { + ciSigEvent i = upper_bound(tick); + if (i == end()) { + printf("timesig(%d): not found\n", tick); + // abort(); + return TimeSignature(4,4); + } + return i->second->sig; + } + +void SigList::timesig(unsigned tick, int& z, int& n) const + { + ciSigEvent i = upper_bound(tick); + if (i == end()) { + printf("timesig(%d): not found\n", tick); + // abort(); + z = 4; + n = 4; + } + else { + z = i->second->sig.z; + n = i->second->sig.n; + } + } + +//--------------------------------------------------------- +// tickValues +//--------------------------------------------------------- + +void SigList::tickValues(unsigned t, int* bar, int* beat, unsigned* tick) const + { + ciSigEvent e = upper_bound(t); + if (e == end()) { + fprintf(stderr, "tickValues(0x%x) not found(%zd)\n", t, size()); + *bar = 0; + *beat = 0; + *tick = 0; + return; + } + + int delta = t - e->second->tick; + int ticksB = ticks_beat(e->second->sig.n); + int ticksM = ticksB * e->second->sig.z; + *bar = e->second->bar + delta / ticksM; + int rest = delta % ticksM; + *beat = rest / ticksB; + *tick = rest % ticksB; + } + +//--------------------------------------------------------- +// bar2tick +//--------------------------------------------------------- + +unsigned SigList::bar2tick(int bar, int beat, unsigned tick) const + { + ciSigEvent e; + + if (bar < 0) + bar = 0; + for (e = begin(); e != end();) { + ciSigEvent ee = e; + ++ee; + if (ee == end()) + break; + if (bar < ee->second->bar) + break; + e = ee; + } + int ticksB = ticks_beat(e->second->sig.n); + int ticksM = ticksB * e->second->sig.z; + return e->second->tick + (bar-e->second->bar)*ticksM + ticksB*beat + tick; + } + +//--------------------------------------------------------- +// raster +//--------------------------------------------------------- + +unsigned SigList::raster(unsigned t, int raster) const + { + if (raster == 1) + return t; + ciSigEvent e = upper_bound(t); + if (e == end()) { + printf("SigList::raster(%x,)\n", t); + // abort(); + return t; + } + int delta = t - e->second->tick; + int ticksM = ticks_beat(e->second->sig.n) * e->second->sig.z; + if (raster == 0) + raster = ticksM; + int rest = delta % ticksM; + int bb = (delta/ticksM)*ticksM; + return e->second->tick + bb + ((rest + raster/2)/raster)*raster; + } + +//--------------------------------------------------------- +// raster1 +// round down +//--------------------------------------------------------- + +unsigned SigList::raster1(unsigned t, int raster) const + { + if (raster == 1) + return t; + ciSigEvent e = upper_bound(t); + if(e == end()) + { + printf("SigList::raster1 event not found tick:%d\n", t); + //return 0; + return t; + } + + int delta = t - e->second->tick; + int ticksM = ticks_beat(e->second->sig.n) * e->second->sig.z; + if (raster == 0) + raster = ticksM; + int rest = delta % ticksM; + int bb = (delta/ticksM)*ticksM; + return e->second->tick + bb + (rest/raster)*raster; + } + +//--------------------------------------------------------- +// raster2 +// round up +//--------------------------------------------------------- + +unsigned SigList::raster2(unsigned t, int raster) const + { + if (raster == 1) + return t; + ciSigEvent e = upper_bound(t); + if(e == end()) + { + printf("SigList::raster2 event not found tick:%d\n", t); + //return 0; + return t; + } + + int delta = t - e->second->tick; + int ticksM = ticks_beat(e->second->sig.n) * e->second->sig.z; + if (raster == 0) + raster = ticksM; + int rest = delta % ticksM; + int bb = (delta/ticksM)*ticksM; + return e->second->tick + bb + ((rest+raster-1)/raster)*raster; + } + +//--------------------------------------------------------- +// rasterStep +//--------------------------------------------------------- + +int SigList::rasterStep(unsigned t, int raster) const + { + if (raster == 0) { + ciSigEvent e = upper_bound(t); + if(e == end()) + { + printf("SigList::rasterStep event not found tick:%d\n", t); + //return 0; + return raster; + } + + return ticks_beat(e->second->sig.n) * e->second->sig.z; + } + return raster; + } + +//--------------------------------------------------------- +// SigList::write +//--------------------------------------------------------- + +#if 0 +void SigList::write(Xml& xml) const + { + xml.stag("siglist"); + for (ciSigEvent i = begin(); i != end(); ++i) + i->second->write(xml, i->first); + xml.etag("siglist"); + } +#endif + +void SigList::write(int level, Xml& xml) const + { + xml.tag(level++, "siglist"); + for (ciSigEvent i = begin(); i != end(); ++i) + i->second->write(level, xml, i->first); + xml.tag(level, "/siglist"); + } + +//--------------------------------------------------------- +// SigList::read +//--------------------------------------------------------- + +#if 0 +void SigList::read(QDomNode node) + { + while (!node.isNull()) { + QDomElement e = node.toElement(); + if (e.tagName() == "sig") { + SigEvent* t = new SigEvent(); + unsigned tick = t->read(node); + iSigEvent pos = find(tick); + if (pos != end()) + erase(pos); + insert(std::pair<const unsigned, SigEvent*> (tick, t)); + } + else + printf("MusE:SigList: unknown tag %s\n", e.tagName().toLatin1().constData()); + node = node.nextSibling(); + } + normalize(); + } +#endif + +void SigList::read(Xml& xml) + { + for (;;) { + Xml::Token token = xml.parse(); + const QString& tag = xml.s1(); + switch (token) { + case Xml::Error: + case Xml::End: + return; + case Xml::TagStart: + if (tag == "sig") { + SigEvent* t = new SigEvent(); + unsigned tick = t->read(xml); + iSigEvent pos = find(tick); + if (pos != end()) + erase(pos); + insert(std::pair<const unsigned, SigEvent*> (tick, t)); + } + else + xml.unknown("SigList"); + break; + case Xml::Attribut: + break; + case Xml::TagEnd: + if (tag == "siglist") { + normalize(); + return; + } + default: + break; + } + } + } + +//--------------------------------------------------------- +// SigEvent::write +//--------------------------------------------------------- + +#if 0 +void SigEvent::write(Xml& xml, int at) const + { + xml.stag(QString("sig at=\"%1\"").arg(at)); + xml.tag("tick", tick); + xml.tag("nom", sig.z); + xml.tag("denom", sig.n); + xml.etag("sig"); + } +#endif + +void SigEvent::write(int level, Xml& xml, int at) const + { + xml.tag(level++, "sig at=\"%d\"", at); + xml.intTag(level, "tick", tick); + xml.intTag(level, "nom", sig.z); + xml.intTag(level, "denom", sig.n); + xml.tag(level, "/sig"); + } + +//--------------------------------------------------------- +// SigEvent::read +//--------------------------------------------------------- + +#if 0 +int SigEvent::read(QDomNode node) + { + QDomElement e = node.toElement(); + int at = e.attribute("at", "0").toInt(); + node = node.firstChild(); + + while (!node.isNull()) { + QDomElement e = node.toElement(); + if (e.tagName() == "tick") + tick = e.text().toInt(); + else if (e.tagName() == "nom") + sig.z = e.text().toInt(); + else if (e.tagName() == "denom") + sig.n = e.text().toInt(); + else + printf("MusE:SigEvent: unknown tag %s\n", e.tagName().toLatin1().constData()); + node = node.nextSibling(); + } + return at; + } + +} +#endif + +int SigEvent::read(Xml& xml) + { + int at = 0; + for (;;) { + Xml::Token token = xml.parse(); + const QString& tag = xml.s1(); + switch (token) { + case Xml::Error: + case Xml::End: + return 0; + case Xml::TagStart: + if (tag == "tick") + tick = xml.parseInt(); + else if (tag == "nom") + sig.z = xml.parseInt(); + else if (tag == "denom") + sig.n = xml.parseInt(); + else + xml.unknown("SigEvent"); + break; + case Xml::Attribut: + if (tag == "at") + at = xml.s2().toInt(); + break; + case Xml::TagEnd: + if (tag == "sig") + return at; + default: + break; + } + } + return 0; + } + + +} // namespace AL + diff --git a/attic/muse2-oom/muse2/al/sig.h b/attic/muse2-oom/muse2/al/sig.h new file mode 100644 index 00000000..ed18981f --- /dev/null +++ b/attic/muse2-oom/muse2/al/sig.h @@ -0,0 +1,117 @@ +//============================================================================= +// AL +// Audio Utility Library +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __SIG_H__ +#define __SIG_H__ + +#include <map> + +#include "../muse/xml.h" +class Xml; + +namespace AL { + +#ifndef MAX_TICK +#define MAX_TICK (0x7fffffff/100) +#endif + +///class Xml; + +//--------------------------------------------------------- +// TimeSignature +//--------------------------------------------------------- + +struct TimeSignature { + int z, n; + TimeSignature() { z = 4; n = 4; } + TimeSignature(int a, int b) { z = a; n = b; } + bool isValid() const; + }; + +//--------------------------------------------------------- +// Signature Event +//--------------------------------------------------------- + +struct SigEvent { + TimeSignature sig; + unsigned tick; // signature valid from this position + int bar; // precomputed + + ///int read(QDomNode); + ///void write(Xml&, int) const; + int read(Xml&); + void write(int, Xml&, int) const; + + SigEvent() { } + SigEvent(const TimeSignature& s, unsigned tk) { + sig = s; + tick = tk; + bar = 0; + } + }; + +//--------------------------------------------------------- +// SigList +//--------------------------------------------------------- + +typedef std::map<unsigned, SigEvent*, std::less<unsigned> > SIGLIST; +typedef SIGLIST::iterator iSigEvent; +typedef SIGLIST::const_iterator ciSigEvent; +typedef SIGLIST::reverse_iterator riSigEvent; +typedef SIGLIST::const_reverse_iterator criSigEvent; + +class SigList : public SIGLIST { + int ticks_beat(int N) const; + void normalize(); + int ticksMeasure(const TimeSignature&) const; + int ticksMeasure(int z, int n) const; + + public: + SigList(); + void clear(); + void add(unsigned tick, const TimeSignature& s); + //void add(unsigned tick, int z, int n); + void del(unsigned tick); + + ///void read(QDomNode); + ///void write(Xml&) const; + void read(Xml&); + void write(int, Xml&) const; + + void dump() const; + + TimeSignature timesig(unsigned tick) const; + void timesig(unsigned tick, int& z, int& n) const; + void tickValues(unsigned t, int* bar, int* beat, unsigned* tick) const; + unsigned bar2tick(int bar, int beat, unsigned tick) const; + + int ticksMeasure(unsigned tick) const; + int ticksBeat(unsigned tick) const; + unsigned raster(unsigned tick, int raster) const; + unsigned raster1(unsigned tick, int raster) const; // round down + unsigned raster2(unsigned tick, int raster) const; // round up + int rasterStep(unsigned tick, int raster) const; + }; + +extern SigList sigmap; + +} + +#endif diff --git a/attic/muse2-oom/muse2/al/xml.cpp b/attic/muse2-oom/muse2/al/xml.cpp new file mode 100644 index 00000000..96489307 --- /dev/null +++ b/attic/muse2-oom/muse2/al/xml.cpp @@ -0,0 +1,366 @@ +//============================================================================= +// AL +// Audio Utility Library +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "xml.h" +#include "al.h" + +#include <QDomElement> +#include <QMetaProperty> +#include <QWidget> + +namespace AL { + +//--------------------------------------------------------- +// Xml +//--------------------------------------------------------- + +Xml::Xml() + { + level = 0; + } + +Xml::Xml(QIODevice* device) + : QTextStream(device) + { + setCodec("utf8"); + level = 0; + } + +//--------------------------------------------------------- +// putLevel +//--------------------------------------------------------- + +void Xml::putLevel() + { + for (int i = 0; i < level*2; ++i) + *this << ' '; + } + +//--------------------------------------------------------- +// header +//--------------------------------------------------------- + +void Xml::header() + { + *this << "<?xml version=\"1.0\" encoding=\"utf8\"?>" << endl; + } + +//--------------------------------------------------------- +// put +//--------------------------------------------------------- + +void Xml::put(const QString& s) + { + putLevel(); + *this << xmlString(s) << endl; + } + +//--------------------------------------------------------- +// stag +// <mops attribute="value"> +//--------------------------------------------------------- + +void Xml::stag(const QString& s) + { + putLevel(); + *this << '<' << s << '>' << endl; + ++level; + } + +//--------------------------------------------------------- +// etag +//--------------------------------------------------------- + +void Xml::etag(const char* s) + { + putLevel(); + *this << "</" << s << '>' << endl; + --level; + } + +//--------------------------------------------------------- +// tagE +// <mops attribute="value"/> +//--------------------------------------------------------- + +void Xml::tagE(const QString& s) + { + putLevel(); + *this << '<' << s << "/>" << endl; + } + +void Xml::tag(const char* name, int val) + { + putLevel(); + *this << '<' << name << '>' << val << "</" << name << '>' << endl; + } + +void Xml::tag(const char* name, unsigned val) + { + putLevel(); + *this << '<' << name << '>' << val << "</" << name << '>' << endl; + } + +void Xml::tag(const char* name, float val) + { + putLevel(); + *this << '<' << name << '>' << val << "</" << name << '>' << endl; + } + +void Xml::tag(const char* name, const double& val) + { + putLevel(); + *this << '<' << name << '>' << val << "</" << name << '>' << endl; + } + +void Xml::tag(const char* name, const QString& val) + { + putLevel(); + *this << "<" << name << ">" << xmlString(val) << "</" << name << '>' << endl; + } + +void Xml::tag(const char* name, const QColor& color) + { + putLevel(); + *this << QString("<%1 r=\"%2\" g=\"%3\" b=\"%4\"/>") + .arg(name).arg(color.red()).arg(color.green()).arg(color.blue()) << endl; + } + +void Xml::tag(const char* name, const QWidget* g) + { + tag(name, QRect(g->pos(), g->size())); + } + +void Xml::tag(const char* name, const QRect& r) + { + putLevel(); + *this << "<" << name; + *this << QString(" x=\"%1\" y=\"%2\" w=\"%3\" h=\"%4\"/>") + .arg(r.x()).arg(r.y()).arg(r.width()).arg(r.height()) << endl; + } + +//--------------------------------------------------------- +// xmlString +//--------------------------------------------------------- + +QString Xml::xmlString(const QString& ss) + { + QString s(ss); + s.replace('&', "&"); + s.replace('<', "<"); + s.replace('>', ">"); + s.replace('\'', "'"); + s.replace('"', """); + return s; + } + +//--------------------------------------------------------- +// readGeometry +//--------------------------------------------------------- + +QRect readGeometry(QDomNode node) + { + QDomElement e = node.toElement(); + int x = e.attribute("x","0").toInt(); + int y = e.attribute("y","0").toInt(); + int w = e.attribute("w","50").toInt(); + int h = e.attribute("h","50").toInt(); + return QRect(x, y, w, h); + } + +//--------------------------------------------------------- +// writeProperties +//--------------------------------------------------------- + +void Xml::writeProperties(const QObject* o) + { + const QMetaObject* meta = o->metaObject(); + + // + // start from dummy "muse" property, assuming this is the + // first muse propertie in widget hierarchy + // + int from = meta->indexOfProperty("muse") + 1; + int n = meta->propertyCount(); + for (int i = from; i < n; ++i) { + QMetaProperty p = meta->property(i); + if (!p.isScriptable()) + continue; + const char* name = p.name(); + QVariant v = p.read(o); + switch(v.type()) { + case QVariant::Bool: + case QVariant::Int: + tag(name, v.toInt()); + break; + case QVariant::Double: + tag(name, v.toDouble()); + break; + case QVariant::String: + tag(name, v.toString()); + break; + case QVariant::Rect: + tag(name, v.toRect()); + break; + case QVariant::Point: + { + QPoint p = v.toPoint(); + putLevel(); + *this << "<" << name << QString(" x=\"%1\" y=\"%2\" />") + .arg(p.x()).arg(p.y()) << endl; + } + break; + + default: + printf("MusE:%s type %d not implemented\n", + meta->className(), v.type()); + break; + } + } + } + +//--------------------------------------------------------- +// readProperties +//--------------------------------------------------------- + +void readProperties(QObject* o, QDomNode node) + { + const QMetaObject* meta = o->metaObject(); + + QDomElement e = node.toElement(); + QString tag(e.tagName()); + int idx = meta->indexOfProperty(tag.toLatin1().constData()); + if (idx == -1) { + printf("MusE:%s: unknown tag %s\n", + meta->className(), tag.toLatin1().constData()); + return; + } + QMetaProperty p = meta->property(idx); + QVariant v; + switch(p.type()) { + case QVariant::Int: + case QVariant::Bool: + v.setValue(e.text().toInt()); + break; + case QVariant::Double: + v.setValue(e.text().toDouble()); + break; + case QVariant::String: + v.setValue(e.text()); + break; + case QVariant::Rect: + v.setValue(AL::readGeometry(node)); + break; + case QVariant::Point: + { + int x = e.attribute("x","0").toInt(); + int y = e.attribute("y","0").toInt(); + v.setValue(QPoint(x, y)); + } + break; + default: + printf("MusE:%s type %d not implemented\n", + meta->className(), p.type()); + return; + } + if (p.isWritable()) + p.write(o, v); + } + +//--------------------------------------------------------- +// dump +//--------------------------------------------------------- + +void Xml::dump(int len, const unsigned char* p) + { + putLevel(); + int col = 0; + setFieldWidth(5); + setNumberFlags(numberFlags() | QTextStream::ShowBase); + setIntegerBase(16); + for (int i = 0; i < len; ++i, ++col) { + if (col >= 16) { + setFieldWidth(0); + *this << endl; + col = 0; + putLevel(); + setFieldWidth(5); + } + *this << (p[i] & 0xff); + } + if (col) + *this << endl << dec; + setFieldWidth(0); + setIntegerBase(10); + } + +//--------------------------------------------------------- +// domError +//--------------------------------------------------------- + +void domError(QDomNode node) + { + QDomElement e = node.toElement(); + QString tag(e.tagName()); + QString s; + QDomNode dn(node); + while (!dn.parentNode().isNull()) { + dn = dn.parentNode(); + const QDomElement e = dn.toElement(); + const QString k(e.tagName()); + if (!s.isEmpty()) + s += ":"; + s += k; + } + fprintf(stderr, "%s: Unknown Node <%s>, type %d\n", + s.toLatin1().constData(), tag.toLatin1().constData(), node.nodeType()); + if (node.isText()) { + fprintf(stderr, " text node <%s>\n", node.toText().data().toLatin1().constData()); + } + } + +//--------------------------------------------------------- +// domNotImplemented +//--------------------------------------------------------- + +void domNotImplemented(QDomNode node) + { + if (!AL::debugMsg) + return; + QDomElement e = node.toElement(); + QString tag(e.tagName()); + QString s; + QDomNode dn(node); + while (!dn.parentNode().isNull()) { + dn = dn.parentNode(); + const QDomElement e = dn.toElement(); + const QString k(e.tagName()); + if (!s.isEmpty()) + s += ":"; + s += k; + } + fprintf(stderr, "%s: Node not implemented: <%s>, type %d\n", + s.toLatin1().constData(), tag.toLatin1().constData(), node.nodeType()); + if (node.isText()) { + fprintf(stderr, " text node <%s>\n", node.toText().data().toLatin1().constData()); + } + } +} + diff --git a/attic/muse2-oom/muse2/al/xml.h b/attic/muse2-oom/muse2/al/xml.h new file mode 100644 index 00000000..a72c1ac5 --- /dev/null +++ b/attic/muse2-oom/muse2/al/xml.h @@ -0,0 +1,76 @@ +//============================================================================= +// AL +// Audio Utility Library +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __XML_H__ +#define __XML_H__ + +#include <QTextStream> + +class QColor; +class QDomNode; +class QRect; +class QWidget; + +namespace AL { + +//--------------------------------------------------------- +// Xml +//--------------------------------------------------------- + +class Xml : public QTextStream { + int level; + + public: + Xml(); + Xml(QIODevice*); + + void header(); + void putLevel(); + + void put(const QString&); + + void stag(const QString&); + void etag(const char*); + + void tagE(const QString&); + + void tag(const char* name, int); + void tag(const char* name, unsigned); + void tag(const char* name, const double& val); + void tag(const char* name, float val); + void tag(const char* name, const QString& s); + void tag(const char* name, const QColor& color); + void tag(const char* name, const QWidget* g); + void tag(const char* name, const QRect& r); + + void dump(int n, const unsigned char*); + void writeProperties(const QObject*); + + static QString xmlString(const QString&); + }; + +extern QRect readGeometry(QDomNode); +extern void readProperties(QObject* o, QDomNode node); +extern void domError(QDomNode node); +extern void domNotImplemented(QDomNode node); +} + +#endif + |