text:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using LibAYEmu;
using System.ComponentModel;

namespace WYZTracker
{
    public class Player : IDisposable
    {
        static Player()
        {
            TickPeriod = 1000 / 50; // 50Hz, 20ms
        }

        private const int GENSOUND_PERIOD = 10;

        public Player()
        {
            this.playState = PlayStatus.Stopped;
            for (int i = 0; i < ayEmus.Length; i++)
            {
                ayEmus[i] = new AY();
                ayEmus[i].SetChipType(LibAYEmu.Chip.AY_Kay, null);
            }
            streamer = new PlaybackStreamer();
            streamer.BufferLengthInMs = 2 * GENSOUND_PERIOD;
            streamer.FillBuffer += new EventHandler<FillBufferEventArgs>(OnFillBuffer);

            this.LimitLoops = -1;
            this.Volume = 1.0;
        }

        private byte[] regs = new byte[14];

        // Longitud del buffer: Frecuencia * número de canales * milisegundos / 1000
        private int TICK_BUF_LENGTH
        {
            get
            {
                return (int)(44100 * 2 * TickPeriod / 1000);
            }
        }

        private Song currentSong;
        private PlayMode playMode = PlayMode.FullSong;

        private Instrument[] currentInstruments;
        private int[] lastPitchModifiers;
        private int[] totalModifiers;
        private Pattern currentPattern;
        private ChannelLine currentLine;

        private double[] lastTickBuf;
        private long lastTickBufPosition = 0;

        private Effect currentEffect;
        private int lineNumber;
        private int patternNumber;
        private int currentTempo;

        private bool[] inOrnament;
        private long[] instrPositions;
        private int effectPosition = int.MinValue;
        private int[] notes;
        private int[] tones;
        private int[] octaves;
        private int[] lastReadOctaves;
        private int[] semiNotes;
        private int[] frequencies;
        private sbyte?[] volModifiers;
        private EnvelopeData[] lastEnvData;

        private PlayStatus playState;
        private int periodCount;

        private Stereo currentStereo;

        private LibAYEmu.AY[] ayEmus = new LibAYEmu.AY[3];
        private PlaybackStreamer streamer;

        private int loopCount;

        public delegate void NextLineEventHandler(object sender, NextLineEventArgs evArgs);
        public event NextLineEventHandler NextLine;
        public event EventHandler SongFinished;
        public event EventHandler CurrentTempoChanged;

        public static double TickPeriod { get; set; }

        public int LimitLoops { get; set; }

        public double Volume
        {
            get
            {
                return this.streamer.Volume;
            }
            set
            {
                this.streamer.Volume = value;
            }
        }

        public Stereo Stereo
        {
            get
            {
                return currentStereo;
            }
            set
            {
                currentStereo = value;
                for (int i = 0; i < ayEmus.Length; i++)
                {
                    ayEmus[i].SetStereo(value, null);
                }
            }
        }

        public PlayMode PlayMode
        {
            get
            {
                return playMode;
            }
            set
            {
                playMode = value;
            }
        }

        public PlayStatus Status
        {
            get
            {
                return playState;
            }
        }

        public Song CurrentSong
        {
            get
            {
                return currentSong;
            }
            set
            {
                if (value != currentSong)
                {
                    if (currentSong != null)
                    {
                        currentSong.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler(currentSong_PropertyChanged);
                    }
                    currentSong = value;
                    if (currentSong != null)
                    {
                        currentSong.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(currentSong_PropertyChanged);
                    }
                    initializeParams();
                }
            }
        }

        public int CurrentTempo
        {
            get { return this.currentTempo; }
            set
            {
                if (value != currentTempo)
                {
                    currentTempo = value;
                    if (currentTempo < 1)
                    {
                        currentTempo = 1;
                    }
                    this.CurrentTempoChanged?.Invoke(this, EventArgs.Empty);
                }
            }
        }

        private ChannelLine CurrentLine
        {
            get
            {
                return currentLine;
            }
            set
            {
                if (value != currentLine)
                {
                    currentLine = value;
                    if (this.currentLine != null)
                    {
                        this.CurrentTempo += this.currentLine.TempoModifier;
                    }
                }
            }
        }

        /// <summary>
        /// Fills the provided buffer with audio data. Stereo 16-bits data is required.
        /// </summary>
        /// <param name="sender">Streamer object.</param>
        /// <param name="instr">FillBufferEventArgs.</param>
        private void OnFillBuffer(object sender, FillBufferEventArgs e)
        {
            if (this.playState == PlayStatus.Playing)
            {
                long remainingSamples = e.Buffer.LongLength;
                long samplesToCopy = 0;
                long currPos = 0;

                while (remainingSamples > 0)
                {
                    if ((lastTickBuf == null) || (lastTickBuf.Length - lastTickBufPosition == 0))
                    {
                        lastTickBuf = getTick();
                        lastTickBufPosition = 0;
                    }
                    // Hay samples pendientes de copiar del ultimo tick!!
                    samplesToCopy = Math.Min(lastTickBuf.Length - lastTickBufPosition, remainingSamples);

                    Array.Copy(lastTickBuf, lastTickBufPosition, e.Buffer, currPos, samplesToCopy);
                    remainingSamples -= samplesToCopy;
                    lastTickBufPosition += samplesToCopy;
                    currPos += samplesToCopy;
                }
            }
            else
            {
                Array.Copy(new UInt16[e.Buffer.Length], e.Buffer, e.Buffer.Length);
            }
        }

        private double[] getTick()
        {
            int numSamples = TICK_BUF_LENGTH;
            int envStyle = 0xFF;
            double[][] buffer = new double[3][] { new double[numSamples],
                                                  new double[numSamples],
                                                  new double[numSamples] };
            double[] result = null;

            if (this.currentSong != null &&
                (playState == PlayStatus.Playing || playState == PlayStatus.Dumping) &&
                this.CurrentLine != null)
            {
                int noise = 0;
                int ayChipsNeeded = (int)Math.Ceiling(this.currentSong.Channels / 3m);

                bool[] noteChanged = new bool[this.currentSong.Channels];

                try
                {
                    if (this.periodCount == 0)
                    {
                        parseNextNote(noteChanged);
                    }

                    ChannelControl[] ctrl = setToneInChannelControl();
                    int[] vols = calculateVolumesAndFrequencies(noteChanged);

                    bool hasEffects = this.areEffectsActive();

                    // Actualizamos aquí abajo, ya que vuelve a hacer falta la nota justo encima.
                    if (this.periodCount == 0 && (playState == PlayStatus.Playing || playState == PlayStatus.Dumping))
                    {
                        updateCurrentLine();
                    }

                    for (int i = 0; i < ayChipsNeeded; i++)
                    {
                        int channel = i * 3; ;
                        int toneA = 0, toneB = 0, toneC = 0;
                        int volA = 0, volB = 0, volC = 0;
                        bool useEnvA = false, useEnvB = false, useEnvC = false;
                        bool activeFreqA = false, activeFreqB = false, activeFreqC = false;
                        int envFreq = 0;

                        noise = this.getNoise(ctrl);

                        if ((ctrl[i] & ChannelControl.TONE_A) == ChannelControl.TONE_A)
                        {
                            toneA = getFrequencyForChannel(channel);
                            volA = getVolumeForChannel(channel, vols);
                            useEnvA = updateEnvelopeForChannel(channel, noise, noteChanged, ref volA, ref envStyle, ref envFreq, ref activeFreqA);
                        }
                        channel++;

                        if ((ctrl[i] & ChannelControl.TONE_B) == ChannelControl.TONE_B)
                        {
                            toneB = getFrequencyForChannel(channel);
                            volB = getVolumeForChannel(channel, vols);
                            useEnvB = updateEnvelopeForChannel(channel, noise, noteChanged, ref volB, ref envStyle, ref envFreq, ref activeFreqB);
                        }
                        channel++;

                        if ((ctrl[i] & ChannelControl.TONE_C) == ChannelControl.TONE_C)
                        {
                            toneC = getFrequencyForChannel(channel);
                            volC = getVolumeForChannel(channel, vols);
                            useEnvC = updateEnvelopeForChannel(channel, noise, noteChanged, ref volC, ref envStyle, ref envFreq, ref activeFreqC);
                        }

                        envFreq = (useEnvA || useEnvB || useEnvC) ? envFreq : 0;

                        int fxChannel = this.currentSong != null ? this.currentSong.FxChannel : 0;

                        bool thisAyHasFx = (i == (fxChannel / 3));
                        int fxChannelInCurrentAy = (fxChannel % 3);

                        this.genSound((!useEnvA || activeFreqA || (thisAyHasFx && fxChannelInCurrentAy == 0 && hasEffects)) ? toneA : 0,
                                      (!useEnvB || activeFreqB || (thisAyHasFx && fxChannelInCurrentAy == 1 && hasEffects)) ? toneB : 0,
                                      (!useEnvC || activeFreqC || (thisAyHasFx && fxChannelInCurrentAy == 2 && hasEffects)) ? toneC : 0,
                                      thisAyHasFx ? noise : 0,
                                      (int)ctrl[i],
                                      volA,
                                      volB,
                                      volC,
                                      envFreq,
                                      envStyle,
                                      buffer[i],
                                      ayEmus[i],
                                      true
                                     );
                    }

                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }

                this.periodCount++;
                if (this.periodCount >= this.CurrentTempo)
                {
                    this.periodCount = 0;
                }

                if (this.effectPosition >= 0)
                {
                    this.effectPosition++;
                    if (this.currentEffect == null || effectPosition >= this.currentEffect.Volumes.Length)
                    {
                        effectPosition = int.MinValue;
                    }
                }

                result = mixChannels(buffer, ayChipsNeeded, numSamples);
            }

            if (result == null)
            {
                result = new double[numSamples];
            }

            return result;
        }

