为了账号安全,请及时绑定邮箱和手机立即绑定

PHP - 将 16 位数字模式映射到二进制块

PHP - 将 16 位数字模式映射到二进制块

PHP
一只甜甜圈 2023-11-05 15:54:35
我正在开发一个用于鼓声音的步进音序器程序。它采用 16 位二进制模式示例:"1010010100101001",然后将二进制模式分解为如下所示的块:10, 100, 10, 100, 10, 100, 1。然后,它根据有多少个块为每个块分配一个时间值。数字。原因是有些鼓样本声音发出的声音比 1 节拍的长度长,所以分块解决了这部分。(例如,如果节拍为 60bpm 1 位 = 1 秒)“10”= 2 秒,“100”= 3 秒,“1”= 秒。(允许我在模式中将声音修剪到适当的长度,并使用 ffmpeg 将其连接成最终的 wav)另外 1 = 鼓击 / 0 = 无声击......这种方法非常适合我的需要。现在我可以制作完美的节拍循环......并且我想在其之上添加速度模式层,以允许幽灵音符/为我的鼓模式添加人的感觉/动态。我决定对速度模式使用 0、1、2、3、4 值系统。“0”= 0% 体积,“1”= 25% 体积,“2”= 50% 体积,“3”= "0"= 0% 体积,"1"= 25% 体积,"2"= 50% 体积,"3"= 75% 体积,"4"= %100 体积。(音量为 0,这样我就可以添加打开踩镲/铙钹碰撞硬停止,而二进制模式中的 0 则不会这样做)因此,除了"1111111111111111"模式外,您还会看到一个速度模式层,例如"4242424242424242"(该速度模式交替使用 100% 击打和 50% 击打,使用踩镲听起来不错/就像真正的鼓手)我使用 PHP 将 16 位二进制模式分解为一个块数组。"1001110011110010"将是['100','1','1','100','1','1','1','100','10']现在通过循环,我需要将 0、1、2、3、4 位数字的另一个 16 位数字层模式映射到每个块的第一位数字。示例1:Velocity Pattern: '4242424242424242'Binary Pattern: '1001110011110010'Array = ['100','1','1','100','1','1','1','100','10']'100' = 4 (1st digit in 4242424242424242 pattern)'1' = 2 (4th digit in 4242424242424242 pattern)'1' = 4 (5th digit in 4242424242424242 pattern)'100' = 2 (6th digit in the 4242424242424242 pattern)'1' = 4 (9th digit in the 4242424242424242 pattern)'1' = 2 (10th digit in the 4242424242424242 pattern)'1' = 4 (11th digit in the 4242424242424242 pattern)'100' = 2 (12th digit in the 4242424242424242 pattern)'10' = 4 (15th digit in the 4242424242424242 pattern)示例2:Velocity Pattern: '4242424242424242'Binary Pattern: '1111111111111111'Array = ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1']
查看完整描述

2 回答

?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

从您给出的示例来看,您似乎需要速度数组中的相应值以及节拍数组中 1 之间的持续时间。


此代码首先通过将 1 拆分为数组,然后过滤掉 0 来提取 1。所以


$beat_pattern = '1001110011110010';

$velocity_pattern = '4242424242424242';


$beat = array_filter(str_split($beat_pattern));

会屈服......$beat


Array

(

    [0] => 1

    [3] => 1

    [4] => 1

    [5] => 1

    [8] => 1

    [9] => 1

    [10] => 1

    [11] => 1

    [14] => 1

)

然后它依次获取每个条目,通过查看下一个键并减去两个键来计算长度,还使用索引来获得相应的速度。


要考虑以 0 开头的情况,您可以循环到 1 的第一个实例并输出同一元素的速度模式......


$beat_pattern = '1001110011110010';

$velocity_pattern = '4242424242424242';


$beat = array_filter(str_split($beat_pattern));

$beatKeys = array_keys($beat);


// For the leading 0's

for( $i = 0; $i < $beatKeys[0]; $i++ )  {

    echo "1-". $velocity_pattern[$i] . PHP_EOL;

}


for ( $i = 0; $i < count($beatKeys); $i++ ) {

    echo ($beatKeys[$i+1] ?? strlen($beat_pattern)) - $beatKeys[$i] . "-".

            $velocity_pattern[$beatKeys[$i]] . PHP_EOL;

}

给出(长度-速度)...


3-4

1-2

1-4

3-2

1-4

1-2

1-4

3-2

2-4


查看完整回答
反对 回复 2023-11-05
?
料青山看我应如是

TA贡献1772条经验 获得超8个赞

假设您有两个输入字符串:


$binary   = '0001000110101001';

$velocity = '4231423142314231';

如果使用正则表达式分析模式,则可以在一次操作中获取所有组成部分,包括模式开始时的停顿(基本上是 0% 的音量节拍)。


$index = 0;

preg_match_all('/^0+|10*/', $binary, $parts);

foreach ($parts[0] as $part) {

    $duration = strlen($part);                   // How many beats

    $volume = $part[0] ? $velocity[$index] : 0;  // The corresponding volume number

    $index += $duration;

}

为了进一步发展这一点,在我看来,为模式生成适当的数据数组是可行的,如果你愿意,你可以打包这个功能:


function drumPattern($binary, $velocity) {

    $output = [];

    $index = 0;

    preg_match_all('/^0+|10*/', $binary, $parts);

    foreach ($parts[0] as $part) {

        $duration = strlen($part);

        $output[] = [

            'duration' => $duration,

            'volume' => $part[0] ? $velocity[$index] : 0

        ];

        $index += $duration;

    }

    return $output;

}


drumPattern($binary, $velocity);

生成以下输出


Array

(

    [0] => Array

        (

            [duration] => 3

            [volume] => 0

        )


    [1] => Array

        (

            [duration] => 4

            [volume] => 1

        )


    [2] => Array

        (

            [duration] => 1

            [volume] => 1

        )


    [3] => Array

        (

            [duration] => 2

            [volume] => 4

        )


    [4] => Array

        (

            [duration] => 2

            [volume] => 3

        )


    [5] => Array

        (

            [duration] => 3

            [volume] => 4

        )


    [6] => Array

        (

            [duration] => 1

            [volume] => 1

        )


)


查看完整回答
反对 回复 2023-11-05
  • 2 回答
  • 0 关注
  • 116 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信