Using cURL to post .wav files to cloud storage?

Hello! I’m trying to figure out how to post a .wav file to a cloud file hosting solution.

In the short term, I decided to use https://upload.io/docs/upload-api#uploading-files since it’s a lot more straightforward than using an Amazon S3 bucket.

In my C++, I have the following working:

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
  
curl_easy_setopt(curl, CURLOPT_URL, "https://audiopoop.free.beeceptor.com");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
res = curl_easy_perform(curl);
  
if(res != CURLE_OK)
{
  DEBUG("curl_easy_perform() failed");
  DEBUG("Cert path was: ");
  DEBUG(cert_path.c_str());
  DEBUG(curl_easy_strerror(res));
}

This makes an HTTP GET to beeceptor.com, where I could see the incoming webservice call. Again, this was successful.

My next step is to make a POST to upload.io. They’re example post looks like:

curl --data-binary @sample-image.jpg \
     -H "Content-Type: image/jpeg" \
     -H "Authorization: Bearer YOUR_PUBLIC_API_KEY" \
     -X POST "https://api.upload.io/v2/accounts/{accountId}/uploads/binary"

I’m having some trouble figuring out how to translate that command line usage into C++.

Would it be something like…

// Forgive me....
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);

// Set content type
struct curl_slist *hs=NULL;
hs = curl_slist_append(hs, "Content-Type: audio/wav");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hs);

// Here's where I'm having issues...
// Should I reload the saved .wav file into a char * array, 
// then send that array into these two lines?
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, sample->sample_length);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, sample->data);

// I haven't updated this yet.  But it will point to upload.io eventually
curl_easy_setopt(curl, CURLOPT_URL, "https://audiopoop.free.beeceptor.com");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
res = curl_easy_perform(curl);

Thanks!
Bret

Ah, never mind! I got it working!

Here’s my code for uploading a file to upload.io. It isn’t perfect. Right now it plops the file in a date-stamped upload file. I’ll work on improving this code to upload the file into a specific folder (if that’s even possible using upload.io.)

Once you have a upload.io account, log in, then go to Upload API v2 Docs | Upload. The upload example will provide you with your specific api key and account id.

  static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
  {
      ((std::string*)userp)->append((char*)contents, size * nmemb);
      return size * nmemb;
  }

Later on…

if(curl) {

  // Forgive me....
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
  
  // Set content type
  struct curl_slist *headers=NULL;
  headers = curl_slist_append(headers, "Content-Type: audio/wav");
  headers = curl_slist_append(headers, "Authorization: Bearer [my api key]");
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
  
  //
  // Read raw .wav file into char *
  // The variable "full_path" is a std::string like C:/Users/clone/Documents/Rack2/audio_poop_recordings/recording_frAQBc8Wsa1x.wav
  // 
  std::string contents;
  std::ifstream in(full_path, std::ios::in | std::ios::binary);
  if (in)
  {
      in.seekg(0, std::ios::end);
      contents.resize(in.tellg());
      in.seekg(0, std::ios::beg);
      in.read(&contents[0], contents.size());
      in.close();
  }
  else
  {
      DEBUG("Unable to read in file to send");
  }
  
  curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, contents.size());
  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, contents.data());
  curl_easy_setopt(curl, CURLOPT_POST,1);
  
  curl_easy_setopt(curl, CURLOPT_URL, "https://api.upload.io/v2/accounts/[my account id]/uploads/binary");
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
  res = curl_easy_perform(curl);
  
  if(res != CURLE_OK)
  {
      DEBUG("curl_easy_perform() failed");
      DEBUG(curl_easy_strerror(res));
  } 
} 
else
{
  DEBUG("curl not defined");
}
1 Like

Hmm… are you preparing a module with access to a central WAV collection?

1 Like

Maaaayyybeeee. Ha ha ha.

I’m playing with an idea that I posted a while back where you can super-easily record audio to a shared, free, central collection, and also super easily playback samples from that collection.

The recording module might look like this:

The playback module would look similar to my WavBank module. Somehow there will be folders involved. :slight_smile:

I’m just playing around right now. I want to create a really minimal version of the recorder and playback modules to see if they catch on, or if nobody ends up using them.

3 Likes