2015-07-14 6 views
-1

Я пытаюсь получить содержимое из аудиофайла и записать их в другой аудиофайл - за исключением того, что выход должен начинаться с нормальной скорости, а затем замедляться по мере того, как время прогрессирует и заканчивается на половине его первоначальной скорости. Я пытаюсь использовать интерполяционный подход Лагранжа, но, похоже, не совсем прав. Я остановился на структуре, чтобы просто посмотреть, что я делаю. Вот мой код:Постепенно замедляйте аудиофайл с нормальной скорости на половину скорости?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main() { 
    FILE *original, *slowdown; 
    unsigned int ChunkSize, Subchunk1Size, Subchunk2Size, RIFFSize, fmtSize, dataSize, SampleRate, ByteRate; 
    unsigned short int AudioFormat, NumChannels, BlockAlign, BitsPerSample; 
    char ChunkID[5], Format[5], Subchunk1ID[5], Subchunk2ID[5]; 
    ChunkID[4] = '\0'; 
    Format[4] = '\0'; 
    Subchunk1ID[4] = '\0'; 
    Subchunk2ID[4] = '\0'; 
    char path[FILENAME_MAX], dslowdown[FILENAME_MAX]; 
    printf("Enter path to Alejandro_project.wav file:\n"); 
    scanf("%s", path); 
    strcpy(dslowdown, path); 
    dslowdown[strlen(path) - 21] = '\0'; 
    strcat(dslowdown, "Alejandro_fast.wav"); 
    original = fopen(path, "rb"); 
    if (!original) { 
     printf("Error: file does not exist.\n"); 
     return EXIT_FAILURE; 
    } 
    fread(ChunkID, 4, 1, original); 
    fread(&ChunkSize, 4, 1, original); 
    fread(Format, 4, 1, original); 
    fread(Subchunk1ID, 4, 1, original); 
    fread(&Subchunk1Size, 4, 1, original); 
    fread(&AudioFormat, 2, 1, original); 
    fread(&NumChannels, 2, 1, original); 
    fread(&SampleRate, 4, 1, original); 
    fread(&ByteRate, 4, 1, original); 
    fread(&BlockAlign, 2, 1, original); 
    fread(&BitsPerSample, 2, 1, original); 
    fread(Subchunk2ID, 4, 1, original); 
    fread(&Subchunk2Size, 4, 1, original); 
    fseek(original, 0, SEEK_SET); 
    slowdown = fopen(dslowdown, "wb"); 
    fwrite(ChunkID, 4, 1, slowdown); 
    fwrite(&ChunkSize, 4, 1, slowdown); 
    fwrite(Format, 4, 1, slowdown); 
    fwrite(Subchunk1ID, 4, 1, slowdown); 
    fwrite(&Subchunk1Size, 4, 1, slowdown); 
    fwrite(&AudioFormat, 2, 1, slowdown); 
    fwrite(&NumChannels, 2, 1, slowdown); 
    fwrite(&SampleRate, 4, 1, slowdown); 
    fwrite(&ByteRate, 4, 1, slowdown); 
    fwrite(&BlockAlign, 2, 1, slowdown); 
    fwrite(&BitsPerSample, 2, 1, slowdown); 
    fwrite(Subchunk2ID, 4, 1, slowdown); 
    fwrite(&Subchunk2Size, 4, 1, slowdown); 
    short int t[4], audio[Subchunk2Size/2], f[4]; 
    for (i = 0; i < Subchunk2Size/2; i++) { 
     fread(&data, 2, 1, original); 
     audio[i] = data; 
    } 
    for (i = 0; i < sizeof(t)/2; i++) 
     t[i + 1] = t[i] + (11.41 - t[i])/11.41 * (1.0/22050.0) + t[i]/11.41 * (0.4/22050.0); 
    for (i = 0; i < sizeof(f)/2; i++) { 
     f[i + 1] = ((t[i] - t[i - 1]) * (t[i] - t[i + 1]) * (t[i] - t[i + 2]))/((t[i - 2] - t[i - 1]) * (t[i - 2] - t[i + 1]) * (t[i - 2] - t[i + 2])) * f[i - 2] + ((t[i] - t[i - 2]) * (t[i] - t[i + 1]) * (t[i] - t[i + 2]))/((t[i - 1] - t[i - 2]) * (t[i - 1] - t[i + 1]) * (t[i - 1] - t[i + 2])) * f[i - 1] + ((t[i] - t[i - 2]) * (t[i] - t[i - 1]) * (t[i] - t[i + 2]))/((t[i + 1] - t[i - 2]) * (t[i + 1] - t[i - 1]) * (t[i + 1] - t[i + 2])) * f[i + 1] + ((t[i] - t[i - 2]) * (t[i] - t[i - 1]) * (t[i] - t[i + 2]))/((t[i + 1] - t[i - 2]) * (t[i + 1] - t[i - 1]) * (t[i + 1] - t[i + 2])) * f[i + 2]; 
    } 
    for (i = 0; i < Subchunk2Size; i++) { 
     audio[i] = audio[f[i]]; 
    } 
    fwrite(audio, sizeof(audio), 1, slowdown); 
    fseek(slowdown, 40, SEEK_SET); 
    fwrite(&Subchunk2Size, 4, 1, slowdown); 
    fseek(slowdown, 40, SEEK_SET); 
    fwrite(audio, sizeof(audio), 1, slowdown); 
    fseek(slowdown, 4, SEEK_SET); 
    fwrite(&ChunkSize, 4, 1, slowdown); 
    fclose(slowdown); 
    fclose(original); 
    return EXIT_SUCCESS; 
} 
+0

