{"action":"created","comment":{"url":"https://api.github.com/repos/mixxxdj/mixxx/pulls/comments/23526108","id":23526108,"diff_hunk":"@@ -159,67 +161,74 @@ TrackPointer AnalyserQueue::dequeueNextBlocking() {\n }\n \n // This is called from the AnalyserQueue thread\n-bool AnalyserQueue::doAnalysis(TrackPointer tio, const Mixxx::SoundSourcePointer& pSoundSource) {\n-    int totalSamples = pSoundSource->length();\n-    //qDebug() << tio->getFilename() << \" has \" << totalSamples << \" samples.\";\n-    int processedSamples = 0;\n+bool AnalyserQueue::doAnalysis(TrackPointer tio, Mixxx::AudioSourcePointer pAudioSource) {\n \n     QTime progressUpdateInhibitTimer;\n     progressUpdateInhibitTimer.start(); // Inhibit Updates for 60 milliseconds\n \n-    int read = 0;\n+    Mixxx::AudioSource::diff_type frameIndex = pAudioSource->getFrameIndexMin();\n     bool dieflag = false;\n     bool cancelled = false;\n-    int progress; // progress in 0 ... 100\n-\n     do {\n         ScopedTimer t(\"AnalyserQueue::doAnalysis block\");\n-        read = pSoundSource->read(kAnalysisBlockSize, m_pSamplesPCM);\n-\n-        // To compare apples to apples, let's only look at blocks that are the\n-        // full block size.\n-        if (read != kAnalysisBlockSize) {\n-            t.cancel();\n-        }\n-\n-        // Safety net in case something later barfs on 0 sample input\n-        if (read == 0) {\n-            t.cancel();\n-            break;\n-        }\n-\n-        // If we get more samples than length, ask the analysers to process\n-        // up to the number we promised, then stop reading - AD\n-        if (read + processedSamples > totalSamples) {\n-            qDebug() << \"While processing track of length \" << totalSamples << \" actually got \"\n-                     << read + processedSamples << \" samples, truncating analysis at expected length\";\n-            read = totalSamples - processedSamples;\n-            dieflag = true;\n-        }\n \n-        SampleUtil::convertS16ToFloat32(m_pSamples, m_pSamplesPCM, read);\n-\n-        QListIterator<Analyser*> it(m_aq);\n-\n-        while (it.hasNext()) {\n-            Analyser* an =  it.next();\n-            //qDebug() << typeid(*an).name() << \".process()\";\n-            an->process(m_pSamples, read);\n-            //qDebug() << \"Done \" << typeid(*an).name() << \".process()\";\n+        DEBUG_ASSERT(frameIndex < pAudioSource->getFrameIndexMax());\n+        const Mixxx::AudioSource::size_type framesRemaining =\n+                pAudioSource->getFrameIndexMax() - frameIndex;\n+        const Mixxx::AudioSource::size_type framesToRead =\n+                math_min(kAnalysisFramesPerBlock, framesRemaining);\n+        DEBUG_ASSERT(0 < framesToRead);\n+\n+        const Mixxx::AudioSource::size_type framesRead =\n+                pAudioSource->readSampleFramesStereo(\n+                        kAnalysisFramesPerBlock,\n+                        &m_sampleBuffer[0],\n+                        m_sampleBuffer.size());\n+        DEBUG_ASSERT(framesRead <= framesToRead);\n+        frameIndex += framesRead;\n+        DEBUG_ASSERT(pAudioSource->isValidFrameIndex(frameIndex));\n+\n+        // To compare apples to apples, let's only look at blocks that are","path":"src/analyserqueue.cpp","position":130,"original_position":130,"commit_id":"c25265fc37d45b92bd0fbbd9c9ff4a83d59efcd0","original_commit_id":"823c9bfddc4efa214e5bc87f9a03297a5f7a12ba","user":{"login":"uklotzde","id":1474154,"avatar_url":"https://avatars.githubusercontent.com/u/1474154?v=3","gravatar_id":"","url":"https://api.github.com/users/uklotzde","html_url":"https://github.com/uklotzde","followers_url":"https://api.github.com/users/uklotzde/followers","following_url":"https://api.github.com/users/uklotzde/following{/other_user}","gists_url":"https://api.github.com/users/uklotzde/gists{/gist_id}","starred_url":"https://api.github.com/users/uklotzde/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uklotzde/subscriptions","organizations_url":"https://api.github.com/users/uklotzde/orgs","repos_url":"https://api.github.com/users/uklotzde/repos","events_url":"https://api.github.com/users/uklotzde/events{/privacy}","received_events_url":"https://api.github.com/users/uklotzde/received_events","type":"User","site_admin":false},"body":"That's an old comment. The analysers seem to expect full blocks of (stereo) sample.\r\n\r\nUsually only the last block is partially read. If any other block is only partially read the file must be corrupt and analysis should stop, even if EOF has not been reached.","created_at":"2015-01-26T12:16:00Z","updated_at":"2015-01-26T12:16:00Z","html_url":"https://github.com/mixxxdj/mixxx/pull/411#discussion_r23526108","pull_request_url":"https://api.github.com/repos/mixxxdj/mixxx/pulls/411","_links":{"self":{"href":"https://api.github.com/repos/mixxxdj/mixxx/pulls/comments/23526108"},"html":{"href":"https://github.com/mixxxdj/mixxx/pull/411#discussion_r23526108"},"pull_request":{"href":"https://api.github.com/repos/mixxxdj/mixxx/pulls/411"}}},"pull_request":{"url":"https://api.github.com/repos/mixxxdj/mixxx/pulls/411","id":25228389,"html_url":"https://github.com/mixxxdj/mixxx/pull/411","diff_url":"https://github.com/mixxxdj/mixxx/pull/411.diff","patch_url":"https://github.com/mixxxdj/mixxx/pull/411.patch","issue_url":"https://api.github.com/repos/mixxxdj/mixxx/issues/411","number":411,"state":"open","locked":false,"title":"New SoundSource/AudioSource API","user":{"login":"uklotzde","id":1474154,"avatar_url":"https://avatars.githubusercontent.com/u/1474154?v=3","gravatar_id":"","url":"https://api.github.com/users/uklotzde","html_url":"https://github.com/uklotzde","followers_url":"https://api.github.com/users/uklotzde/followers","following_url":"https://api.github.com/users/uklotzde/following{/other_user}","gists_url":"https://api.github.com/users/uklotzde/gists{/gist_id}","starred_url":"https://api.github.com/users/uklotzde/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uklotzde/subscriptions","organizations_url":"https://api.github.com/users/uklotzde/orgs","repos_url":"https://api.github.com/users/uklotzde/repos","events_url":"https://api.github.com/users/uklotzde/events{/privacy}","received_events_url":"https://api.github.com/users/uklotzde/received_events","type":"User","site_admin":false},"body":"This is the first step towards a better/cleaner SoundSource API.\r\nThe operations for reading audio data have been moved into the\r\nnew abstract base class AudioSource.\r\n\r\nCurrently SoundSource inherits from AudioSource for technical reasons.\r\nThis is too much much coupling that needs to be broken up. I have\r\nalready some ideas on how to resolve it, but first this work needs to\r\nbe integrated.\r\n\r\nDuring the refactoring I've noticed, that the quality and maturity of the\r\naudio decoders for different file types greatly varies:\r\n\r\nGood/mature:\r\n- FLAC\r\n- Ogg\r\n- Opus\r\n- WavPack\r\n- libsndfile\r\n\r\nMediocre:\r\n- MP3\r\n\r\nUgly/inefficient:\r\n- M4A (2014-12-04: Code has been rewritten without legacy code borrowed from other projects)\r\n- ModPlug\r\n\r\nUntested AudioSource API:\r\n- Apple CoreAudio\r\n- Windows Media Foundation\r\n\r\nUnfinished AudioSource API (just a hack):\r\n- FFmpeg\r\n\r\nEspecially the code for the M4A decoder should be revised and cleaned up as\r\nsoon as possible, followed by a review of the MP3 decoder. Reading audio\r\ndata must work as stable and efficient as possible. This has priority over\r\nthe improvement of the internal software architecture!","created_at":"2014-11-29T23:03:10Z","updated_at":"2015-01-26T12:16:00Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0d9a4fdec9ea1729ebd2e94b071b9f7438546fa1","assignee":null,"milestone":{"url":"https://api.github.com/repos/mixxxdj/mixxx/milestones/2","labels_url":"https://api.github.com/repos/mixxxdj/mixxx/milestones/2/labels","id":754553,"number":2,"title":"1.13","description":"","creator":{"login":"ywwg","id":888940,"avatar_url":"https://avatars.githubusercontent.com/u/888940?v=3","gravatar_id":"","url":"https://api.github.com/users/ywwg","html_url":"https://github.com/ywwg","followers_url":"https://api.github.com/users/ywwg/followers","following_url":"https://api.github.com/users/ywwg/following{/other_user}","gists_url":"https://api.github.com/users/ywwg/gists{/gist_id}","starred_url":"https://api.github.com/users/ywwg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ywwg/subscriptions","organizations_url":"https://api.github.com/users/ywwg/orgs","repos_url":"https://api.github.com/users/ywwg/repos","events_url":"https://api.github.com/users/ywwg/events{/privacy}","received_events_url":"https://api.github.com/users/ywwg/received_events","type":"User","site_admin":false},"open_issues":8,"closed_issues":4,"state":"open","created_at":"2014-08-14T23:06:10Z","updated_at":"2014-11-29T23:05:51Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/mixxxdj/mixxx/pulls/411/commits","review_comments_url":"https://api.github.com/repos/mixxxdj/mixxx/pulls/411/comments","review_comment_url":"https://api.github.com/repos/mixxxdj/mixxx/pulls/comments/{number}","comments_url":"https://api.github.com/repos/mixxxdj/mixxx/issues/411/comments","statuses_url":"https://api.github.com/repos/mixxxdj/mixxx/statuses/c25265fc37d45b92bd0fbbd9c9ff4a83d59efcd0","head":{"label":"uklotzde:NewSoundSourceAPI","ref":"NewSoundSourceAPI","sha":"c25265fc37d45b92bd0fbbd9c9ff4a83d59efcd0","user":{"login":"uklotzde","id":1474154,"avatar_url":"https://avatars.githubusercontent.com/u/1474154?v=3","gravatar_id":"","url":"https://api.github.com/users/uklotzde","html_url":"https://github.com/uklotzde","followers_url":"https://api.github.com/users/uklotzde/followers","following_url":"https://api.github.com/users/uklotzde/following{/other_user}","gists_url":"https://api.github.com/users/uklotzde/gists{/gist_id}","starred_url":"https://api.github.com/users/uklotzde/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uklotzde/subscriptions","organizations_url":"https://api.github.com/users/uklotzde/orgs","repos_url":"https://api.github.com/users/uklotzde/repos","events_url":"https://api.github.com/users/uklotzde/events{/privacy}","received_events_url":"https://api.github.com/users/uklotzde/received_events","type":"User","site_admin":false},"repo":{"id":11108787,"name":"mixxx","full_name":"uklotzde/mixxx","owner":{"login":"uklotzde","id":1474154,"avatar_url":"https://avatars.githubusercontent.com/u/1474154?v=3","gravatar_id":"","url":"https://api.github.com/users/uklotzde","html_url":"https://github.com/uklotzde","followers_url":"https://api.github.com/users/uklotzde/followers","following_url":"https://api.github.com/users/uklotzde/following{/other_user}","gists_url":"https://api.github.com/users/uklotzde/gists{/gist_id}","starred_url":"https://api.github.com/users/uklotzde/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uklotzde/subscriptions","organizations_url":"https://api.github.com/users/uklotzde/orgs","repos_url":"https://api.github.com/users/uklotzde/repos","events_url":"https://api.github.com/users/uklotzde/events{/privacy}","received_events_url":"https://api.github.com/users/uklotzde/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/uklotzde/mixxx","description":"Mixxx is Free DJ software that gives you everything you need to perform live mixes.","fork":true,"url":"https://api.github.com/repos/uklotzde/mixxx","forks_url":"https://api.github.com/repos/uklotzde/mixxx/forks","keys_url":"https://api.github.com/repos/uklotzde/mixxx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uklotzde/mixxx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uklotzde/mixxx/teams","hooks_url":"https://api.github.com/repos/uklotzde/mixxx/hooks","issue_events_url":"https://api.github.com/repos/uklotzde/mixxx/issues/events{/number}","events_url":"https://api.github.com/repos/uklotzde/mixxx/events","assignees_url":"https://api.github.com/repos/uklotzde/mixxx/assignees{/user}","branches_url":"https://api.github.com/repos/uklotzde/mixxx/branches{/branch}","tags_url":"https://api.github.com/repos/uklotzde/mixxx/tags","blobs_url":"https://api.github.com/repos/uklotzde/mixxx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uklotzde/mixxx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uklotzde/mixxx/git/refs{/sha}","trees_url":"https://api.github.com/repos/uklotzde/mixxx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uklotzde/mixxx/statuses/{sha}","languages_url":"https://api.github.com/repos/uklotzde/mixxx/languages","stargazers_url":"https://api.github.com/repos/uklotzde/mixxx/stargazers","contributors_url":"https://api.github.com/repos/uklotzde/mixxx/contributors","subscribers_url":"https://api.github.com/repos/uklotzde/mixxx/subscribers","subscription_url":"https://api.github.com/repos/uklotzde/mixxx/subscription","commits_url":"https://api.github.com/repos/uklotzde/mixxx/commits{/sha}","git_commits_url":"https://api.github.com/repos/uklotzde/mixxx/git/commits{/sha}","comments_url":"https://api.github.com/repos/uklotzde/mixxx/comments{/number}","issue_comment_url":"https://api.github.com/repos/uklotzde/mixxx/issues/comments/{number}","contents_url":"https://api.github.com/repos/uklotzde/mixxx/contents/{+path}","compare_url":"https://api.github.com/repos/uklotzde/mixxx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uklotzde/mixxx/merges","archive_url":"https://api.github.com/repos/uklotzde/mixxx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uklotzde/mixxx/downloads","issues_url":"https://api.github.com/repos/uklotzde/mixxx/issues{/number}","pulls_url":"https://api.github.com/repos/uklotzde/mixxx/pulls{/number}","milestones_url":"https://api.github.com/repos/uklotzde/mixxx/milestones{/number}","notifications_url":"https://api.github.com/repos/uklotzde/mixxx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uklotzde/mixxx/labels{/name}","releases_url":"https://api.github.com/repos/uklotzde/mixxx/releases{/id}","created_at":"2013-07-01T22:22:18Z","updated_at":"2015-01-12T23:41:03Z","pushed_at":"2015-01-26T11:12:00Z","git_url":"git://github.com/uklotzde/mixxx.git","ssh_url":"git@github.com:uklotzde/mixxx.git","clone_url":"https://github.com/uklotzde/mixxx.git","svn_url":"https://github.com/uklotzde/mixxx","homepage":"http://mixxx.org","size":237449,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"mixxxdj:master","ref":"master","sha":"6a40409b0fa5bfb53c2d3e5e7b8ab055c748ac27","user":{"login":"mixxxdj","id":1743769,"avatar_url":"https://avatars.githubusercontent.com/u/1743769?v=3","gravatar_id":"","url":"https://api.github.com/users/mixxxdj","html_url":"https://github.com/mixxxdj","followers_url":"https://api.github.com/users/mixxxdj/followers","following_url":"https://api.github.com/users/mixxxdj/following{/other_user}","gists_url":"https://api.github.com/users/mixxxdj/gists{/gist_id}","starred_url":"https://api.github.com/users/mixxxdj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mixxxdj/subscriptions","organizations_url":"https://api.github.com/users/mixxxdj/orgs","repos_url":"https://api.github.com/users/mixxxdj/repos","events_url":"https://api.github.com/users/mixxxdj/events{/privacy}","received_events_url":"https://api.github.com/users/mixxxdj/received_events","type":"Organization","site_admin":false},"repo":{"id":10126031,"name":"mixxx","full_name":"mixxxdj/mixxx","owner":{"login":"mixxxdj","id":1743769,"avatar_url":"https://avatars.githubusercontent.com/u/1743769?v=3","gravatar_id":"","url":"https://api.github.com/users/mixxxdj","html_url":"https://github.com/mixxxdj","followers_url":"https://api.github.com/users/mixxxdj/followers","following_url":"https://api.github.com/users/mixxxdj/following{/other_user}","gists_url":"https://api.github.com/users/mixxxdj/gists{/gist_id}","starred_url":"https://api.github.com/users/mixxxdj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mixxxdj/subscriptions","organizations_url":"https://api.github.com/users/mixxxdj/orgs","repos_url":"https://api.github.com/users/mixxxdj/repos","events_url":"https://api.github.com/users/mixxxdj/events{/privacy}","received_events_url":"https://api.github.com/users/mixxxdj/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mixxxdj/mixxx","description":"Mixxx is Free DJ software that gives you everything you need to perform live mixes.","fork":false,"url":"https://api.github.com/repos/mixxxdj/mixxx","forks_url":"https://api.github.com/repos/mixxxdj/mixxx/forks","keys_url":"https://api.github.com/repos/mixxxdj/mixxx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mixxxdj/mixxx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mixxxdj/mixxx/teams","hooks_url":"https://api.github.com/repos/mixxxdj/mixxx/hooks","issue_events_url":"https://api.github.com/repos/mixxxdj/mixxx/issues/events{/number}","events_url":"https://api.github.com/repos/mixxxdj/mixxx/events","assignees_url":"https://api.github.com/repos/mixxxdj/mixxx/assignees{/user}","branches_url":"https://api.github.com/repos/mixxxdj/mixxx/branches{/branch}","tags_url":"https://api.github.com/repos/mixxxdj/mixxx/tags","blobs_url":"https://api.github.com/repos/mixxxdj/mixxx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mixxxdj/mixxx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mixxxdj/mixxx/git/refs{/sha}","trees_url":"https://api.github.com/repos/mixxxdj/mixxx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mixxxdj/mixxx/statuses/{sha}","languages_url":"https://api.github.com/repos/mixxxdj/mixxx/languages","stargazers_url":"https://api.github.com/repos/mixxxdj/mixxx/stargazers","contributors_url":"https://api.github.com/repos/mixxxdj/mixxx/contributors","subscribers_url":"https://api.github.com/repos/mixxxdj/mixxx/subscribers","subscription_url":"https://api.github.com/repos/mixxxdj/mixxx/subscription","commits_url":"https://api.github.com/repos/mixxxdj/mixxx/commits{/sha}","git_commits_url":"https://api.github.com/repos/mixxxdj/mixxx/git/commits{/sha}","comments_url":"https://api.github.com/repos/mixxxdj/mixxx/comments{/number}","issue_comment_url":"https://api.github.com/repos/mixxxdj/mixxx/issues/comments/{number}","contents_url":"https://api.github.com/repos/mixxxdj/mixxx/contents/{+path}","compare_url":"https://api.github.com/repos/mixxxdj/mixxx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mixxxdj/mixxx/merges","archive_url":"https://api.github.com/repos/mixxxdj/mixxx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mixxxdj/mixxx/downloads","issues_url":"https://api.github.com/repos/mixxxdj/mixxx/issues{/number}","pulls_url":"https://api.github.com/repos/mixxxdj/mixxx/pulls{/number}","milestones_url":"https://api.github.com/repos/mixxxdj/mixxx/milestones{/number}","notifications_url":"https://api.github.com/repos/mixxxdj/mixxx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mixxxdj/mixxx/labels{/name}","releases_url":"https://api.github.com/repos/mixxxdj/mixxx/releases{/id}","created_at":"2013-05-17T15:14:38Z","updated_at":"2015-01-24T23:54:03Z","pushed_at":"2015-01-23T19:56:31Z","git_url":"git://github.com/mixxxdj/mixxx.git","ssh_url":"git@github.com:mixxxdj/mixxx.git","clone_url":"https://github.com/mixxxdj/mixxx.git","svn_url":"https://github.com/mixxxdj/mixxx","homepage":"http://mixxx.org","size":311129,"stargazers_count":227,"watchers_count":227,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":188,"mirror_url":null,"open_issues_count":35,"forks":188,"open_issues":35,"watchers":227,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mixxxdj/mixxx/pulls/411"},"html":{"href":"https://github.com/mixxxdj/mixxx/pull/411"},"issue":{"href":"https://api.github.com/repos/mixxxdj/mixxx/issues/411"},"comments":{"href":"https://api.github.com/repos/mixxxdj/mixxx/issues/411/comments"},"review_comments":{"href":"https://api.github.com/repos/mixxxdj/mixxx/pulls/411/comments"},"review_comment":{"href":"https://api.github.com/repos/mixxxdj/mixxx/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/mixxxdj/mixxx/pulls/411/commits"},"statuses":{"href":"https://api.github.com/repos/mixxxdj/mixxx/statuses/c25265fc37d45b92bd0fbbd9c9ff4a83d59efcd0"}}}}