-8

更新 2

我想制作一个可以在我的 pic 18f4550 上播放声音(可以说是红色、绿色和蓝色)的程序,有一个扬声器连接到 picdem,这部分工作正常,我用微芯片版本 6.83 用 C 编写了以下程序编译器。

当我说红色时(这有一个位模式),我需要检索 .wav 文件的位值。我的正确问题是,如何获取 .wav 文件的位值。

void main (void)
{   

    TRISD = 0x00;               // PORTD  als uitgang
    TRISB = 0b00110000;         // RB4 en RB5 als ingang
    TRISA = 0x00;               // RA output
        
    RCONbits.IPEN = 0;  // interrupts
    INTCONbits.GIE = 1; 
    INTCONbits.RBIE = 1;
    
    while(1)
    {   
        _asm sleep _endasm  
    }
}

#pragma interrupt ISR
void ISR (void)
{
    int red[] = {bit values off sound red???};
    int blue[] = {bit values off sound green???};
    int green[] = {bit values off sound blue???};


    if (INTCONbits.RBIF==1)
    {
        if(PORTBbits.RB5==0)        // S3 pressed?
        {
            int i = 0;
            int b;
            do {
                LATAbits.LATA2 = rood[i];
                LATDbits.LATD1 ^= 1;
                b = 0;

                //do-while voor de frequentie (1500 is de freq)
                do {
                    b++;
                }while(b <= 2000);

                i++;
            }while(rood[i] <= 50);

            //LATDbits.LATD1 ^= 1;      // D2 togglen

        }
        
    }   
    INTCONbits.RBIF = 0;
}
4

3 回答 3

2

对原始问题的回答: 您要求的“红色频率,以位表示”是 480 到 405 THz,因此以 111100000 到 110010101 为单位。但您也说“它以纳米为单位定义”,即 630 到 740nm这是二进制的 1001110110 到 1011100100。如果要驱动带波形的扬声器,则需要采样音频波形或语音合成芯片。在任何一种情况下,我给你的二进制值都与“红色”这个词的声音无关,它需要更多的位来表示任何可听的声音(例如,在 16 kbps PCM 下至少 0.5 秒将是 8 kbp = 1 KB)。

用二进制表示颜色的另一种方法是 RGB 系统,其中红色为 0xFF0000,二进制为 111111110000000000000000。

回答有关如何在 wav 文件中获取位的问题 首先我们必须确定 wav 文件的存储位置。它可以存储为 PIC 中的 const 数组,也可以存储在外部存储设备中,您必须通过某种串行或并行总线读取它。由于 PIC18F4550 有 32k 字节的闪存,如果您的程序相当小,则可能有足够的空间容纳 3 个 wav 文件。

然后我们必须确定硬件将如何播放声音。您似乎试图通过移位来从位端口发送一个字节值。但是要做到这一点,我们需要更多地了解硬件,因为您不能将扬声器连接到位端口并期望声音输出(无论如何都不能没有进一步处理 PCM 信号 - 您是否正在尝试1 位 DAC设计?如果是这样,这里有进一步的注释,但这是非常雄心勃勃的)。

除此之外,wav 文件中的位值将通过获取文件中的每个样本(8 位?)并使用按位与操作将掩码值 0x01 轮换来确定设置了哪些位来获得。

于 2011-05-03T12:25:44.293 回答
1

构成某些英语字母编码的二进制值与构成某人说出编码单词的声音的采样版本的 PCM 值之间绝对没有相关性。

如果您想播放某人说“红色”的声音,您首先必须对其进行采样并将结果位存储在某处,然后以适当的比特率将它们提供给您的输出。采样的声音可能比“红色”的 ASCII 表示(即 24 位)大得多。

有包含此类样本的集成芯片,实际上可以在给定 ASCII 编码字的情况下产生声音,一个例子就是这个。除非您将这样的芯片连接到您的 MCU,否则您的问题没有多大意义。

于 2011-05-02T17:50:00.873 回答
1

根据您在评论中所说的话,听起来您想从字符串的 ASCII 表示中获取位流,例如"red". 您可以通过遍历字符串的每个字符,然后遍历每个位位置来做到这一点:

const char *str = "I hate programming";

// Loop over each character
for (i = 0; i < strlen(str); i++)
{
    // Loop over each bit
    for (j = 0; j < 8; j++)
    {
        // Extract bit #j of character i, using bit-shift and mask
        bit = (str[i] >> j) & 1;

        // bit will be 0 or 1, so do something with it here
    }
}

如果您希望每个字符中的位以相反的顺序排列,那么只需反转内部 ( j) 循环的顺序即可。

请注意,正如@unwind 在他的回答中所说,这与实际为口语生成音频波形无关。

于 2011-05-02T17:41:44.640 回答