Science and technology

How I create music playlists on Linux

I lately wrote a C program in Linux to create a smaller random choice of MP3 recordsdata from my intensive MP3 library. The program goes by way of a listing containing my MP3 library, after which creates a listing with a random, smaller choice of songs. I then copy the MP3 recordsdata to my smartphone to take heed to them on the go.

Sweden is a sparsely populated nation with many rural areas the place you do not have full cellphone protection. That’s one motive for having MP3 recordsdata on a smartphone. Another motive is that I do not at all times have the cash for a streaming service, so I prefer to have my very own copies of the songs I get pleasure from.

You can obtain my utility from its Git repository. I wrote it for Linux particularly partly as a result of it is easy to search out well-tested file I/O routines on Linux. Many years in the past, I attempted writing the identical program on Windows utilizing proprietary C libraries, and I bought caught making an attempt to get the file copying routing to work. Linux offers the consumer straightforward and direct entry to the file system.

In the spirit of open supply, it did not take a lot looking out earlier than I discovered file I/O code for Linux to encourage me. I additionally discovered some code for allocating reminiscence which impressed me. I wrote the code for random quantity technology.

The program works as described right here:

  1. It asks for the supply and vacation spot listing.
  2. It asks for the variety of recordsdata within the listing of MP3 recordsdata.
  3. It searches for the proportion (from 1.0 to 88.0 p.c) of your assortment that you just want to copy. You may enter a quantity like 12.5%, if in case you have a set of 1000 recordsdata and want to copy 125 recordsdata out of your assortment moderately than 120 recordsdata. I put the cap at 88% as a result of copying greater than 88% of your library would largely generate a set much like your base assortment. Of course, the code is open supply so you may freely modify it to your liking.
  4. It allocates reminiscence utilizing pointers and malloc. Memory is required for a number of actions, together with the record of strings representing the recordsdata in your music assortment. There can be an inventory to carry the randomly generated numbers.
  5. It generates an inventory of random numbers within the vary of all of the recordsdata (for instance, 1 to 1000, if the gathering has 1000 recordsdata).
  6. It copies the recordsdata.

Some of those elements are less complicated than others, however the code is simply about 100 strains:

#embody <dirent.h>
#embody <stdio.h>
#embody <string.h>
#embody <sys/varieties.h> /* embody obligatory header recordsdata */
#embody <fcntl.h>
#embody <stdlib.h>
#embody <unistd.h>
#embody <time.h>

#outline BUF_SIZE 4096 /* use buffer of 4096 bytes */
#outline OUTPUT_MODE 0700 /*shield output file */
#outline MAX_STR_LEN 256