        /// <summary>
        /// Mixes the source channels.
        /// </summary>
        /// <param name="source">Source channels.</param>
        /// <param name="numSources">Number of source channels. Must be </param>
        /// <returns></returns>
        private double[] mixChannels(double[][] source, int numSources, int numSamples)
        {
            double[] result = new double[numSamples];

            if (numSources == 1)
            {
                for (int i = 0; i < numSamples; i++)
                {
                    result[i] = source[0][i];
                }
            }
            else if (numSources == 2)
            {
                for (int i = 0; i < numSamples; i++)
                {
                    double a = source[0][i];
                    double b = source[1][i];
                    result[i] = a + b - a * b;
                }
            }
            else
            {
                for (int i = 0; i < numSamples; i++)
                {
                    double a = source[0][i];
                    double b = source[1][i];
                    double c = source[2][i];
                    result[i] = a + b + c - a * b - a * c - b * c + a * b * c;
                }
            }

            return result;
        }

        private bool lastCycleHadFx = false;

        private bool updateEnvelopeForChannel(int channel, int noise, bool[] noteChanged, ref int vol, ref int envStyle, ref int envFreq, ref bool activeFreqs)
        {
            bool useEnv = false;
            if (this.currentSong.FxChannel == channel && this.areEffectsActive())
            {
                if ((noise & 0x80) == 0x80)
                {
                    envStyle = this.currentEffect.EnvTypes[this.effectPosition];
                    if (envStyle == 0x01)
                    {
                        envStyle = 0xFF;
                    }
                    envFreq = this.currentEffect.EnvFreqs[this.effectPosition];
                    vol |= 0x10;
                    useEnv = true;
                    lastCycleHadFx = true;
                    activeFreqs = false;
                }
            }
            else
            {
                int tone = getFrequencyForChannel(channel);
                ChannelNote currentNote = this.CurrentLine.Notes[channel];
                useEnv = (this.currentInstruments[channel] != null && this.currentInstruments[channel].ID == "R");
                if (useEnv)
                {
                    envFreq = tone / lastEnvData[channel].FrequencyRatio;
                    activeFreqs = lastEnvData[channel].ActiveFrequencies;
                    if (noteChanged[channel] || lastCycleHadFx)
                    {
                        lastCycleHadFx = false;
                        envStyle = lastEnvData[channel].Style;
                    }
                    else
                    {
                        envStyle = 0xFF;
                    }
                }
            }
            return useEnv;
        }

        private int getFrequencyForChannel(int channel)
        {
            int result = 0;
            int fxChannel = this.currentSong == null ? 0 : this.currentSong.FxChannel;
            if (channel == fxChannel && this.areEffectsActive())
            {
                result = this.currentEffect.Frequencies[effectPosition];
            }
            else if (this.currentSong.Channels > channel && (!this.currentSong.MutedChannels[channel]))
            {
                result = frequencies[channel];
            }
            return result;
        }

        private int getVolumeForChannel(int channel, int[] vols)
        {
            int result = 0;
            int fxChannel = this.currentSong == null ? 0 : this.currentSong.FxChannel;
            if (channel == fxChannel && this.areEffectsActive())
            {
                result = this.currentEffect.Volumes[this.effectPosition];
            }
            else if (this.currentSong.Channels > channel && (!this.currentSong.MutedChannels[channel]))
            {
                result = vols[channel];
            }
            return result;
        }

        private bool areEffectsActive()
        {
            return (effectPosition >= 0 &&
                    !this.currentSong.MutedChannels[this.currentSong.Channels] &&
                    effectPosition < this.currentEffect.Volumes.Length);
        }

        private int getNoise(ChannelControl[] ctrl)
        {
            int result = 0;
            if (this.areEffectsActive())
            {
                int fxChannel = currentSong.FxChannel;
                result = this.currentEffect.Noises[effectPosition];
                if ((result & 0x7F) > 0)
                {
                    int ctrlIndex = fxChannel / 3;
                    int channelRemainder = fxChannel % 3;

                    if (channelRemainder == 0)
                    {
                        ctrl[ctrlIndex] |= ChannelControl.NOISE_A;
                    }
                    if (channelRemainder == 1)
                    {
                        ctrl[ctrlIndex] |= ChannelControl.NOISE_B;
                    }
                    if (channelRemainder == 2)
                    {
                        ctrl[ctrlIndex] |= ChannelControl.NOISE_C;
                    }
                }
            }
            return result;
        }

        private int[] calculateVolumesAndFrequencies(bool[] noteChanged)
        {
            int[] vols = new int[this.currentSong.Channels];

            ChannelNote note;

            for (int i = 0; i < this.currentSong.Channels; i++)
            {
                if (notes[i] == -1)
                {
                    // Si está en silencio, ponemos el volumen a 0.
                    vols[i] = 0;
                }
                else
                {
                    note = this.CurrentLine.Notes[i];

                    if (this.currentInstruments[i] != null &&
                        this.currentInstruments[i].ID != null &&
                        this.currentInstruments[i].PitchModifiers != null &&
                        instrPositions[i] < this.currentInstruments[i].PitchModifiers.Length)
                    {
                        lastPitchModifiers[i] = this.currentInstruments[i].PitchModifiers[instrPositions[i]];
                    }

                    vols[i] = this.getVolFromNote(note, ref this.currentInstruments[i], ref instrPositions[i]);

                    if (tones[i] != 0)
                    {
                        if ((vols[i] & 0x10) != 0)
                        {
                            // Ornament
                            int newTone = tones[i] + lastPitchModifiers[i];
                            setFrequencyForTone(i, newTone);
                            frequencies[i] += totalModifiers[i];
                            inOrnament[i] = true;
                        }
                        else if (inOrnament[i] && !noteChanged[i])
                        {
                            inOrnament[i] = false;
                            setFrequencyForTone(i, tones[i]);
                            frequencies[i] += totalModifiers[i];
                        }

                        if ((vols[i] & 0x20) != 0)
                        {
                            if ((long)frequencies[i] * 2 > int.MaxValue)
                            {
                                frequencies[i] = int.MaxValue;
                            }
                            else
                            {
                                frequencies[i] *= 2;
                            }
                        }
                        else
                        {
                            if ((vols[i] & 0x40) != 0)
                            {
                                frequencies[i] /= 2;
                            }
                        }
                    }

                    if (this.currentInstruments[i] != null && this.currentInstruments[i].ID != "R" && ((vols[i] & 0x10) == 0))
                    {
                        frequencies[i] += lastPitchModifiers[i];
                        totalModifiers[i] += lastPitchModifiers[i];
                    }

                    if (currentInstruments[i] != null && currentInstruments[i].ID != "R")
                    {
                        vols[i] &= 0xF;
                        if (volModifiers[i] != null) // TODO:  && vols[i] != 0, cuando el player lo implemente.
                        {
                            int targetVol = vols[i] + volModifiers[i].GetValueOrDefault();
                            if (targetVol < 0) { targetVol = 0; }
                            if (targetVol > 0xF) { targetVol = 0xF; }
                            if (vols[i] > 0 && targetVol == 0) { targetVol = 1; }
                            vols[i] = targetVol;
                        }
                    }
                }
            }
            return vols;
        }

        private ChannelControl[] setToneInChannelControl()
        {
            ChannelControl[] ctrl = new ChannelControl[3];
            int fxChannel = this.currentSong == null ? 0 : this.currentSong.FxChannel;

            for (int i = 0; i < 3; i++)
            {
                // Calculamos los volumenes de los canales:
                if (this.currentSong.Channels > i * 3 && !this.currentSong.MutedChannels[i * 3])
                {
                    ctrl[i] |= ChannelControl.TONE_A;
                }
                if (i * 3 == fxChannel && !this.currentSong.MutedChannels[this.currentSong.Channels])
                {
                    ctrl[i] |= ChannelControl.TONE_A;
                }

                if (this.currentSong.Channels > i * 3 + 1 && !this.currentSong.MutedChannels[i * 3 + 1])
                {
                    ctrl[i] |= ChannelControl.TONE_B;
                }
                if (i * 3 + 1 == fxChannel && !this.currentSong.MutedChannels[this.currentSong.Channels])
                {
                    ctrl[i] |= ChannelControl.TONE_B;
                }

                if (this.currentSong.Channels > i * 3 + 2 && !this.currentSong.MutedChannels[i * 3 + 2])
                {
                    ctrl[i] |= ChannelControl.TONE_C;
                }
                if (i * 3 + 2 == fxChannel && !this.currentSong.MutedChannels[this.currentSong.Channels])
                {
                    ctrl[i] |= ChannelControl.TONE_C;
                }
            }
            return ctrl;
        }