Данная программа не компилируется. i и данные не определены. Используйте -Wall при компиляции и исправлении всех предупреждений. После того, как вы получите его для компиляции, вы можете начать отладку. – user464502

ответ

0

Я понял. Я вернулся к структуре и изменил математику.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main() { 
    FILE *original, *fast, *slow, *slowdown; 
    unsigned int RIFFSize, fmtSize, dataSize; 
    struct WAVE { 
     char ChunkID[4]; 
     unsigned int ChunkSize; 
     char Format[4]; 
     char Subchunk1ID[4]; 
     unsigned int Subchunk1Size; 
     unsigned short int AudioFormat; 
     unsigned short int NumChannels; 
     int SampleRate; 
     int ByteRate; 
     unsigned short int BlockAlign; 
     unsigned short int BitsPerSample; 
     char Subchunk2ID[4]; 
     unsigned int Subchunk2Size; 
    } o, f, s, sd; 
    char path[FILENAME_MAX], dfast[FILENAME_MAX], dslow[FILENAME_MAX], dslowdown[FILENAME_MAX]; 
    printf("Enter the path to an input WAVE (.wav) file:\n"); 
    gets(path); 
    strcpy(dfast, path); 
    dfast[strlen(path) - 4] = '\0'; 
    strcpy(dslow, dfast); 
    strcpy(dslowdown, dslow); 
    strcat(dfast, "_fast.wav"); 
    strcat(dslow, "_slow.wav"); 
    strcat(dslowdown, "_slowdown.wav"); 
    original = fopen(path, "rb"); 
    if (!original) { 
     printf("Error: file does not exist.\n"); 
     return EXIT_FAILURE; 
    } 
    fread(&o, 44, 1, original); 
    fseek(original, 0, SEEK_SET); 
    fread(&f, 44, 1, original); 
    fseek(original, 0, SEEK_SET); 
    fread(&s, 44, 1, original); 
    fseek(original, 0, SEEK_SET); 
    fread(&sd, 44, 1, original); 
    fmtSize = o.Subchunk1Size + 8; 
    dataSize = o.Subchunk2Size + 8; 
    RIFFSize = o.ChunkSize + 8 - (fmtSize + dataSize); 
    printf("Characteristics of %s:\n", path); 
    printf("RIFF Size:  %d\n", RIFFSize); 
    printf("fmt Size:  %d\n", fmtSize); 
    printf("data Size:  %d\n\n", dataSize); 
    printf("ChunkID:  %.4s\n", o.ChunkID); 
    printf("ChunkSize:  %d\n", o.ChunkSize); 
    printf("Format:  %.4s\n\n", o.Format); 
    printf("Subchunk1ID: %.4s\n", o.Subchunk1ID); 
    printf("Subchunk1Size: %d\n", o.Subchunk1Size); 
    printf("AudioFormat: %d\n", o.AudioFormat); 
    printf("NumChannels: %d\n", o.NumChannels); 
    printf("SampleRate: %d\n", o.SampleRate); 
    printf("ByteRate:  %d\n", o.ByteRate); 
    printf("BlockAlign: %d\n", o.BlockAlign); 
    printf("BitsPerSample: %d\n\n", o.BitsPerSample); 
    printf("Subchunk2ID: %.4s\n", o.Subchunk2ID); 
    printf("Subchunk2Size: %d\n\n", o.Subchunk2Size); 
    fseek(original, 0, SEEK_SET); 
    fast = fopen(dfast, "wb"); 
    f.SampleRate = o.SampleRate * 2; 
    f.ByteRate = 2 * f.SampleRate; 
    fseek(fast, 0, SEEK_SET); 
    fwrite(&f, 44, 1, fast); 
    fmtSize = f.Subchunk1Size + 8; 
    dataSize = f.Subchunk2Size + 8; 
    RIFFSize = f.ChunkSize + 8 - (fmtSize + dataSize); 
    printf("\nCharacteristics of %s:\n", dfast); 
    printf("RIFF Size:  %d\n", RIFFSize); 
    printf("fmt Size:  %d\n", fmtSize); 
    printf("data Size:  %d\n\n", dataSize); 
    printf("ChunkID:  %.4s\n", f.ChunkID); 
    printf("ChunkSize:  %d\n", f.ChunkSize); 
    printf("Format:  %.4s\n\n", f.Format); 
    printf("Subchunk1ID: %.4s\n", f.Subchunk1ID); 
    printf("Subchunk1Size: %d\n", f.Subchunk1Size); 
    printf("AudioFormat: %d\n", f.AudioFormat); 
    printf("NumChannels: %d\n", f.NumChannels); 
    printf("SampleRate: %d\n", f.SampleRate); 
    printf("ByteRate:  %d\n", f.ByteRate); 
    printf("BlockAlign: %d\n", f.BlockAlign); 
    printf("BitsPerSample: %d\n\n", f.BitsPerSample); 
    printf("Subchunk2ID: %.4s\n", f.Subchunk2ID); 
    printf("Subchunk2Size: %d\n\n", f.Subchunk2Size); 
    short int data; 
    unsigned int i; 
    for (i = 0; i < f.Subchunk2Size/2; i++) { 
     fread(&data, 2, 1, original); 
     fwrite(&data, 2, 1, fast); 
    } 
    fclose(fast); 
    fseek(original, 0, SEEK_SET); 
    slow = fopen(dslow, "wb"); 
    s.SampleRate = o.SampleRate/2; 
    s.ByteRate = 2 * s.SampleRate; 
    fseek(slow, 0, SEEK_SET); 
    fwrite(&s, 44, 1, slow); 
    printf("\nCharacteristics of %s:\n", dslow); 
    printf("RIFF Size:  %d\n", RIFFSize); 
    printf("fmt Size:  %d\n", fmtSize); 
    printf("data Size:  %d\n\n", dataSize); 
    printf("ChunkID:  %.4s\n", s.ChunkID); 
    printf("ChunkSize:  %d\n", s.ChunkSize); 
    printf("Format:  %.4s\n\n", s.Format); 
    printf("Subchunk1ID: %.4s\n", s.Subchunk1ID); 
    printf("Subchunk1Size: %d\n", s.Subchunk1Size); 
    printf("AudioFormat: %d\n", s.AudioFormat); 
    printf("NumChannels: %d\n", s.NumChannels); 
    printf("SampleRate: %d\n", s.SampleRate); 
    printf("ByteRate:  %d\n", s.ByteRate); 
    printf("BlockAlign: %d\n", s.BlockAlign); 
    printf("BitsPerSample: %d\n\n", s.BitsPerSample); 
    printf("Subchunk2ID: %.4s\n", s.Subchunk2ID); 
    printf("Subchunk2Size: %d\n\n", s.Subchunk2Size); 
    for (i = 0; i < s.Subchunk2Size/2; i++) { 
     fread(&data, 2, 1, original); 
     fwrite(&data, 2, 1, slow); 
    } 
    fclose(slow); 
    fseek(original, 0, SEEK_SET); 
    slowdown = fopen(dslowdown, "wb"); 
    unsigned int samples; 
    fseek(original, 44, SEEK_SET); 
    fseek(slowdown, 44, SEEK_SET); 
    samples = o.Subchunk2Size/2; 
    double dt = 1/22050.0, out, space, t; 
    double point[4], ta, tb, tc, td; 
    unsigned int stamp; 
    unsigned int count = 0; 
    short int fd[4], audio; 
    t = dt; 
    space = dt; 
    point[0] = (-1.0) * (-2.0) * (-3.0) * dt; 
    point[1] = (1.0) * (-1.0) * (-2.0) * dt; 
    point[2] = (2.0) * (1.0) * (-1.0) * dt; 
    point[3] = (3.0) * (2.0) * (1.0) * dt; 

    while (t < (samples - 2) * dt) { 
     stamp = (int)(t/dt - 1); 
     fseek(original, 44 + stamp * 2, SEEK_SET); 
     for(i = 0; i < 4; i++) { 
      fread(&fd[i], 2, 1, original); 
    } 
     ta = stamp * dt; 
     tb = (stamp + 1) * dt; 
     tc = (stamp + 2) * dt; 
     td = (stamp + 3); 
     out = (((t - tb) * (t - tc) * (t - td))/(point[0])) * fd[0] + (((t - ta) * (t - tc) * (t - td))/(point[1])) * fd[1] + (((t - ta) * (t - tb) * (t - td))/(point[2])) * fd[2] + (((t - ta) * (t - tb) * (t - tc))/(point[3])) * fd[3]; 
     audio = (short int)(out); 
     fwrite(&audio, 2, 1, slowdown); 
     space = (((samples - 1) * dt - t)/((samples - 1) * dt)) * dt + (t/((samples - 1) * dt)) * .4 * dt; 
     t += space; 
     count++; 
    } 
    sd.Subchunk2Size = count * 2; 
    sd.ChunkSize = 36 + sd.Subchunk2Size; 
    fseek(slowdown, 0, SEEK_SET); 
    fwrite(&sd, 44, 1, slowdown); 
    fmtSize = sd.Subchunk1Size + 8; 
    dataSize = sd.Subchunk2Size + 8; 
    RIFFSize = sd.ChunkSize + 8 - (fmtSize + dataSize); 
    printf("\nCharacteristics of %s:\n", dslowdown); 
    printf("RIFF Size:  %d\n", RIFFSize); 
    printf("fmt Size:  %d\n", fmtSize); 
    printf("data Size:  %d\n\n", dataSize); 
    printf("ChunkID:  %.4s\n", sd.ChunkID); 
    printf("ChunkSize:  %d\n", sd.ChunkSize); 
    printf("Format:  %.4s\n\n", sd.Format); 
    printf("Subchunk1ID: %.4s\n", sd.Subchunk1ID); 
    printf("Subchunk1Size: %d\n", sd.Subchunk1Size); 
    printf("AudioFormat: %d\n", sd.AudioFormat); 
    printf("NumChannels: %d\n", sd.NumChannels); 
    printf("SampleRate: %d\n", sd.SampleRate); 
    printf("ByteRate:  %d\n", sd.ByteRate); 
    printf("BlockAlign: %d\n", sd.BlockAlign); 
    printf("BitsPerSample: %d\n\n", sd.BitsPerSample); 
    printf("Subchunk2ID: %.4s\n", sd.Subchunk2ID); 
    printf("Subchunk2Size: %d\n\n", sd.Subchunk2Size); 
    printf("\nAs you can see, the only differences between the fast/slow output files and the original input file are the sample rate and byte rate. However, the slowdown output file differs from the original input file not only in its sample rate and byte rate, but also in its data size, Chunk size, and Subchunk2 size.\n"); 
    fclose(slowdown); 
    fclose(original); 
    return EXIT_SUCCESS; 
}