int predominant(void) {
DIR *d;
struct dirent *dir;
char strTemp[256], srcFile[256],
dstFile[256], srcDir[256], dstDir[256];
char **ptrFileLst;

char buffer[BUF_SIZE];
int nrOfStrs=-1, srcFileDesc,
dstFileDesc, readByteCount,
writeByteCount, numFiles;
int indPtrFileAcc, q;

float nrFilesCopy;
//vars for generatingRandNumList
int i, ok, curRanNum, curLstInd,
numFound, numsToGen, largNumRange;
int *numLst;

float procFilesCopy;
printf("Enter name of source Directoryn");
scanf("%s", srcDir);
printf("Enter name of destionation Directoryn");
scanf("%s", dstDir);
printf("How many files does the directory with mp3 files contain?n");
scanf("%d", &numFiles);
printf("What percent of the files do you wish to make a random selection ofn");
printf("enter a number between 1 and 88n");
scanf("%f", &procFilesCopy);
//allocate reminiscence for filesList, record of random numbers
ptrFileLst= (char**) malloc(numFiles * sizeof(char*));
for (i=0; i<numFiles; i++)
ptrFileLst[i] = (char*)malloc(MAX_STR_LEN * sizeof(char));
largNumRange=numFiles;
nrFilesCopy=(procFilesCopy/100)*numFiles;

numsToGen=(int)((procFilesCopy/100)*numFiles);
printf("nrFilesCopy=%f", nrFilesCopy);
printf("NumsToGen=%d", numsToGen);
numLst = malloc(numsToGen * sizeof(int));
srand(time(0));

numLst[0]=rand()%largNumRange+1;
numFound=0;
do { curRanNum=(int)rand()%largNumRange+1;
if(numLst[0]==curRanNum) {
  numFound=1; }
} whereas(numFound==1);
  numLst[1]=curRanNum;
  getchar();
  curLstInd=1;
  i=0;
  whereas(1){
    do{
    numFound=0;
    curRanNum=(int)rand()%largNumRange+1;
    for(int ok=0; ok<=curLstInd; ok++){
      if(numLst[k]==curRanNum)
      numFound=1;
    }
  } whereas(numFound==1);
  numLst[curLstInd+1]=curRanNum;
  curLstInd++;
  i++;
// numsToGen=Total numbers to generate minus two
// already generated by the code above this loop
if(i==(numsToGen-2))
  break;
}

d = opendir(srcDir);
if(d){
  whereas ( (dir = readdir(d)) != NULL ){
  strcpy(strTemp, dir->d_name);

if(strTemp[0]!='.'){
  nrOfStrs++;
  strcpy(ptrFileLst[nrOfStrs], strTemp);
} }
closedir(d); }

for(q=0; q<=curLstInd; q++){
  indPtrFileAcc=numLst[q];
  strcpy(srcFile,srcDir);
  strcat(srcFile, "https://opensource.com/");
  strcat(srcFile,ptrFileLst[indPtrFileAcc]);
  strcpy(dstFile,dstDir);
  strcat(dstFile, "https://opensource.com/");
  strcat(dstFile,ptrFileLst[indPtrFileAcc]);
  
srcFileDesc = open(srcFile, O_RDONLY);
dstFileDesc = creat(dstFile, OUTPUT_MODE);

whereas(1){
  readByteCount = learn(srcFileDesc, buffer, BUF_SIZE);
  if(readByteCount<=0) 
    break;
    writeByteCount = write(dstFileDesc, buffer, readByteCount);
  if(writeByteCount<=0)
    exit(4); }

//shut the recordsdata 
shut(srcFileDesc);
shut(dstFileDesc); } }

This code is presumably probably the most advanced:


whereas(1){
readByteCount = learn(srcFileDesc, buffer, BUF_SIZE);
if(readByteCount<=0) 
  break;
  writeByteCount = write(dstFileDesc, buffer, readByteCount);
  if(writeByteCount<=0)
    exit(4); }

This reads various bytes (readByteCount) from a file specified into the character buffer. The first parameter to the operate is the file title (srcFileDesc). The second parameter is a pointer to the character buffer, declared beforehand in this system. The final parameter of the operate is the dimensions of the buffer.

The program returns the variety of the bytes learn (on this case, 4 bytes). The first if clause breaks out of the loop if various 0 or much less is returned.

If the variety of learn bytes is 0, then the entire writing is finished, and the loop breaks to write down the following file. If the variety of bytes learn is lower than 0, then an error has occurred and this system exits.

When the 4 bytes are learn, it would write to them.The write operate takes three arguments.The first is the file to write down to, the second is the character buffer, and the third is the variety of bytes to write down (4 bytes). The operate returns the variety of bytes written.

If 0 bytes are written, then a write error has occurred, so the second if clause exits this system.

The whereas loop reads and copies the file, 4 bytes at a time, till the file is copied. When the copying is finished, you may copy the listing of randomly generated mp3 recordsdata to your smartphone.

The copy and write routine are pretty environment friendly as a result of they use file system calls in Linux.

Improving the code

This program is easy and it might be improved when it comes to its consumer interface, and the way versatile it’s. You can implement a operate that calculates the variety of recordsdata within the supply listing so you do not have to enter it manually, for example. You can add choices so you may cross the proportion and path non-interactively.nBut the code does what I would like it to do, and it is a demonstration of the straightforward effectivity of the C programming language.

Most Popular

To Top