        private void parseNextNote(bool[] noteChanged)
        {
            ChannelNote note;
            if (this.CurrentLine.Fx != int.MinValue)
            {
                currentEffect = getEffect(this.CurrentLine.Fx);
                effectPosition = 0;
            }

            // Hemos de aplicar la nota actual, y apuntar a la siguiente.
            for (int i = 0; i < this.currentSong.Channels; i++)
            {
                noteChanged[i] = false;

                note = this.CurrentLine.Notes[i];
                if (note.HasInstrument)
                {
                    Instrument currentInstrument;
                    if ((currentInstrument = this.currentSong.GetInstrument(note.Instrument)) != null)
                    {
                        instrPositions[i] = 0;
                        this.currentInstruments[i] = currentInstrument;
                        if (currentInstrument.ID == "R")
                        {
                            lastEnvData[i] = note.EnvData;
                        }
                        volModifiers[i] = note.VolModifier;
                    }
                    noteChanged[i] = true;
                }
                else
                {
                    if (note.VolModifier.HasValue)
                    {
                        volModifiers[i] = note.VolModifier;
                    }
                }
                if (note.HasOctave)
                {
                    octaves[i] = note.Octave - 2;
                    lastReadOctaves[i] = octaves[i];
                    instrPositions[i] = 0;
                }
                if (note.HasSeminote)
                {
                    semiNotes[i] = (note.Seminote == '+') ? 1 : -1;
                    instrPositions[i] = 0;
                    noteChanged[i] = true;
                }
                else
                {
                    if (note.HasValue)
                    {
                        semiNotes[i] = 0;
                    }
                }
                if (note.HasNote)
                {
                    notes[i] = note.GetNote();
                    instrPositions[i] = 0;
                    noteChanged[i] = true;
                }
                if (notes[i] == -1)
                {
                    tones[i] = 0;
                }
                else
                {
                    if (noteChanged[i])
                    {
                        octaves[i] = lastReadOctaves[i];
                        tones[i] = 12 * octaves[i] + (notes[i] + semiNotes[i]) + 2;
                        totalModifiers[i] = 0;
                        setFrequencyForTone(i, tones[i]);
                    }
                }
            }
        }

        private void setFrequencyForTone(int channel, int tone)
        {
            if (tone >= 0)
            {
                int num = 0;
                while (tone >= this.currentSong.Frequencies.Length)
                {
                    tone -= 12;
                    num++;
                }
                int freq = this.currentSong.Frequencies[tone];
                frequencies[channel] = (int)(freq / Math.Pow(2, num));
            }
            else
            {
                frequencies[channel] = 0;
            }
        }

        private Effect getEffect(int p)
        {
            Effect eff = null;
            foreach (Effect e in this.currentSong.Effects)
            {
                if (e.ID == p)
                {
                    eff = e;
                    break;
                }
            }
            return eff;
        }

        private void updateCurrentLine()
        {
            this.lineNumber++;
            if (this.lineNumber >= this.currentPattern.Lines.Length)
            {
                if (playMode == PlayMode.FullSong)
                {
                    this.patternNumber++;
                    if (this.patternNumber >= this.currentSong.PlayOrder.Count)
                    {
                        if (this.currentSong.Looped && (this.LimitLoops == -1 || loopCount < this.LimitLoops))
                        {
                            this.patternNumber = this.currentSong.LoopToPattern;
                            this.loopCount++;
                        }
                        else
                        {
                            this.OnSongFinished();
                        }
                    }
                }
                GoToPattern(this.patternNumber);
            }
            else
            {
                this.CurrentLine = this.currentPattern.Lines[this.lineNumber];
            }
            this.OnNextLine(new NextLineEventArgs(this.patternNumber, this.lineNumber));
        }

        private int getVolFromNote(ChannelNote note, ref Instrument currentInstrument, ref long instrPos)
        {
            int vol;

            if ((note.HasInstrument) && (periodCount == 0))
            {
                currentInstrument = this.currentSong.GetInstrument(note.Instrument);
            }
            if (currentInstrument != null && currentInstrument.ID != "R")
            {
                if (instrPos >= currentInstrument.Volumes.Length)
                {
                    vol = 0;
                }
                else
                {
                    vol = currentInstrument.Volumes[instrPos];
                    instrPos++;
                    if (instrPos >= currentInstrument.Volumes.Length)
                    {
                        if (currentInstrument.Looped)
                        {
                            instrPos = currentInstrument.LoopStart;
                        }
                    }
                }
            }
            else if (currentInstrument == null)
            {
                vol = 0;
            }
            else
            {
                vol = 0x10;
            }
            return vol;
        }

        private void currentSong_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "ChipFrequency")
            {
                UpdateChipFrequencies();
            }
            if (e.PropertyName == "Tempo")
            {
                this.CurrentTempo = this.currentSong.Tempo;
            }
        }

        private void initializeParams()
        {
            int numChannels = this.currentSong.Channels;

            this.inOrnament = new bool[numChannels];
            this.currentInstruments = new Instrument[numChannels];
            this.lastPitchModifiers = new int[numChannels];
            this.totalModifiers = new int[numChannels];

            this.notes = new int[numChannels];
            this.tones = new int[numChannels];
            this.octaves = new int[numChannels];
            this.lastReadOctaves = new int[numChannels];
            this.semiNotes = new int[numChannels];
            this.instrPositions = new long[numChannels];
            this.frequencies = new int[numChannels];
            this.lastEnvData = new EnvelopeData[numChannels];
            this.volModifiers = new sbyte?[numChannels];
            this.loopCount = 0;
            this.lineNumber = 0;

            this.CurrentTempo = this.currentSong.Tempo;

            for (int i = 0; i < numChannels; i++)
            {
                this.currentInstruments[i] = null;
                this.lastPitchModifiers[i] = 0;

                // Arranca en silencio...
                this.notes[i] = -1;
                this.tones[i] = 0;
                this.octaves[i] = 0;
                this.semiNotes[i] = 0;
                this.instrPositions[i] = 0;
                this.lastEnvData[i] = new EnvelopeData();
                this.volModifiers[i] = null;
            }
            UpdateChipFrequencies();
            GoToPattern(0);
        }

        public void UpdateChipFrequencies()
        {
            for (int i = 0; i < ayEmus.Length; i++)
            {
                ayEmus[i].SetChipFreq(this.currentSong.ChipFrequency);
            }
        }

        public void Play()
        {
            Play(0);
        }

        public void Play(int patternIdx)
        {
            this.playState = PlayStatus.Playing;

            periodCount = 0;
            effectPosition = int.MinValue;
            this.CurrentLine = null;
            this.initializeParams();
            this.GoToPattern(patternIdx);
            for (int i = 0; i < ayEmus.Length; i++)
            {
                ayEmus[i].Reset();
            }
        }

        public void Stop()
        {
            this.playState = PlayStatus.Stopped;
        }

        public void Pause()
        {
            switch (this.playState)
            {
                case PlayStatus.Playing:
                    this.playState = PlayStatus.Paused;
                    break;
                case PlayStatus.Paused:
                    this.playState = PlayStatus.Playing;
                    break;
                case PlayStatus.Stopped:
                    this.initializeParams();
                    this.playState = PlayStatus.Stopped;
                    break;
            }
        }

        public void GoToPattern(int patternOrder)
        {
            if (patternOrder < this.currentSong.PlayOrder.Count)
            {
                this.lineNumber = 0;
                this.patternNumber = patternOrder;
                this.currentPattern = this.currentSong.Patterns[this.currentSong.PlayOrder[patternOrder]];
                this.CurrentLine = this.currentPattern.Lines[0];
                this.periodCount = 0;
            }
        }

        protected virtual void OnNextLine(NextLineEventArgs e)
        {
            this.NextLine?.Invoke(this, e);
        }

        protected virtual void OnSongFinished()
        {
            this.SongFinished?.Invoke(this, EventArgs.Empty);
        }

        private void genSound(int tonea, int toneb, int tonec, int noise, int control, int vola,
                              int volb, int volc, int envfreq, int envstyle, double[] buffer,
                              LibAYEmu.AY emu, bool setRegs)
        {
            byte[] regs = new byte[14];

            /* setup regs */
            regs[0] = (byte)(tonea & 0xff);
            regs[1] = (byte)(tonea >> 8);
            regs[2] = (byte)(toneb & 0xff);
            regs[3] = (byte)(toneb >> 8);
            regs[4] = (byte)(tonec & 0xff);
            regs[5] = (byte)(tonec >> 8);
            regs[6] = (byte)(noise);
            regs[7] = (byte)((~control) & 0x3f); 	/* invert bits 0-5 */
            regs[8] = (byte)(vola); 				/* included bit 4 */
            regs[9] = (byte)(volb);
            regs[10] = (byte)(volc);
            regs[11] = (byte)(envfreq & 0xff);
            regs[12] = (byte)(envfreq >> 8);
            regs[13] = (byte)(envstyle);

            if (setRegs)
            {
                emu.SetRegs(regs);
            }
            emu.GenSound(buffer, buffer.Length, 0);
        }

        #region Miembros de IDisposable

        /// <summary>
        /// Releases resources.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Destructor.
        /// </summary>
        ~Player()
        {
            Dispose(false);
        }

        /// <summary>
        /// Dispose.
        /// </summary>
        /// <param name="disposing">Indicates if the user called the dispose method or the finalizer did it.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (streamer != null)
            {
                streamer.Dispose();
                streamer = null;
            }
        }

        #endregion

        internal void Reset()
        {
            periodCount = 0;
            this.initializeParams();
            this.GoToPattern(0);
            for (int i = 0; i < ayEmus.Length; i++)
            {
                ayEmus[i].Reset();
            }
        }

        public void DumpToWavFile(WaveFile wav, int repeats)
        {
            periodCount = 0;
            for (int i = 0; i < ayEmus.Length; i++)
            {
                ayEmus[i].Reset();
            }
            effectPosition = int.MinValue;
            this.initializeParams();

            this.LimitLoops = repeats - 1;

            this.playState = PlayStatus.Dumping;
            while (PlayStatus.Dumping == this.playState)
            {
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                System.IO.BinaryWriter writer = new System.IO.BinaryWriter(ms);

                int tickNumber = 0;
                do
                {
                    double[] tickData = getTick();
                    foreach (double sample in tickData)
                    {
                        writer.Write((UInt16)(sample * Int16.MaxValue));
                    }
                } while ((tickNumber++ < 1500) && PlayStatus.Dumping == this.playState);

                wav.AppendData(ms.ToArray());
            }
        }
    }
}


