Точная синхронизация в iOS

Мысль [приблизительно 114] @dp AnonCast и решенный для испытания его немного. Вот то, что я придумываю, который мог бы быть полезен для некоторых:

// using the concepts of dp's AnonCast
static Func<T> TypeCurry<T>(Func<object> f, T type)
{
    return () => (T)f();
}

И вот то, как это могло бы использоваться:

static void Main(string[] args)
{

    var getRandomObjectX = TypeCurry(GetRandomObject,
        new { Name = default(string), Badges = default(int) });

    do {

        var obj = getRandomObjectX();

        Console.WriteLine("Name : {0} Badges : {1}",
            obj.Name,
            obj.Badges);

    } while (Console.ReadKey().Key != ConsoleKey.Escape);

}

static Random r = new Random();
static object GetRandomObject()
{
    return new {
        Name = Guid.NewGuid().ToString().Substring(0, 4),
        Badges = r.Next(0, 100)
    };
}
16
задан Itamar Katz 19 December 2010 в 22:00
поделиться

2 ответа

Хорошо, у меня есть несколько ответов после еще нескольких тестов, поэтому я делюсь ими с любыми заинтересованными.

Я поместил переменную для измерения временных интервалов между тиками в методе play (метод, который фактически отправляет сообщение play объекту AVAudioPlayer), и как мое простое сравнение с внешним эксперимент показал, что 60 ударов в минуту были слишком медленными - я получил эти временные интервалы (в секундах):

1.004915
1.009982
1.010014
1.010013
1.010028
1.010105
1.010095
1.010105

Мой вывод состоял в том, что некоторые служебные данные истекают после подсчета каждого интервала в 1 секунду, и это дополнительное время (около 10 мсек) накапливается до заметной величины через несколько десятков секунд - что очень плохо для метронома. Поэтому вместо того, чтобы измерять интервал между вызовами, я решил измерить общий интервал с первого вызова, чтобы ошибка не накапливалась. Другими словами, я заменил это условие:

while (continuePlaying && ((currentTime0 + [duration doubleValue]) >= currentTime1)

на это условие:

while (continuePlaying && ((_currentTime0 + _cnt * [duration doubleValue]) >= currentTime1 ))

, где теперь _currentTime0 и _cnt являются членами класса (извините, если это c ++ Жаргон, я новичок в Obj-C), первый содержит метку времени первого вызова метода, а последний - int счетное число тиков (== вызовов функций). Это привело к следующим измеренным временным интервалам:

1.003942
0.999754
0.999959
1.000213
0.999974
0.999451
1.000581
0.999470
1.000370
0.999723
1.000244
1.000222
0.999869

, и даже без вычисления среднего значения очевидно, что эти значения колеблются около 1,0 секунды (а среднее значение близко к 1,0 с точностью, по крайней мере, в миллисекундах) ).

Я буду рад услышать больше информации о том, что вызывает дополнительное время - 10 мсек звучит как вечность для современного процессора - хотя я не знаком со спецификациями процессора iPod (это iPod 4G, и Википедия говорит, что CUP - это PowerVR SGX GPU 535 при 200 МГц)

21
ответ дан 30 November 2019 в 17:14
поделиться

Использование цикла while и режима сна для измерения времени метронома не является надежным способом решения этой проблемы, поскольку, как вы видели, он может вызывать колебания и смещения. Я считаю, что стандартным способом решения этой проблемы является использование Core Audio (так или иначе) для подачи непрерывного аудиопотока, содержащего тики метронома, разделенные правильной величиной молчания между ними, в зависимости от темпа. Поскольку вы знаете точную частоту дискретизации, вы можете очень точно рассчитать время тиков. К сожалению, создать аудио самостоятельно немного сложнее, чем то, что вы пытаетесь сделать, но этот вопрос Stackoverflow может помочь вам начать.

1
ответ дан 30 November 2019 в 17:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: