0

I have been trying to make a program that takes .raw files and outputs .raw file but with echo (echo after 1 second). The problem is, that while in CB my code works perfectly fine, in Visual the echo is not delayed by one second, but not delayed at all (it overlaps with original sound, you can hear it tho). I have no idea why is that, but it seems, that Visual omits "i" from for loop in threadFun function. Lastly, I have to do that in Visual, so answers like "do that in CB then" are not pleasantly seen

#include <iostream>
#include <fstream>
#include <vector>
#include <string.h>
#include <thread>

using namespace std;


void threadFun(vector <vector<char>> &buffer3, vector <vector<char>> buffer2, int x, int dataPerThread, int Size, int mult, int echoNum)
{
    int var = x - dataPerThread;
    for (x; x > var; x--)
    {
        for (int i=1; i <= echoNum; i++)
        {
            buffer3[x / Size + i][x % Size] += buffer2[x / Size][x % Size] * mult;
        }
    }
}

void tripleEcho(int nrOfThreads, std::string filename, int Size, float wwycisz)
{
    vector<thread> threads;

    vector <vector<char>> buffer2; //wektor oryginalnej, wczytanej œcie¿ki dŸwiêkowej
    vector <vector<char>> buffer3; //wektor bufora wyjœciowego
    vector <char> bufferempty; //wektor pusty o rozmiarze jednego bitrate'u

    for (int i = 0; i < Size; i++)
        bufferempty.push_back(0); //uzupelnianie pustego wektora o rozmiarze jednego bitrate'u

    int counter1 = 0; //indeks pomocniczy do operacji na wektorach
    int rozmiarDanych = 0; //ilosc wczytanych znaków
    char buf; //zmienna pomocnicza

    ifstream inFile;
    ofstream outFile;

    inFile.open(filename, ios::binary); //otwarcie pliku wejœciowego jako strumieñ
    outFile.open("output.raw", ios::binary); //otwarcie pliku wyjœciowego jako strumieñ

    while (!inFile.eof())
    {
        buffer2.push_back(bufferempty); //dodanie nowego, pustego wektora oryginalnej œcie¿ki dŸwiêkowej
        buffer3.push_back(bufferempty); //dodanie nowego, pustego wektora do bufora wyjœciowego

        for (int i = 0; i < Size && !inFile.eof(); i++)
        {
            inFile.read((char*)&buf, sizeof(char)); //wczytanie danych z pliku wejœciowego
            buffer2[counter1][i] = buf; //zapisanie odczytanego znaku do wektora oryginalnej œcie¿ki
            buffer3[counter1][i] = buf; //zapisanie odczytanego znaku do wektora bufora wyjsciowego
            rozmiarDanych++; //zwiêkszenie iloœci przeczytanych znaków
        }
        counter1++; //zwiêkszenie indeksu wektora pomocniczego
        cout<<"a"<<endl;
    }

    bool koniec = false; //zmienna pomocnicza do zakoñczenia efektu nieskoñczonego echa
    float mult = wwycisz; //wspolczynnik wyciszania

    int sizeOfData = rozmiarDanych;
    int dataPerThread = rozmiarDanych / nrOfThreads;

    for (int i = 0; i < 3; i++)
    {
        buffer3.push_back(buffer3[counter1 - 1]); //nak³adaj¹c kolejne echo opóŸnione o bitrate, trzeba dodaæ kolejny,
                                                  //pusty wektor o rozmiarze opóŸnienia
    }

    if (rozmiarDanych / nrOfThreads < 1)
    {
        for (int x = rozmiarDanych % nrOfThreads; x > 0; x--)
        {
            threads.push_back(thread(threadFun, ref(buffer3), buffer2, sizeOfData, dataPerThread, Size, mult, 3));
        }
    }
    else if(rozmiarDanych / nrOfThreads == 1)
    {
        for (int i = nrOfThreads; i > 0; i--)
        {

            threads.push_back(thread(threadFun, ref(buffer3), buffer2, sizeOfData, dataPerThread, Size, mult, 3));
        }

    }
    else if (rozmiarDanych / nrOfThreads > 1)
    {

        int spareData = rozmiarDanych % nrOfThreads;
        for (int i = nrOfThreads; i > 0; i--)
        {

            int dpt;
            if (spareData > 0)
            {
                dpt = dataPerThread + 1;
            }

            else
                dpt = dataPerThread;
            threads.push_back(thread(threadFun, ref(buffer3), buffer2, sizeOfData, dpt, Size, mult, 3));
            sizeOfData = sizeOfData-dataPerThread;
            if(spareData>0)
                sizeOfData--;
            spareData--;
        }

    }

    for (int i = 0; i < threads.size(); i++)
    {
        threads[i].join();
    }
    for (int i = 0; i < buffer3.size() - 1; i++) {

        for (int j = 0; j < Size; j++)
            outFile.write((char*)&buffer3[i][j], sizeof(char)); //wypisanie na³o¿onego fragmentu do pilku wynikowego
    }

    for (int j = 0; j < rozmiarDanych % Size; j++)
        outFile.write((char*)&buffer3[buffer3.size() - 1][j], sizeof(char)); //wypisanie na³o¿onego fragmentu do pilku wynikowego dla wektora (mo¿e byæ krótszy ni¿ rozmiar Bitrate)

    inFile.close(); //zamkniêcie pliku wejœciowego
    outFile.close(); //zamkniêcie pliku wyjœciowego
}

int main()
{
    tripleEcho(25, "sample.raw", 48000, 1);
    return 0;
}
Zinsky
  • 13
  • 4
  • 1
    First of all, you need to read [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – molbdnilo Jan 28 '21 at 14:53
  • Your symptoms are typical of undefined behaviour. Start with making sure that all your subdivision and indexing arithmetic is correct, and add validation wherever you can. (The bounds in `for (int i=1; i <= echoNum; i++)` look very suspicious.) – molbdnilo Jan 28 '21 at 15:03
  • If your question is "Why are the results different?" it's because you have **[race conditions](https://stackoverflow.com/questions/34510/what-is-a-race-condition)**. Multiple threads are reading and writing to the same data. Crucially, `char += char` is not atomic. – Drew Dormann Jan 28 '21 at 15:10
  • @molbdnilo good thing they teach us wrong on my university... – Zinsky Jan 28 '21 at 16:15
  • @DrewDormann I made sure that every thread is working on a different set of data from the vector, I thought that this is enough to make it work good – Zinsky Jan 28 '21 at 16:17
  • 1
    having a thread change the vector size while another is doing anything else with it is UB. – doug Jan 28 '21 at 19:39

0 Answers0