Please do not just copy from someone else's records. Contact them, most people love to share.
No. 58, 23 March, 1802.
TERM PDF as used by John Merz is not an Adobe electronic file, it is Personal Data File for an individual soldier.
Copyrights are the property of the individual who submitted the information, article, or graphic.
This site, rootsweb.com or any individual involved with this website are not responsible for the content of information or articles submitted by any individual.
Last updated: March 27, 2006 .


text:
Tag: social media
Green on Screen: The Zero Waste Influencers of Youtube
0 shares662 views
The neoliberal side of social media
Depression: available for download
The Body Issue Battle Faced By Today's Young People
0 shares773 views2
The 21st Century Conundrum: Generation Like! Comment! Share!
Freya Marshall Payne - March 1, 2016
Bebo. MySpace. Hi5. Friendster. Facebook. YouTube. Flickr. Twitter. Tumblr. Instagram. Some of these are dead; some of these are dying; some of these still have many more…
Facebook's French flags: an act of solidarity or Eurocentric bias?
The Badger - December 1, 2015
On the evening of Friday 13th November my friends and I sat in a darkened bar hunched over a phone, pints abandoned, furiously trying to follow the…
The curse of social media: what is the relationship between body image and social media?
Freya Marshall Payne - November 16, 2015
For who knows how long, body image, self-esteem and body consciousness have been an issue for many human beings – especially females. Whether it's the fear of…
The Digital Footprint: Our right to disappear?
Freya Marshall Payne - October 19, 2015
Channel 4 have recently debuted the show 'Hunted', which tasks 14 fugitives with going on the run in the United Kingdom for 28 days. While on the run…
The inescapable clutches of social networking
The Badger - November 25, 2014
Jordan Ellis discusses the power of social networking: how we do not realise its influences, its worth, and the effects it has on our brains. Ask yourself…
Glued to our screens?
The Badger - October 1, 2012
The 21st Century Real Virtual World Jonathan Stefanni-Machado Apple's highly anticipated iPhone 5 was released on 21 September in the…

redpajama_set_name: RedPajamaCommonCrawl


text:
The Parliamentary Budget office springs to life, crippled
I wanted it to be able to provide confidential costings during the election campaign.
It won't now. And Hockey says he won't use it.
Here's what I wrote last month when there was time to put things right:
"It is in all of our interests to give oppositions access to the same high quality costing process as governments. The access has to be confidential. Developing a policy is an iterative process. Ideally an opposition or a government comes up with idea, sketches it out, perhaps get surprised at how much it costs (or doesn't cost) fine tunes it, sends it back for another costing and so on until the polciy and costing are final.
The new Parliamentary Budget Office will enable oppositions to do that. For the first time oppositions will be able to put up ideas to an official costing organisation in confidence and keep coming back until they get it right.
Except that they won't, once the campaign starts. Unhelpfully, the provisions of the government's bill remove confidentiality with the issue of writs. After the campaign starts (exactly the time oppositions might need to fine tune their policies) consultation becomes a one-shot game. An opposition can submit a policy to the PBO, but it won't know what the PBO makes of it until just before the finding is published on the PBO website.
No opposition will take that risk, at least about something risky. Joe Hockey has already said he won't use the process. Nor should he. it is loaded against the opposition.
It can easily be fixed. All that's needed is an amendment that would allow confidential consultations during the campaign as well as during the rest of the year. It'd be in Labor's interest as well as the Coalition's. It'll be in opposition soon enough. Swan, Hockey or whoever occupies the shadow treasurer's chair could iterate with the PBO as much as they want until they get the policy right, knowing the PBO would release only the final costing and not embarrass them.
Hockey moved an amendment to that effect in the House of Representatives. It was defeated. But all is not lost. The Greens are prepared to save the day and negotiate on confidentiality in the Senate. Their only condition is that all parties putting themselves up for office be required to release official costings of all of policies worth more than $100 million, also a good idea.
There's a chance sense will prevail. We have a rare opportunity to get things right, to set up a system that will work for both sides of politics forever. Labor shows every sign of shooting itself in the foot. I'm not confident Hockey won't either. But we're close, very close."
The government said "no" after circulating a minute from the Secretaries of Treasury and Finance coming up with three reasons why not.
It's below.
Reason 1 is doing so would be inconsistent with the Charter of Budget Honesty arrangements. Err.. The reason for the PBO is that the Charter of Budget honesty arrangements are not working. The whole point of having the new office is that it will do things differently. By definition it will be inconsistent.
Reason 2, about game playing, is a tenuous possibility. But there can be safeguards. It would be easy for a clever PBO to check announced policies, and if party A asked the PBO to cost announced policies from party B, the PBO could just say no, or at least "not unless party B asks me to".
Reason 3, about resourcing is something of an excuse. A temporary spike in workload would be easy to manage through secondments and hiring consultants.
It's done now. The PBO is alive, but a little broken.
Pbo Executive Minute
. Labor takes aim at itself. The tragedy of its Parliamentary Budget Office.
. The election was a year ago. Hockey's auditors are still under investigation
. Coalition costings: The inexcusable, the inexplicable...
. Coaliton "too dim" to stop its own rules being used against it
Labels: commonwealth budgets, election costings
Memo Reserve Bank. Read Twitter, it's underrated
MYEFO: Small changes, mostly harmless
Economic outlook dangerous, unless you're in Austr...
Mining companies, as seen by the AMWU
MYEFO. It'd be best not to cut
MYEFO countdown. Swan's looking for $7 billion, plus
Extraordinary. The boom is spreading job prospects...
Only one more cut? ABE forecasts
Europe ought to be a wake up call. David Murray on...
The Parliamentary Budget office springs to life, c...
Vietnam conscripts half as likely to be holding do...
Wow. The Sydney Morning Herald's new ad campaign. ...
That extra $5 billion you need, make it maybe $11 ...
High wages are moving west
Get real. Wage growth is more of a wage crawl
Our houses are emptying, as are our dreams of owni...
The war between traders and economists
Super is a con, perpetrated by people who con them...
Not many more rate cuts - Reserve
You wouldn't read about it, much. Living costs are...
Fun at work. What news presenters do during commer...
Why gold? Why indeed. Here's the video:
How long have I got? Warning: life tables appended
Standstill. We are no longer making enough jobs
Mining has jumped the shark, passed the point wher...
What banks do, and why they are changing what they do
There ain't going to be a budget surplus, nor shou...
This is what the Bankers Association means when it...
Downgrade. Your forecasts won't be met - Reserve
Iron ore down 34%, coking coal down 21% - RBA update
Welcome aboard Stephen Koukoulas
We're spending at shops again?
The European bailout, explained
We're the most evolved, apart from Norway
Long ago and oh so far away... the budget looked good
The cash rate is low, mortgage rates are not
The Reserve will cut, the banks will pass it on


text:
Home Decode
Decode Social Issues
By Team Decode November 12, 2021
The origin of the idea of Aided education institutes has a noble cause at the center of it. While in the last few decades most of the aided institutions have been struggling to provide market standard infrastructure and staff. Most of the aided institutions reach out to Government and Non-Government institutions for funds and regularisation of staff from time to time. The Government's grant only contributes through the means of salaries of aided staff. The infrastructure, management, quality control, all of it, are taken care of by the independent school management. As of now, most of the Aided schools/colleges have very poor infrastructure, a low number of teaching staff, and low student enrollment rates. While the state government provides salaries for teaching and non-teaching-aided staff, the demand for promotions for existing staff and recruitment of new staff is more than 2 decades old. While institutions earlier received grants amounting to 6% of the salaries paid to its aided staff, this grant has also been disbursed irregularly for years now.
In 1999 December, a GO was introduced that barred the Government of Andhra Pradesh from recruiting teachers in Aided schools/colleges. The same GO was carried forward by previous governments till 2017. The Government has no control over the recruitment of aided staff (Teaching/Non teaching) and thus some of the aided institutions are not transparent with regards to their recruitment standards.
As per Section 60 of the Andhra Pradesh Education Act, 1982, the government may take over an educational institution after giving one month's notice, if it is of the opinion that it would be in the public interest or to secure the proper management of the institution. However, the Current Government had issued orders that detailed the policy to be followed for taking over "willing" private aided schools and colleges, including minority institutions.
The current Government introduced a proposal where, they can work with the "Willing" institutions, for providing better infrastructure, amenities to the staff and Government facilities to the students via various schemes. The Government has received an overwhelming response for the policy and accordingly, 68.78% of the 2249 private aided educational institutions, that are functional as of the date of issuance of the policy, have submitted their written willingness voluntarily choosing one of the two options and 6600+ staff (teaching and non-teaching) have reported to the Government for absorption.
DEOs and MEOs (Mandal Education Officers) have been asked to ensure students are accommodated at nearby government schools, if their current school management decides to shut their operations, or if they don't wish to continue in the school once it is unaided. In cases where schools are about to close down, teaching activities and mid-day meal provision will continue until students are shifted to alternative schools.
For aided teachers, promotions have been halted for decades. They also do not have any additional benefits like provident fund etc. In some schools, working conditions and infrastructure are not very good, and aided teachers are forced to give up a part of their salary towards school expenses. So for many teachers, this merger would bring happy days.
A malicious campaign is in effect to deceive students through social media with false narratives. Here we are clearing up some of the top false narratives.
Aided colleges will Cease to Exist?
Aided institutions will continue to be in existence and will keep working on the same model if they want to. There is no compulsion on the merger and only the "willing" aided schools/colleges, have to go ahead with the merger. In simple words, there are 4 options for an aided educational institution.
Option 1 – Willingness to voluntarily surrender the entire institution along with assets and the existing staff which will make the institutions as Government Educational Institutions without any liabilities and financial burden on the exchequer.
Option 2 – Willingness to voluntarily surrender only the aid in the form of surrendering all the duly sanctioned aided posts along with aided staff, but not the assets, which will make the institutions as Private Unaided Educational Institutions.
Option 3 – Unwilling to Option 1 and Option 2 and thereby continue to exist as a Private Aided Educational Institution as per the existing rules, regulations, grant-in-aid code etc.
Option 4 (in case of a withdrawal of interest) – Withdrawing the willingness given earlier to either Option 1 or Option 2 and thereby to take back the surrendered staff and run the institution as a Private Aided Educational Institutions per the existing rules, regulation, grant-in-aid code etc.
Is the Acquisition Compulsory?
The acquisition is not compulsory at all and it's the institution's decision to stay independent or to come under Government management. Only the "Willing" institutions need to send an application in writing to initiate the process.
The institutions that are finding it hard to operate, can get into better shape through this merger. Under Government management, the infrastructure, amenities, CBSE syllabus, Better staff with all applicable norms will be provided.
Is the Merger permanent?
This is not permanent. The institution can decide to move back from the merger at any point in time. the decisions stand with the institution, totally.
More Fees Burden on Students!
APSFMRC, APSHEC boards have already decided the fee structure for private schools/colleges. So, any unaided school/college that charges extra fees, will be dealt with according to the Govt. norms. The aided school or college that choose to come under Government management will obviously have the low fee structure of the Govt school/college and have better infrastructure.
Once the school becomes unaided, students willing to continue in the unaided school, will not get the benefit of Amma Vodi?
In cases where schools are about to close down, teaching activities and mid-day meal provision will continue until students are shifted to alternative schools. Students who wish to continue in the same unaided school will get benefits of Amma Vodi, as applicable.
Staff will be absorbed in Government?
The aided staff only will need to be surrendered in the case, of a school/college that decides to surrender the Government aid. In such cases, the Staff will be absorbed by the Government and local body schools. This process will be conducted through a transparent web-counseling method.
Fee burden on Parents?
The Govt. of Andhra Pradesh through various schemes like Amma Vodi. Vidya Kanuka, Vasathi Deevena, Gorumuda, Nadu-Nedu has strengthened the infrastructure of Govt schools and that has resulted positively through student enrollments. The Government has made its intentions clear that Quality Education is a basic right for all. The fees burden of parents have been shared by the Govt. through schemes like Amma Vodi, and there is also a cap on private school and college fees. It's highly unlikely that this Govt. will burden parents with higher fees.
The Government will have to spend a lot on the teacher's salaries and their new recruitment, which might not be as par with their current status-quo?
The Government is already paying the salaries of the aided staff, which will be the same or over it. The staff will further get all the Government facilities as they will officially be a Government employee now. In a way, this is regularising the staff.
The aided institute might lose its status quo if they opt-in for the merger?
No. The aided school or college will not lose their status quo. The name/brand or original founder's name will be the same as before.
What happens to the property of the school?
All the movable/immovable property of the school will be surrendered in case of a merger and the property can only be used for public purposes or the institution's purposes.
The aided schools that decide to remain independent and become private schools, will have to obtain permission from the Government, in case they want to dispose of any property held by the institution. This decision will protect the rights of the students only. All the property can only be used for the purpose it was donated or bought or contributed for.
In case the aided school decides to surrender the aided staff and become independent, they will just have to surrender the aided staff, not any property.
Tags: aided school Andhra Pradesh


text:
Version en Español
Last updated: 09:49 / Wednesday, 7 September 2016
Interview with Marcos Pimentel
This Past Year Has Been a Lesson and a Test of BTG Pactual's Strength; They See Opportunities in Chile and Peru
Photo: Marcos Pimentel, Global Head of Fixed Income Sales at BTG Pactual and Managing Director Partner / Courtesy photo
By Meritxell Sedó
Marcos Pimentel is Global Head of Fixed Income Sales at BTG Pactual and Managing Director Partner since 2014
"When the crisis made its appearance, the company's partners and executives worked hard to strengthen the firm and establish a clear definition of the business areas in which we would like to grow"
The bank is attracting assets for two funds in which the company holds an exclusive distribution mandate. One is focused on private equity and the other in absolute returns
Fund management companies wanting to come to Latin America will be better positioned if they do so through a partner that offers a solution throughout the entire region
BTG Pactual has a platform in the region's major economies and provides international fund managers with access to solutions developed internally by the bank
BTG believes think that there is room for distributors to have access to other distribution channels in Chile such as asset managers, wealth management companies, and insurers
Until the end of November 2015, not content with being the largest independent investment bank in Latin America, BTG Pactual had ambitious plans for global expansion. All this changed overnight, the bank was forced to redesign its structure and strategy, divest part of its assets, and lay off some of its employees. BTG Pactual is now smaller, but is focused on those business areas and markets where it can stand out from its competitors. Marcos Pimentel, responsible for overall sales in the area of fixed income and managing partner in BTG Pactual, acknowledged in an exclusive interview with Funds Society that the last 10 months have been difficult for the entity, but in the end, it has served as a lesson, helping to demonstrate its strength to the market and to its clients.
The new bank has a more local than global flavor. In the past, the company had dreamt of becoming a global bank within the Wealth Management and Asset Management sectors, but these plans have been interrupted in the short term, because BTG Pactual prefers to concentrate its efforts in the areas of business and markets where the company has a competitive advantage.
"While in the past BTG Pactual had a broader business portfolio, the company now has a more concentrated and defined portfolio, having chosen to focus on those business areas where the company clearly stands out from the competition: Sales and Trading, Wealth Management, Asset Management and Investment Banking. Focusing on markets where we have a strong local presence: Brazil, Chile, Peru, Argentina, Colombia, and Mexico, where we will continue to be a benchmark," said Marcos Pimentel.
Pimentel knows the company well, as he joined Banco Pactual in 1992 as part of the IT team, working his way towards the sales and trading area by 1994. From 1999 to 2009, he worked for other institutions such as Bank of America, Standard Bank, and Credit Suisse, where he held various positions as head of sales and global markets. Educated in Rio de Janeiro, Marcos Pimentel holds a degree in Business Administration from the Federal University of Rio de Janeiro and an MBA from IBMEC.
For Marcos Pimentel, the company's partnership culture has been instrumental in, not only overcoming the crisis, but in emerging even stronger: "BTG stands out from other financial institutions in the region because it consists of partners, the partnership owns around 80% of bank capital, when the crisis made its appearance, partners and company executives worked hard to strengthen the company and to establish a clear definition of the business areas in which we would like to grow."
Pimentel points out that the capital structure was strengthened, especially in matters of corporate governance, where the main changes to make the company more accessible to investors were made, the crisis was used to implement reforms, making the bank a better institution. "It's smaller, we have significantly reduced the number of employees, we sold several non-core lines of business, for example, BSI, the private banking unit in Switzerland; we are now smaller, but we are focused on those business areas in which we want to be, being the leading investment bank in the region," he adds.
In Brazil, the bank is currently attracting assets for two funds in which the company holds an exclusive distribution mandate. One is focused on private equity and the other in absolute return, which according to Marcos Pimentel, have had tremendous success among investors. The company, which has allocated considerable resources and efforts in Peru, Chile, Brazil and Colombia, also has professionals who understand the product and know the needs of both fund managers and local clients, approaching clients differently. Given the company's experience in Latin America, BTG now seeks to build a portfolio of 4 or 5 fund managers for distribution within the region as a single package.
The funds' distribution business managed by third parties
While the funds' distribution business managed by third parties is more like managing a specialty boutique rather than a supermarket, fund management companies wanting to come to Latin America will be better positioned if they do so through a partner that offers a solution throughout the entire region. This is one of BTG Pactual's main advantages, the fact of having a platform within the region's major economies and providing access to international managers to solutions developed internally by the bank, such as fund services, legal services, technology and compliance. "As a bank, we can use the capabilities developed by BTG Pactual to help with the distribution of funds managed by third parties when selling products in the region. Having a local legal advice department in every country in which we operate helps tremendously, because each country has its own regulations. Being prepared, supported by local professionals and a structure in each of these countries is very important when you're trying to sell a product that is not standard. We are the only platform in the region covering all points of fund distribution managed by third parties; in fact, it is a key business area for BTG. We have a long history in this business; we want to grow in it, which is why we are investing greatly. We just hired Ignacio Pedrosa, a great professional in this area. I believe that it is quite obvious to fund managers and clients, who are the potential investors in these funds, that we have the experience and that we are diversified, and they know that we are good enough to serve both of those parties."
Differences in the distribution of international funds in Latin American markets
For Marcos Pimentel, Chile is a highly consolidated market, local investors have been investing in international funds for years, they have developed the technology to do so, and therefore it is the most competitive market in the region. Chile is the country with the largest number of assets allocated to offshore funds; about 22% of total assets under management are managed outside the country. It is a more mature market, but if you want to be in the business of funds' distribution managed by third parties in Latin America, you have to start in Chile. "What has happened in Chile, and what we want to do differently than in the past, is that pension funds have become the largest investors in international funds, investing about 39% of their assets in foreign funds. There are more opportunities if you invest with asset managers, wealth management companies and insurers, these investors do not have such a high share of foreign investment; overall, only 8% of the assets of all of these institutions are invested in international funds. Most distributors are focusing on offering their products through the AFPs. At BTG, we think that there is room for distributors to have access to other distribution channels: asset managers, wealth management companies, and insurers," he says.
With regards to Peru, Pimentel believes that this market offers good growth opportunity. It is the second market in terms of development in foreign investment funds in the region. Peruvian pension funds have been able to develop client sophistication; they understand funds and are prepared to invest abroad. "It's a small market, roughly half the Chilean market, but it's a market in which regulation is good, there are several competitors, but as it still isn't a mature market, we think it has potential for growth."
Colombia's case is very different; this is a market which has yet to develop. Although changes are happening gradually, pension funds are not investing as much in international funds as are Chilean or Peruvian fund managers. Local regulation allows pension funds to invest in international equity funds, but is very limited about investments in international fixed income funds. According to Marcos Pimentel, this market still needs to grow in sophistication, far from being a growth market as in Peru's case, or mature as in Chile's. But the opportunity might lie in that, in as far as investing abroad is concerned, they are at the beginning of the process, and the total of AuM´s of institutional clients is relevant".
In this banking institution's country of origin, until there is a reform in the regulation of the Brazilian market, local pension funds will continue to have many restrictions for investing abroad, which greatly reduces the channeling of investment towards international funds, because pension funds are the largest investors in the country. Meanwhile, family offices and certain individuals have more opportunities to invest abroad than do pension funds. "Brazil has many peculiarities, its law and compliance with that law is not easy for foreign professionals who don't know how to conduct business in the country. I think, especially in Brazil, BTG is the leading institution for the distribution of third party funds, since there isn't any other player as large in the market. Even so, this is a business area that will develop in the medium and long term."
Finally, Marcos points out that Mexico is a difficult market. It is the second largest market in the region, but regulation is not easy and the competition is tough. Local banks already offer sophisticated services to clients. "For us, it is the most challenging market, we have taken time to understand it and that is why we are lagging a bit behind."
Market Vision
With respect to the situation of the global economy, Marcos Pimentel is well aware that volatility levels have increased in global markets. Looking towards the second quarter of the year, he clearly sees that as the US presidential election approaches, the greater will be the climate of uncertainty in the stock markets, because the approach of each of the two candidates is diametrically opposed. In the short term, Europe's economic climate is not optimistic either, since the result of Brexit has added yet more problems to an economy that did not quite show strong signs of recovery.
Regarding the situation in Latin America, the region's dependence on the prices of raw materials and the economy of the Asian giant, seems to indicate that the evolution of the economies of Latin America will mirror China's evolution. Focusing on each of those Latin American markets, Marcos Pimentel speaks of different growth cycles. While Argentina shows small signs of improvement in relation to its previous situation, it still has many challenges to face, even though he acknowledges that they are making great strides. For its part, the Chilean economy has suffered greatly due to falling copper prices, as was to be expected from the world's largest producer of the mineral, although it is a stable economy which should perform well.
"Peru's case is impressive, it is a small economy, but with an incredibly good performance. Its currency, its growth and its unemployment rate, make the Peruvian economy the most consistent in the region," he says. "Colombia suffered somewhat, late last year and earlier this year, due to its dependence on the oil barrel price, and now with the slight price rise of crude oil, the economy has returned to its growth path. Mexico is the second largest economy in the region, but has a great dependence on the US economy, so its performance will be linked to the outcome of the US elections."
Speaking of Brazil, Marcos Pimentel mentions the huge recession hitting the country, which is compounded by the policies implemented by the previous government in the years before the crisis. But he does show some optimism, as the new interim government has managed to restore confidence slightly, and he expects, at least, a slight positive growth by next year. "The economic team appointed by Temer is top notch, I am confident that once the end of the impeachment, they will have the strength to carry out the necessary reforms and make the country regain its trajectory."
That said, in market terms, he believes the Brazilian rally is over. "The rally began when investors anticipated that there could be an impeachment process in the country, at that time, the Brazilian Real and bonds were very cheap, now that the process is almost over, most likely the rally will end as well. In the short term, inflation in Brazil is increasingly under control, so in the second half of the year, we will very probably see a cut in interest rates, which are currently close to 15%. The economic team is making great efforts to pass the necessary reforms, especially those related to public expenditure and pension plans."
In a world of low, or even negative, interest rates, Brazil is offering one of the highest rates among emerging countries, once the impeachment process is over, and investors begin to feel more comfortable about Brazil's political risk, fixed income investments will return. And this will not only happen in Brazil, markets such as Chile, Peru, and Colombia, are smaller in size than Brazil and Mexico, but they will greatly arouse investors' interest.
News / Business
Expert 2016
Henrique Cardoso Believes that Brazil has Reached a Turning Point
AMG USO 2021
Last number
See magazine
Wells Fargo´s Wealth & Investment Management is Exiting its International Segment
News / Private Banking
Citi Unifies its Global Wealth Management Business under the Leadership of Jim O'Donnell
News / Alternatives
Alternative Assets Will Grow at an Annual Rate of 9.8% up to 2025
Franklin Templeton Launches an Investment Institute Led by Stephen Dover
Now on cover
Column by Alex Gregory
Private Investments Risk Part 6: Look Around, What Do You See?
Column by Quim Abril
Portfolio Manager Diary: How Do We Contrast the Information Obtained when We Analyze a Company?
With Schroders, Pictet Asset Management and We Family Offices
Funds Society Launches its First ESG Virtual Investment Summit
FLAIA's Real Estate, Direct Lending & Private Debt Forum 2020 – Part IV is Coming Up
Ability to innovate and adapt
Santander Named Bank of the Year in Spain and Americas by The Banker Magazine
Subsidiary of Eaton Vance
Calvert Research and Management Launches the Calvert Institute for Responsible Investing
© 2021 Fundssociety.com | All rights reserved.


text:
Sie sind hier: Startseite Heros sp. Madeira
Heros sp. Madeira
The Rio Madeira is a right tributary of the Amazon River and is considered the largest tributary in the world. Its origin is in Bolivia where it is formed from the confluence of the Rio Beni and the Rio Marmoré. It flows into the Amazon in Brazil at Itacoatiara. The Rio Madeira is a white water river, purely from a geographical point of view one would expect the Heros species H. efasciatus, H. severus and H. spurius there. Concerning the dark body bands H. sp. Madeira corresponds most closely to H. efasciatus, but the coloration deviates quite considerably from the known color forms of this species. Such a pigeon blue ground color, which is already shown by juveniles and which becomes more and more intense with age, is not shown by any other Heros species known so far.
Like all Heros species this one grows well over 15 cm long, in large aquariums you can expect 5 cm more with these long-lived animals. There are known to be two brood care strategies in Heros, mouth brooding and open brooding. H. sp. Madeira is an open brooder, both parents care together for the extensive brood. In sexually mature animals, the sexes can be easily distinguished by the different facial markings; in juveniles, sex differentiation is not possible. Heros sp. Madeira originally came to Germany on private initiative; our animals are German offspring.
For our customers: the animals have code 682969 on our stocklist. Please note that we only supply to wholesalers.
Looking for fish
Fish archives
Wir nehmen den Datenschutz ernst!
We use cookies to optimize our website for you and to continuously improve it. These include cookies, which are necessary for the control of our commercial business objectives, which are used exclusively for anonymous statistical purposes, for comfort settings or for the presentation of personalised content. You decide for which category you want to allow cookies. Further information can be found in our privacy policy. Data Privacy Policy
These cookies are essential for the website. They help to make the website usable and enable, for example, security-relevant functionalities.
We collect anonymous data for statistics and analysis. These cookies enable us, for example, to track the number of visitors or the impact of certain pages and thus optimize our content for you.


According to the 2016 UBA Health Plan Survey, copay models are still the most popular, with a three-tier copay structure the most prevalent. Median retail copayments for these three-tier plans are $10 for generic drugs, $35 for preferred brand drugs (drugs on the carrier's prescription drug list) and $60 for non-preferred brand drugs (drugs not on the carrier's prescriptions drug list). While 54.5 percent of all prescription plans are copay only, approximately 40 percent of all prescription drug plans have co-insurance along with (or in lieu of) copays–a plan design that is particularly common among four-tier plans.


Pomegranate Same | Are Crabapple & Pomegranate the Same?
Repotting a gardenia bush is something you can do when moving it from outdoors to indoors, or vice versa. Find out when to repot a gardenia bush with help from the spokesperson for new plants in this free video clip.
This is Nicholas Staddon with Monrovia Nursery. Today, we're going to talk about when to repot a gardenia bush. Gardenias are great plants to have on the patio, in the house or actually in the garden. But if you have them in containers, there comes a point when they are getting a little older, they need to be repotted. Chances are they're going to tell you. As Gardenias get older, they get bigger, they get fuller. You know instinctively it's time to repot my plant. So the other thing is they can turn a little bit yellow, they're not getting enough moisture, they're not getting enough food. So there's a couple of good things to look for. The time of year that you repot your Gardenias is really important. You're going to enjoy them in the Summertime. So the best time to repot them is Spring through early Summer. Let them get settled in to that great new soil into that possible new spot as well. So you've been through the Summer, you've had a great great Summer, lots of friends over. But you know it's time to repot some of the Gardenias that you just didn't get time to do. That's fine, Autumn in the warmer climates is still a great time to upshift them. So get the right soil, move them, they'll be a lot happier, a little bit of fertilizer, a bigger container and next season, you'll have bigger, better Gardenias. So there you have it, just a few quick tips on how to make you Gardenias look better and live longer. This is Nicholas Staddon from Monrovia Nursery on when to repot a Gardenia bush.


text:
package com.hazelcast.client.map;

import com.hazelcast.client.config.ClientConfig;
import com.hazelcast.client.config.ClientNetworkConfig;
import com.hazelcast.client.test.TestHazelcastFactory;
import com.hazelcast.config.Config;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.nio.Address;
import com.hazelcast.test.HazelcastParametersRunnerFactory;
import com.hazelcast.test.annotation.ParallelTest;
import com.hazelcast.test.annotation.QuickTest;
import org.junit.Before;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
@Parameterized.UseParametersRunnerFactory(HazelcastParametersRunnerFactory.class)
@Category({QuickTest.class, ParallelTest.class})
public class DummyClientMapPartitionIteratorTest extends AbstractMapPartitionIteratorTest {

    @Before
    public void setup() {
        factory = new TestHazelcastFactory();

        Config config = getConfig();
        server = factory.newHazelcastInstance(config);
        factory.newHazelcastInstance(config);

        client = factory.newHazelcastClient(getClientConfig(server));
    }

    private static ClientConfig getClientConfig(HazelcastInstance instance) {
        Address address = instance.getCluster().getLocalMember().getAddress();
        String addressString = address.getHost() + ":" + address.getPort();
        ClientConfig clientConfig = new ClientConfig();
        ClientNetworkConfig networkConfig = new ClientNetworkConfig();
        networkConfig.setSmartRouting(false);
        networkConfig.addAddress(addressString);
        clientConfig.setNetworkConfig(networkConfig);
        return clientConfig;
    }
}

redpajama_set_name: RedPajamaGithub


text:
GMI Construction wins £40m contract to build new train manufacturing facility in the UK
WCN Editorial Team 11 Feb 2021 EUROPE BUILDINGS
GMI Construction Group has secured a contract worth £40m from Siemens Mobility to construct its new train manufacturing facility at Goole, the UK.
The project is part of the first phase of investment in Siemens Mobility's new £200m train manufacturing facility and rail supply chain village.
Under the contract, the Yorkshire-based GMI will be responsible for the construction of the main facility as well as the 4.5km of rail track, which is required for connecting the main railway line.
Siemens Mobility has also awarded a further £10m contracted to other UK suppliers including C R Reynolds (for enablement works), Clay 10 (for site visuals) and Premier Modular (for temporary offices).
GMI stated that the first trains to be manufactured in Goole will be new Tube trains for London's Piccadilly line.
The contract also includes LPA Lighting for the interior train lighting, Baker Bellfield to supply cab partition walls and I M Kelly for driver seats.
The work on the project is expected to create nearly 700 direct jobs, with a further 250 jobs during the construction phase and an additional 1,700 indirect supply chain opportunities.
Additionally, the new train manufacturing facility is planned to be opened in 2023.
Siemens Mobility Rolling Stock & Customer Services managing director Sambit Banerjee said: "We want to create more than just a rail manufacturing factory, this is about generating long-term investment, skills and jobs.
"We are actively looking for as many UK suppliers as possible to contribute to Goole's success. The appointment of GMI as main contractor, with shared values and growth ambitions for the local area, is a clear step in the right direction. Together we will make this an important and sustainable rail centre of excellence for the future."
GMI Construction wins £40m contract to build Siemens' new train manufacturing facility in the UK. (Credit: GMI Construction.)
Willmott Dixon to deliver new headquarters for West Yorkshire Police in UK
Team led by Foster + Partners wins design competition for Stockholm Central Station
Skanska to build new municipal town centre in Norway
HS2 awards framework to TK Elevator to deliver station lifts and escalators
Outline plans approved for £2.5bn Gigafactory in West Midlands, UK
Proposal for net zero housing development approved in Scotland


text:
Home About Articles Newsletter Shop
Dann Berg
sr. technical program
manager and writer
Hello, I'm Dann. I work at the intersection of engineering, finance, and cloud cost optimization. In simpler terms, I help make big, scary cloud bills not so big or scary.
Want to do a deep dive? There's more on my About page, or you can check me out on LinkedIn, Github, AngelList and Twitter/Mastodon . If you want something more personal, you can find me at the monthly NYC FinOps Meetup, which I run. It's also pretty easy to find more about me with a quick Google search. Spelling Dann with two Ns is great for SEO.
In a past life, I was a tech journalist, and my writing has appeared on MSNBC, Fox News, The Verge, Mashable, Laptop Magazine, and Tom's Guide. I also co-authored two full-length plays with my wife, including "The Floorshow", which is about a group of tap-dancing showgirls in the 1950s.
I live in Brooklyn, New York with my wife and our cat.
Selected Output
A lot of my writing can be found on the articles page. Much much older blog posts can be found on my old blog IAmDann.
I wrote a play with my wife called The Floorshow about a group of tap-dancing showgirls in the 1950s. It had a week-long run in 2019, which went really well. You should check out the sizzle reel.
For fun, I decided to register the domain dann.fun and have a little fun with it.
The code for this website and theme is publically available on Github. Feel free to borrow/steal in any way you wish.
Speaking of code, here's a small application I wrote called Daily PinBoard, which will send you a daily email showing you all the PinBoard bookmarks that you made on that day's date in previous years.
Though now defunct, I used to actively update my website Novice No Longer. I also had a podcast of the same name that people seemed to like.
Here's some of my work from when I was Reviews Editor at The Verge.
You can check out a video of my play "Diary: A One Act Play" being performed in Manhattan Repertory Theatre's 2015 Spring One Act Competition.
There was a time that I documented sticker art around New York City and published the website Stickers of NYC. I also run the neighborhood blog OhNoDoBro, although I don't really update it as often as I'd like.
Even though they're no longer available, I have fond memories of my three apps: Reader Tracker (iOS), Watcher Tracker (iOS), and WorkBurst (macOS).
Look, Simba. Everything the light touches is © 2023 by Dann Berg and powered by Hugo.


Premium cedar fence- 5/8″ x 6″ x 6″ #1 quality dog eared cedar fencing boards. 2″ x 4″ pressure treated rails; top. middle, and bottom (3 each). 4″ x 4″ pressure treated line posts set in 30″ of concrete. 4″ x 6″ pressure treated posts for gates set in 30″ of concrete. 4″ x 4″ cedar gate frames for gates 48″ or less. 1 5/8″ steel framed double drive gate for gates larger than 48″.


text:
Factceleb /biography/kenny-chesney-net-worth-albums-children-girlfriend-family
Kenny Chesney - Biography
Singer, Songwriter, Producer
Kenneth Arnold Chesney
Knoxville, Tennessee, USA
David Chesney
Karen Chandler
Jennifer Chandler (half-sister)
Gibbs High School
Multi-ethnic (Irish, English)
Ex-Spouse:
Who is Kenny Chesney?
Kenny Chesney is a singer, songwriter, producer by profession, and American by nationality. The country musician's 20 albums have been certified Gold or higher by the RIAA. Where is Kenny Chesney now?
Kenny Chesney (Image: CMT)
Kenny Chesney – Age, Parents, Siblings
Kenny Chesney's birth took place on March 26, 1968, in Knoxville, Tennessee, USA. He was born Kenneth Arnold Chesney to his mother Karen Chandler, a hairstylist, and his father David Chesney, a former elementary school teacher.
He is not the only child of his parents and has a sibling, a younger half-sister named Jennifer Chandler.
For education, Kenny Chesney attended Gibbs High School. After graduation, he went on to study at East Tennessee State University. He graduated from the same in 1990 with a degree in marketing.
His ethnicity is English and Irish.
Kenny Chesney – Girlfriend, Wife, Children, Divorce
Chesney married his longtime girlfriend Renée Zellweger on May 9, 2005. His wife Zellweger is a famous Hollywood actress. However, just after four months of marriage, they announced their plans for an annulment. Their marriage ended in annulment on 20 December 2005 rather than a divorce. They did not have any children together.
Since then he had been reported to have dated Vanessa Millon, Jamie Hill Fuller in 2008, Miss Tennessee 2005 Amy Colley and was rumored to have an affair with Sara Evans, and ESPN reporter Jenn Brown. In 2012 he was pictured at several awards with a woman named Mary Nolan.
However, Kenny Chesney seems to be single currently, although a secret romance cannot be ruled out.
Related: Madison Vandenburg - Singer, Songwriter - American Idol 2019 finalist
Kenny Chesney, and Renée Zellweger were married for 5 months (Image: Page Six)
Kenny Chesney – Career
Chesney self-released his first demo album in 1989, which sold around 1,000 copies. From the money he earned, he bought a new guitar and moved to Nashville where he performed at several local clubs.
In 1992 the aspiring singer was introduced to Troy Tomlinson, who signed him to Opryland Music Group. And just a year later Kenny Chesney was signed with Capricorn Records. His debut album In My Wildest Dreams was released in April 1994 and sold approximately 10,000 copies.
After Capricorn Records closed down, he signed with BNA Records. With the label, he released his second album All I Need to Know in 1995. Two of its songs reached the top 10 while one single peaked at number 23.
Over the years Kenny Chesney has released 20 studio albums. Some include All I Want for Christmas Is a Real Good Tan (2003), Be as You Are (2005), The Road and the Radio (2006), Lucky Old Sun (2008), Welcome to the Fishbowl (2012), Cosmic Hallelujah (2016), Songs for the Saints (2018).
Related: Lil Nas X singer of hit single Old Town Road
Kenny Chesney (Image: Nash Country Daily)
Kenny Chesney – Awards, Nominations
For his music and contribution to country music, Kenny Chesney has been awarded the Academy of Country Music Awards (1997), Triple Crown Award (2005), and four Academy of Country Music, among others.
Kenny Chesney – Net Worth, Salary
His net worth is estimated to be around $180 million while the figure for his annual salary is not known.
Kenny Chesney – Instagram, Twitter, Facebook
On social media handles including Twitter, Facebook, and Instagram Kenny Chesney is active with thousands to over a million followers. He also has a YouTube channel with over 914K subscribers.
Related: Jewel Kilcher - also a country Singer, Songwriter
Tags : Kenny Chesney singer songwriter producer country singer
socialgazette
celebritynetworth
Marshall Williams
Alexander Armstrong – Bio, Age, Family, BBC, Music, Marriage, Wife, Children, Net Worth
Liu Yifei – Boyfriend, Movies, Family, Net Worth, Children
Jerome Flynn – Bio, Age, Game of Thrones, Ser Bronn, Lena Headey, Wife, Children, Net worth
Anna Camp – Bio, Wiki, Boyfriend, Husband, Net Worth, Children, Movies, Family, Ethnicity
Kodak Black – Bio, Wiki, No Flockin, Tunnel Vision, Albums, Net Worth, Arrest, Rape, Girlfriend, Children
Utkarsh Ambudkar – Wife, Children, Parents, Ethnicity, Net Worth, Girlfriend
Ricky Garcia – Bio, Wiki, Forever in Your Mind, Disney, Movies, Girlfriend, Abuse, Net Worth, Family
Chris Sullivan – Bio, Wiki, Wife, Girlfriend, Height, This is Us, Films, Divorce, Children, Net Worth
Ricky Gervais – Bio, Age, Siblings, Show, Netflix, Humanity, Podcast, Radio, Books, Wife, Girlfriend, Activist, Net Worth
Megan Thee Stallion – Bio, Wiki, College, EP, Album, Boyfriend, Children, Net Worth
Chloe Bailey – Bio, Wiki, Chloe x Halle, Movies, Ig, Net Worth, Siblings, Boyfriend, Height
Tana Mongeau – Bio, Wiki, YouTube, TanaCon, Boyfriend, Girlfriend, Net Worth, Children, Divorce
Johnny Carson – Bio, Age, Movies, The Tonight Show, Last Show, Wife, Children, Death, Net Worth
Jamie Campbell Bower – Girlfriend, Songs, Ethnicity, Wife, Siblings
Ella Mai – Bio, Wiki, Songs, EP, Album, Change, Tour, Awards, Net Worth, Boyfriend
Naomi Scott – Bio, Age, Movies, Lemonade Mouth, Power Rangers, Aladdin, Charle's Angels, EP, Husband, Divorce, Net Worth
Lucky Daye – Singer, Net Worth, Songs, Girlfriend, Family
Vance Joy – Bio, Age, Siblings, Football, Album, Riptide, Tour, Girlfriend, Awards, Net Worth
Toby Sebastian – Pugh, Bio, Wiki, Height, GOT, Girlfriend, Wife, Net Worth, Siblings, Children
Layton Greene – Wiki, Net Worth, Family, Boyfriend, Songs
Rozonda Thomas – Bio, Wiki, Son, TLC, Parents, Height, Boyfriend, Husband, Net Worth, Ethnicity


From the 2003 album, Learn Yourself. This sophomore LP by this Sydney band had a number of hits. Ian Mussington guests on percussion on this track.
This entry was posted in Rock and tagged The Beautiful Girls. Bookmark the permalink.


text:
<?php

namespace Nord\Lumen\Elasticsearch\Search\Query\Traits;

/**
 * Trait HasFields
 * @package Nord\Lumen\Elasticsearch\Search\Query\Traits
 */
trait HasFields
{

    /**
     * @var array
     */
    protected $fields = [];

    /**
     * @return array
     */
    public function getFields()
    {
        return $this->fields;
    }

    /**
     * @param array $fields
     *
     * @return $this
     */
    public function setFields($fields)
    {
        $this->fields = $fields;

        return $this;
    }
}